O Stack Exchange detecta automaticamente a votação em série (quando um usuário faz um voto positivo ou negativo em muitas das postagens de outro usuário) e o inverte. Neste desafio, você implementará um detector "voto em série" muito, muito simples.
Entrada
A entrada é uma sequência que representa uma lista de votos. Cada grupo de dois caracteres representa um voto - o primeiro é o eleitor e o segundo é o usuário que está sendo votado. Por exemplo, a seguinte entrada
ababbccd
pode ser analisado como ab
ab
bc
cd
e representa a
votar b
duas vezes,
b
votar c
uma vez e c
votar d
uma vez.
A entrada será composta apenas por letras minúsculas e será sempre igual> 0. Você também não pode votar em si mesmo (portanto, não aa
ou hh
).
Resultado
Para os propósitos deste desafio, a votação em série é definida como qualquer usuário que esteja votando em outro usuário três ou mais vezes.
A saída é quantos votos devem ser revertidos para cada usuário (ou seja, quantos votos em cada usuário foram revertidos, não quantos votos que eles deram foram revertidos), no formato [user][votes][user2][votes2]...
. Por exemplo, uma entrada de abababab
( a
votação b
quatro vezes) deve ser gerada
b4
(quatro votos foram revertidos de a
para b
).
A saída pode estar na ordem que você desejar, mas tanto a entrada quanto a saída devem ser cadeias simples, conforme descrito acima.
Casos de teste
In Out
---------------------------------------------------------------------------
abababcbcbcbcbbababa b7a3
edfdgdhdfgfgfgih g3
jkkjjkkjjkkjljljljmlmlnmnmnm j6k3m3
opqrstuv <none>
vwvwwvwv <none>
xyxyxyxyxyxyxyzyzyzyxzxzxz y10z3
nanananananananabatman a8
banana <none>
nanananananananabatman
o caso de teste.Respostas:
Pitão, 22 bytes
Experimente on-line: Demonstration or Test Suite
Explicação:
Exemplo:
fonte
Ilegível ,
18301796179117711762174517361727162616061577 bytesA saída está em ordem alfabética inversa (
z
paraa
), mas de acordo com suas regras que parecem ser permitidas.Explicação
Primeiro, para ter uma impressão do que o ilegível pode fazer, aqui está sua operação básica:
write(x, inc(read(x)))
.Este programa usa a fita da seguinte maneira. Os nomes das variáveis serão usados no pseudocódigo posteriormente abaixo. Além disso, isso documenta a primeira versão (que era de 1830 bytes); veja as edições na parte inferior do que mudou desde então.
q
a
,p
,ch
hash
,v
b
,r
aa
,l
a
(96) az
(121) (o código ASCII da letra menos um).0
= ainda não visto,-1
= visto uma vez,-2
= visto duas vezes,-3
= visto qualquer número de vezes mais que 2.O algoritmo essencialmente procede da seguinte maneira:
a
eb
. Calcule o valor do hash(a-2)*(a-1)+b-1
, que é exclusivo para cada combinação de letras a – z.*hash
). Se for-3
, o usuário já está qualificado para a remoção de votos, então aumente*(b-1)
. Caso contrário, diminua*hash
. Se for agora-3
, o usuário acabou de se qualificar para a remoção de votos após três ocorrências, então aumente*(b-1)
em3
.z
paraa
) e produza os que precisam de dedução de votos. Isso requer divisão inteira manual por 10 para converter o número em dígitos decimais.Com tudo isso esclarecido, é assim que o programa se parece com pseudocódigo:
Edit 1, 1830 → 1796: Percebi que posso reutilizar o valor de retorno de um loop while em um só lugar.
Edit 2, 1796 → 1791: Acontece que o programa é um pouco menor se, em vez de usar as células 6–95, eu armazenar os dígitos decimais nas células com números negativos (–1 em diante). Como um bônus adicional, o programa não está mais limitado a 10 votos!
Edit 3, 1791 → 1771: Em vez de atribuir o resultado de
*(ch = l + 95)
av
, agora o atribuo a eleq
e depois movo a atribuiçãov = q
para a condição while, levando o código para 1777 bytes. Em seguida, troque o local deq
ev
na fita, porqueq
agora é 1 mais comum quev
.Edit 4, 1771 → 1762: Duh. Inicializar
hash
para 1 em vez de 0 é 9 bytes mais curto. O código hash agora é mais 1, o que não importa.Edit 5, 1762 → 1745: Se eu inicializar
q
er
para 1 em vez de 0, tenho que espalhar alguns-1
s em alguns lugares para torná-lo correto e tudo parece cancelar - exceto que owhile v { --v; [...] }
loop agora precisa executar uma iteração a menos, o que posso fazer dizendowhile --v { [...] }
, que é 26 caracteres menor.Edit 6, 1745 → 1736: Em vez de
{ r = 1; ++q }
, podemos escreverq = *((r = 1)+1)+1
. Isso se baseia no fato deq
estar no slot variável nº 2. Se estivesse no slot 1, isso seria ainda mais curto, mas o programa inteiro seria mais longo no geral.Edit 7, 1745 → 1727: Reverse Edit 6 e, em vez disso, conseguiu salvar salvando o loop while mais interno na expressão que calcula o código ASCII do dígito, que também termina em 1736 bytes ... mas salvou uma instrução de decremento (9 bytes ) alterando
((++r) - 11) ? r :
para(r - 10) ? ++r :
.Edit 8, 1727 → 1626: Retrabalhou o cálculo de hash. Agora ele usa um loop while a menos. Agora, as localizações das células estão com seus códigos ASCII reais (não são mais 1 desativadas). Reorganizou as variáveis para diferentes locais na fita porque agora elas ocorrem com diferentes frequências.
Edite 9, 1626 → 1606: Inlining mais louco. O corpo do primeiro loop while agora se parece com isso:
e a atribuição de variáveis agora mudou quase completamente.
Editar 10, 1606 → 1577: Eu observei que
a
ea2
são ambos decrementado a 0 enquanto em laços, de modo que se podia emparelharp
com qualquer um daqueles, mas não comch
, não seria necessário para inicializarp
a0
(que custa 29 bytes). Acontece que eu posso fazer isso trocandop
er
. As mais recentes atribuições de variáveis (e sua frequência de ocorrência no código) são agora:fonte
CJam, 23 bytes
Festa de longa duração!
ou
Execute todos os casos de teste
Explicação
A outra versão começa revertendo os pares, o que economiza dois bytes em outro lugar: a) selecionar o primeiro caractere em cada string é apenas em
:c
vez deWf=
selecionar o segundo. b) Não precisamos ordenar novamente antes do segundo RLE, porque os pares já foram classificados principalmente pelo caractere restante.fonte
Q
na sua segunda resposta, deve serq
para fins que não envolvem o envoltório de teste.3
em uma lista para comparação é um bom truque. Eu o resolvi apenas para meu próprio entretenimento e perdi um byte lá porque eu o usava0=2>
. Caso contrário, acabei quase igual à sua primeira solução, exceto pelo uso, em::\
vez doWf%
último passo.Bash,
95948581 bytesUma solução elegante e longa, mas longa, para começar ...
Graças à User112638726 para salvar um byte com
sed
, DigitalTrauma para salvar 9 comfold
, e Rainer P. para salvar 4 mais comawk
'ssubstr
!Para ver como funciona, vamos pegar a entrada
abababcbcbcbcbbababa
.Depois
fold -2
(enrole a linha com uma largura de 2), temosDepois
sort | uniq -c
(-c
é um sinalizador muito bacana parauniq
gerar a contagem de quantas vezes cada linha aparece na entrada), obtemosAgora vamos examinar o
awk
comando final :$1>2
: Somente produza material se o registro 1 (também conhecido como número de votos idênticos) for maior que 2 (ou seja, ≥ 3). Em outras palavras, ignore qualquer linha que comece com um número ≤ 2.{c[substr($2,2)]+=$1}
: Se o número for maior que 2, adicione esse número àc
tabela de hash, usando o segundo caractere do registro 2 (também conhecido como voto-ee) como chave. (Não precisamos inicializar tudo para zero;awk
faz isso por nós.)END{...}
: Isso significa apenas "depois de processar o arquivo inteiro, eis o que fazer a seguir".for(x in c)printf x c[x]
: Bastante auto-explicativo. Imprima todas as chaves e seu valor correspondente.fonte
&
é equivalente a\0
in sed #sed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
bacada
, por exemplo.JavaScript,
114113110Casos de teste:
Mostrar snippet de código
Em um nível alto, esse código preenche um objeto com pares de valores-chave que mapeiam os destinatários do voto para o número de votos, como
{ b:7, a:3 }
e os une a uma sequência em umfor
loop. O código está em umaeval
expressão para permitir o uso defor
uma função de seta sem precisar gastar bytes em{ }
e;return r
.( Adota o user81655 para salvar três bytes!)
Explicação do
eval
código:fonte
Haskell, 103 bytes
Exemplo de uso:
f "jkkjjkkjjkkjljljljmlmlnmnmnm"
->"k3j6m3"
Como funciona:
fonte
JavaScript (ES6),
195174169167158 bytesTeste
Mostrar snippet de código
fonte
var
s. Quem se importa em poluir o escopo global no código de golfe? ;)/(\w{2})/g
pode ser apenas/../g
- já sabemos que a entrada é apenas letras e a repetição de um (ou dois) caracteres é menor que{2}
. Se você estiver interessado, pode dar uma olhada (e comentar perguntas) na minha resposta JavaScript para esse desafio. Bem-vindo ao PGCC!Mathematica,
11010099 bytesfonte
Perl,
868483 bytesSão 82 bytes mais 1 para o
-p
argumento da linha de comando:Um pouco não-destruído:
${$'}
vez de$g{$'}
. Infelizmente,$$'
não funciona.fonte
Pure Bash, 151
Mais do que eu esperava, mas aqui está.
Usa a indexação de matriz associativa para fazer a contagem necessária. Requer bash versão 4.0 ou superior.
fonte
PHP 247 caracteres
(ai)
Explicado
Fez isso sem espreitar outras respostas. Este é o código de golfe mais difícil que eu já enfrentei. Congratulo-me com todas as otimizações.
fonte
R, 221 bytes
código
destroçado
Há muito espaço para melhorias aqui.
fonte