Parabéns por obter 10.000 reputação!


19

Depois que o @ MartinBüttner alcançou exatamente 10.000 reputação , agora temos três linhas completas de 10.000 usuários na página de usuários ! Agora, como somos todos programadores aqui, gostamos de automatizar as coisas em vez de fazê-las manualmente. Seu desafio é escrever um programa para parabenizar automaticamente os novos 10 mil usuários.

Especificação

Entrada

A entrada será nlinhas de números separados por espaço. (Se desejar, você também pode usar uma lista de números separados por espaço e separados por vírgula, se isso diminuir o seu código.) Por exemplo:

10 20 30 40 50
15 25 35 45 55
20 30 40 50 60

Ou:

10 20 30 40 50,15 25 35 45 55,20 30 40 50 60

Cada lista de números representa uma lista dos valores de reputação dos usuários em um único dia.

Resultado

A saída será a mesma quantidade de nlinhas (ou uma lista separada por vírgulas do mesmo comprimento). Cada item de linha / lista será:

  • :D se houvesse um usuário cuja reputação se tornasse> = 10.000.
    • Vários :Ds separados por espaço, se houver vários usuários que atenderam ou passaram a contagem de 10.000 repetições. Por exemplo, :D :D :Dpara 3 novos usuários de 10.000.
  • :( e, em seguida, interrompa a saída se a entrada for ambígua ou impossível (mais sobre isso na próxima seção).
  • nada se nenhuma dessas condições for verdadeira.

Ambiguidade

É possível que a entrada seja ambígua. Para os propósitos deste desafio, assumimos que:

  • O limite de reputação é de 200 por dia, ignorando aceita e recompensas e afins pelo desafio.
  • Os usuários não podem perder a reputação (novamente por simplicidade e pelo desafio).

A entrada é considerada ambígua quando é impossível determinar quais valores de reputação correspondem a qual usuário. Por exemplo, na entrada 10 20,30 40, você não pode dizer se o usuário de 10 representantes se tornou o usuário de 30 representantes ou o usuário de 40 representantes.

A entrada é considerada impossível quando os usuários de um dia não poderiam ter se tornado usuários do dia seguinte. Por exemplo, na entrada 10 20,310 320, essa situação é claramente impossível porque os usuários não poderiam ter conquistado 300 reputação em um dia. Usuários perdendo reputação também são impossíveis.

Casos de borda

  • Os valores iniciais da reputação podem começar em qualquer coisa (ou seja, um usuário pode começar com a reputação 1337).
  • Não há saída para o primeiro item de linha / lista.
  • A entrada sempre será sintaticamente válida, o que significa que os valores de reputação sempre serão números inteiros positivos; sempre haverá a mesma quantidade de valores de reputação por item de linha / lista etc.
  • Os valores da reputação não são classificados; eles podem estar em qualquer ordem.

Casos de teste

Entrada: 9900,10000
Saída::D

Entrada: 9900 9950 9910,10100 9950 9910,10300 10150 10110
Saída::D,:D :D

Entrada: 10 20 30,42 10 20,10 242 20,442 42 10,0 0 0,442 42 10
Saída:,,,:(

Entrada: 10 20,15 25,15 25
Saída:,,

Entrada: 9999 9998 9997,10000 9998 9997,10000 10000 9997,10300 10000 10000
Saída::D,:D,:(

Entrada: 100,90,80,70
Saída::(

Entrada: 10000 10000 10000 9999,10000 10000 10000 10000,10010 10020 10030 10040
Saída::D,:(

Entrada: 9999 9998 9997 9996,10196 10197 10198 10199,10399 10199 10197 10196
Saída::D :D :D :D,


@ MartinBüttner Ah, não percebi isso. Corrigido
Maçaneta da porta

O primeiro passo nesse exemplo também é ambíguo.
Martin Ender

11
Enquanto o exemplo 4 não é ambíguo.
Martin Ender

(i.e. a user can start with 1337 reputation).Eu gostei desse coz que era meu representante ... bem, 5 minutos atrás, até que alguém votou positivamente sobre uma de minhas respostas xD
Teun Pronk

Exemplo 5, a etapa 2 também é ambígua (qual usuário de 10k é qual?). O mesmo vale para o exemplo 7 (a menos que você adicione alguma regra de que discernir usuários com representantes iguais é irrelevante, mas como você sabe qual usuário era qual no primeiro dia, se ele se empatou com outra pessoa mais tarde?)
Martin Ender

Respostas:


12

Ruby, 209 bytes

Edit: Eu mudei para Ruby, que reduziu isso em cerca de 30%. Veja o histórico de edições para a versão original do Mathematica. Suponho que as principais economias venham do Ruby permutationnão ignorar posições trocadas de elementos idênticos (nos quais eu tive que enganar o Mathematica).

Isso usa o formato separado por nova linha.

gets.split('
').map{|s|s.split.map &:to_i}.each_cons(2){|a,b|a.permutation.map{|q|q.zip(b).map{|x,y|y-x}}.reject{|d|d.any?{|x|x<0||x>200}}.size!=1?abort(':('):(puts':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))}

A essência é esta:

  • Obtenha todos os pares consecutivos de dias.
  • Obtenha todas as permutações do dia anterior e subtraia cada uma delas do dia atual.
  • Abandone todos os resultados que contenham diferenças negativas ou maiores 200.
  • Se o número de permutações restantes não for 1, produza :(.
  • Caso contrário, produza quantos :Dnovos usuários 10k.
  • No final, solte todos os dias após o primeiro :(.

Menos golfe:

gets.split("\n").map{|s|
  s.split.map &:to_i
}.each_cons(2){|a,b|
  a.permutation.map{|q|
    q.zip(b).map{|x,y|
      y-x
    }
  }.reject{|d|
    d.any?{|x|
      x<0||x>200
    }
  }.size!=1 ? abort(':(') : (puts ':D '*(a.count{|d|d<1e4}-b.count{|d|d<1e4}))
}

Eu acho que é uma bela cadeia de enumeradores. :)

PS: É estranho que eu tenha sido o primeiro a enviar uma resposta para isso?


8
Eu não acho estranho. Alguma coisa me diz que você tem a vantagem
9788 Calvin's Hobbies

Então, isso falhará em alguns exemplos da pergunta, certo?
Cruncher

@ Cruncher Irá falhar aqueles que eu acho que estão errados de acordo com as especificações (como eu mencionei nos comentários). Se a maçaneta da porta decidir alterar as especificações em vez de corrigir os exemplos, acho que terei que refazer isso.
Martin Ender

@ MartinBüttner Isso é o que eu imaginei. Apenas confirmando :)
Cruncher

6

Haskell, 254 249 244 232 228

import Data.List
t=m(9999<)
p(a:b:r)=(a,b,r)%(filter(all(`elem`[0..200]))$nub$m(zipWith(-)b)$permutations a)
p _=""
(a,b,r)%(_:[])=(concat$m(const":D ")$t b\\t a)++'\n':p(b:r)
_%_=":("
m=map
main=interact$p.m(m read.words).lines

Uma pequena explicação: o algoritmo é muito semelhante ao usado por MartinBüttner, exceto pelo nubque eu pensei um pouco. Note que a diferença lista é usada para trabalhar fora quantos mais reputação valores são 10000 ou maior no dia n + 1 em relação ao dia n: t b\\t a.

Também concordo com MartinBüttner na interpretação das especificações e que alguns dos exemplos acima estão errados, até o ponto em que o exemplo 2 esteja errado (deveria estar :().


Você não deveria usar o pseudônimo map?
haskeller orgulhoso

11
Isso mesmo (economizando 2 bytes), mas outros 10 bytes podem ser salvos criando zinfix e substituindo-o replicate (length l) xpor map (const x) l. Haskell não é fantástico?
TheSpanishInquisition

com certeza é. Bom golfe! Na mesma nota, como o aplicativo de função tem a maior precedência, você poderá reduzi (t b)\\(t a)- t b\\t alo para obter mais 4 bytes.
haskeller orgulhoso

Seria bom se houvesse algum código para encontrar esses lugares onde o código pode ser reduzido automaticamente ... Parece um projeto um pouco grande.
haskeller orgulhoso

Você está certo @proudhaskeller, essas parênteses eram desnecessárias. Obrigado.
TheSpanishInquisition
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.