O desafio
Seu objetivo é escrever o programa mais curto possível, com uma lista de eventos (como upvote, downvote, etc) e retornar a reputação do usuário e os privilégios que ele conquistou.
Que tipo de eventos?
Aqui está um gráfico dos eventos, listados em ordem de reputação conquistada:
-15 answer unaccepted
-10 answer unupvoted
-5 question unupvoted
-2 answer downvoted
-2 question downvoted
-2 unaccept answer
-1 downvote answer
+1 join website
+1 undownvote answer
+2 accept answer
+2 question undownvoted
+2 answer undownvoted
+5 question upvoted
+10 answer upvoted
+15 answer accepted
+100 association bonus
Que tipo de privilégios?
Aqui está uma lista de privilégios, em ordem de reputação necessária.
1 create posts
5 participate in meta
10 remove new user restrictions
10 create wiki posts
15 vote up
15 flag posts
20 talk in chat
50 comment everywhere
75 set bounties
100 edit community wiki
100 create chat rooms
125 vote down
150 create tags
200 retag questions
250 view close votes
500 cast close and reopen votes
750 established user
1000 edit questions and answers
1000 create gallery chat rooms
1250 create tag synonyms
1500 approve tag wiki edits
2000 access to moderator tools
3500 protect questions
4000 trusted user
Entrada
A entrada (no STDIN) será uma lista de eventos, um por linha, exatamente como eles aparecem no primeiro gráfico (exceto pela quantidade de reputação). Uma linha em branco representa o fim da entrada. Aqui está um exemplo (deve haver uma linha em branco no final):
join website
association bonus
answer upvoted
answer upvoted
question upvoted
answer accepted
answer upvoted
accept answer
unaccept answer
question unupvoted
accept answer
question upvoted
Resultado
A primeira linha de saída (para STDOUT) deve nomear a quantidade de repetições acumuladas. Cada linha seguinte deve listar um privilégio conquistado, exatamente como eles aparecem e na mesma ordem que o segundo gráfico. A saída esperada para a entrada acima:
153 reputation
1 create posts
5 participate in meta
10 remove new user restrictions
10 create wiki posts
15 vote up
15 flag posts
20 talk in chat
50 comment everywhere
75 set bounties
100 edit community wiki
100 create chat rooms
125 vote down
150 create tags
Regras, restrições e notas
Isso é código de golfe. Aplicam-se regras de código padrão de golfe.
(EDIT: Como tive duas entradas que acessam arquivos, gostaria de salientar que o tamanho do arquivo precisa ser adicionado ao comprimento do código como parte das regras padrão para o código de golfe)
fonte
Respostas:
GolfScript (
569 568 475473 caracteres)Isso usa caracteres não imprimíveis para compactar as seqüências necessárias, portanto, no formato xxd:
Módulo de compressão de strings, o programa é
Bastante trivial na maioria dos aspectos, mas existem dois pontos de interesse.
A primeira é a função hash para as strings de entrada. Fiquei surpreso com o quão simples uma função hash produz resultados exclusivos para cada uma das 9
un
strings diferentes (uma vez removidas) e, como bônus, também produz um resultado diferente para a string vazia, o que evita eliminar a linha em branco final do entrada.O cálculo do representante para uma linha individual é
Primeiro, remove
un
da string e anota se foi encontrado. Em seguida, aplica uma função hash super simplesh(s) = ( sum over i: (-1)^i s[i] ) % 11
,. (Você pode ver por que fiquei surpreso quando o encontrei). A cordaé uma tabela de pesquisa que mapeia o valor de hash para a alteração no rep (subtrai 110 do valor ASCII) e, se encontrado
un
no início, nega a alteração.O segundo ponto de interesse é o filtro para os privilégios. Eu tentei um pouco mais simples:
que avalia a linha (palavras indefinidas não fazem nada) para obter sua pontuação para comparação com a reputação (armazenada em
^
). Isso quase funciona. O que o quebra é o queand
ocorre em algumas das strings e é uma função predefinida. Solução: altere as linhas o suficiente para queand
não ocorra mais. (Pode-se argumentar que remover espaços seria melhor do que remover a letraa
, mas isso não faz diferença no comprimento).fonte
Ruby 1.9.3,
514467459 (507460452 + 7 para sinalizadores)Corra com
ruby -rzlib <program>
.Se os literais da string binária não colaram corretamente (o que provavelmente não fizeram), aqui está um dump hexadecimal:
fonte
Haskell, 787 caracteres
fonte
C #
127112081206fonte
C -
10831069Percebo que estou um pouco atrasado para o jogo, mas C não está representado, então imaginei que iria dar uma facada nele.
Aqui está uma versão um pouco menos golfe:
Penso que a ideia básica é semelhante à abordagem de muitas outras pessoas. Eu uso um pouco de hash caseiro para lidar com o reconhecimento de entradas. O hash convenientemente fornece zero para uma string vazia, tornando a linha de leitura de entrada muito compacta. Tenho certeza de que o hash poderia ser muito melhorado. Algumas economias de caráter podem ser obtidas permitindo-se algumas colisões estratégicas de hash para coisas que têm a mesma reputação.
Eu também me diverti muito perversamente escondendo umagoto
macro (dentro da minha primeira vez em que uso umagoto
, tenho orgulho em dizer).O único lugar em que tenho certeza de que tenho muito espaço para melhorias é na seção de saída. Eu nem tentei comprimir a lógica de impressão real, por isso tenho certeza de que também poderia salvar alguns caracteres.
fonte
puts
vez deprintf
.goto E
porreturn
(eliminando o rótulo) e remover a!=0
função hash (é redundante).C (
765737 caracteres)Ou um pouco mais legível com quebras de linha e recuo adicionados:
Os códigos acima assumem uma única nova linha no final do arquivo. Se houver dois, é necessário escrever em
s+=*l?e[…]:0
vez des+=e[…]
, a um custo adicional de 5 caracteres . A escritawhile(*gets(l))
seria mais curta, mas não funcionará, já que eu não incluo cabeçalhos; portanto, o compilador assume que nãogets
retorna .int
char*
A expressão de hash
(l[11]%8^l[7])-97
foi encontrada ao tentar todas as expressões dos seguintes formulários, procurando aquele com o menor comprimento de código resultante:Uma representação de caracteres ASCII imprimível adequada foi encontrada usando uma pesquisa de força bruta semelhante.
Python 3 (
743715 caracteres)No mesmo espírito que acima. Este depende de uma segunda nova linha no final da entrada, no entanto.
fonte
Java - 1519 caracteres
Para encontrar reputação, ele adiciona todo o caractere na sequência de entrada (por exemplo, 'ingressar no site' adiciona ao formulário 1219) e quando b == 1219, r = r + 1.
fonte
c
faz umaif
verificação para decidir se umtrue
ou umfalse
deve ser retornado onde, como esteboolean
daif
directamente pode ser devolvido para trazer o tamanho até 1470 ;) Sugeri uma melhoria para sua resposta. É aguardando revisão por pares :)Scala 1089
Reescreveu do zero, quase. Se eu tiver que calcular os dados, é mais barato (embora feio) incluir os dados diretamente.
Primeira abordagem, lendo os preços dos eventos e a guia de privilégios dos arquivos:
lendo dados do arquivo: 405
fonte
J (704)
O programa consiste em quatro partes:
o seguinte script decodificador ( 277 bytes)
um arquivo de palavras binárias, chamado
w
, também 277 bytes (faça o download aqui ).O formato do arquivo é o seguinte: cada palavra é codificada como um grupo de "bytes" de cinco bits. Cada grupo de cinco bits pode ter um valor de
1
para27
representar letras ou0
ser o separador. Cada palavra única na descrição dos eventos e privilégios é armazenada aqui.um arquivo de eventos binários, chamado
e
, que é 54 bytes (download aqui ).Cada evento consiste em uma reputação de 12 bytes e uma ou mais palavras de 6 bytes. Por exemplo,
accept answer
é codificado da seguinte maneira:um arquivo privilégios binários, chamado
p
, que é de 96 bytes (download aqui ).O formato do arquivo é o mesmo que
e
, por exemplo,access to moderator tools
é codificado da seguinte forma:fonte
Perl,
856849 caracteresapenas adicionando quebras de linha após alguns pontos e vírgulas para facilitar a leitura;):
fonte
Java (caracteres 1470)
Nota: É uma modificação da resposta de Aman ZeeK Verma, mas como minha edição não foi aceita e minha resposta é significativamente menor que a dele, estou postando aqui.
Versão legível:
Versão Minificada:
fonte
PHP: 676 caracteres
Não vai ganhar nenhum prêmio, mas caramba, eu simplesmente não consigo descobrir como fazer isso ficar menor, então eu vou postar:
Como a parte que calcula o representante é muito difícil de ler, aqui está a formatação extra. Abusa constantes indefinidas e usa @ para calá-las:
fonte
APL (549)
Este empacota os dados em caracteres Unicode.
fonte
Python 3.x (801 caracteres)
O melhor que posso fazer até agora, só preciso elaborar uma codificação melhor que a base64 (dica: alguém pode ajudar?).
fonte