Félicitations pour avoir obtenu 10 000 points de réputation!

19

Après que @ MartinBüttner ait atteint exactement 10 000 points de réputation , nous avons maintenant trois rangées complètes de 10 000 utilisateurs sur la page des utilisateurs ! Maintenant, puisque nous sommes tous des programmeurs ici, nous aimons automatiser les choses au lieu de les faire manuellement. Votre défi est d'écrire un programme pour féliciter automatiquement les nouveaux utilisateurs 10k.

spécification

Contribution

L'entrée sera des nlignes de nombres séparés par des espaces. (Si vous le souhaitez, vous pouvez également prendre une seule liste de nombres séparés par des virgules, si cela raccourcit votre code.) Par exemple:

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

Chaque liste de nombres représente une liste des valeurs de réputation des utilisateurs sur une seule journée.

Production

Le résultat sera le même nombre de nlignes (ou une liste séparée par des virgules de la même longueur). Chaque élément de ligne / liste sera:

  • :D s'il y avait un utilisateur dont la réputation venait de devenir> = 10 000.
    • Plusieurs espaces séparés par des espaces :Dsi plusieurs utilisateurs ont atteint ou dépassé le nombre de 10 000 représentants. Par exemple, :D :D :Dpour 3 nouveaux utilisateurs 10 000.
  • :( puis arrêtez la sortie si l'entrée est ambiguë ou impossible (plus à ce sujet dans la section suivante).
  • rien si aucune de ces conditions n'est vraie.

Ambiguïté

Il est possible que l'entrée soit ambiguë. Aux fins de ce défi, nous supposons que:

  • Le plafond de réputation est de 200 par jour, en ignorant les acceptations et les primes et autres pour le défi.
  • Les utilisateurs ne peuvent pas perdre de réputation (encore une fois pour la simplicité et pour le défi).

La saisie est considérée comme ambiguë lorsqu'il est impossible de déterminer quelles valeurs de réputation correspondent à quel utilisateur. Par exemple, dans l'entrée 10 20,30 40, vous ne pouvez pas dire si l'utilisateur 10 répétitions est devenu l'utilisateur 30 répétitions ou l'utilisateur 40 répétitions.

La saisie est considérée comme impossible lorsque les utilisateurs d'un jour n'auraient pas pu devenir les utilisateurs du lendemain. Par exemple, en entrée 10 20,310 320, cette situation est clairement impossible car les utilisateurs n'auraient pas pu gagner 300 points de réputation en une journée. La perte de réputation des utilisateurs est également impossible.

Cas de bord

  • Les valeurs de réputation initiales peuvent commencer à tout (c'est-à-dire qu'un utilisateur peut commencer avec 1337 points de réputation).
  • Il n'y a pas de sortie pour le premier élément de ligne / liste.
  • L'entrée sera toujours syntaxiquement valide, ce qui signifie que les valeurs de réputation seront toujours des entiers positifs, il y aura toujours la même quantité de valeurs de réputation par ligne / élément de liste, etc.
  • Les valeurs de réputation ne sont pas triées; ils peuvent être dans n'importe quel ordre.

Cas de test

Entrée: 9900,10000
Sortie::D

Entrée: 9900 9950 9910,10100 9950 9910,10300 10150 10110
Sortie::D,:D :D

Entrée: 10 20 30,42 10 20,10 242 20,442 42 10,0 0 0,442 42 10
Sortie:,,,:(

Entrée: 10 20,15 25,15 25
Sortie:,,

Entrée: 9999 9998 9997,10000 9998 9997,10000 10000 9997,10300 10000 10000
Sortie::D,:D,:(

Entrée: 100,90,80,70
Sortie::(

Entrée: 10000 10000 10000 9999,10000 10000 10000 10000,10010 10020 10030 10040
Sortie::D,:(

Entrée: 9999 9998 9997 9996,10196 10197 10198 10199,10399 10199 10197 10196
Sortie::D :D :D :D,

Poignée de porte
la source
@ MartinBüttner Ah, je n'ai pas remarqué ça. Corrigé
Poignée de porte
La première étape de cet exemple est également ambiguë.
Martin Ender
1
Alors que l'exemple 4 n'est pas ambigu.
Martin Ender
(i.e. a user can start with 1337 reputation).J'ai aimé ce coz qui était mon représentant ... il y a 5 minutes jusqu'à ce que quelqu'un vote pour une de mes réponses xD
Teun Pronk
Exemple 5, l'étape 2 est également ambiguë (quel utilisateur 10k est lequel?). Il en va de même pour l'exemple 7 (à moins que vous n'ajoutiez une règle selon laquelle le discernement des utilisateurs à répétition égale n'est pas pertinent, mais comment savoir alors quel utilisateur était lequel le premier jour, s'il était à égalité avec quelqu'un d'autre plus tard?)
Martin Ender

Réponses:

12

Rubis, 209 octets

Edit: je suis passé à Ruby qui a raccourci cela d'environ 30%. Voir l'historique des modifications pour la version originale de Mathematica. Je suppose que les principales économies proviennent du fait que Ruby n'a permutationpas ignoré les positions commutées d'éléments identiques (dans lesquelles j'ai dû piéger Mathematica).

Cela utilise le format séparé par les sauts de ligne.

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}))}

L'essentiel est le suivant:

  • Obtenez toutes les paires de jours consécutifs.
  • Obtenez toutes les permutations de la journée précédente et soustrayez chacune d'elles de la journée en cours.
  • Abandonnez tous les résultats qui contiennent des différences négatives ou supérieures à 200.
  • Si le nombre de permutations restantes n'est pas 1, affichez :(.
  • Sinon, générez autant :Dqu'il y a de nouveaux utilisateurs 10k.
  • À la fin, laissez tomber tous les jours après le premier :(.

Moins de golf:

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}))
}

Je pense que c'est une belle chaîne d'énumérateurs. :)

PS: Est-ce bizarre que j'ai été le premier à soumettre une réponse à cela?

Martin Ender
la source
8
Je ne pense pas que ce soit bizarre. Quelque chose me dit que vous avez l'avantage sur le terrain;)
Calvin's Hobbies
Donc, cela échouera à certains des exemples de la question, non?
Cruncher
@Cruncher Il échouera ceux qui, selon moi, sont erronés selon les spécifications (comme je l'ai mentionné dans les commentaires). Si Doorknob décide de changer la spécification au lieu de corriger les exemples, je suppose que je devrai retravailler cela.
Martin Ender
@ MartinBüttner C'est ce que je pensais. Je confirme juste :)
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

Une petite explication: l'algorithme est très similaire à celui utilisé par MartinBüttner, sauf le nub lequel j'ai réfléchi. Notez que la différence de liste est utilisée pour le travail combien plus les valeurs sont la réputation 10000 ou plus le jour n + 1 par rapport au jour n: t b\\t a.

Je suis également d'accord avec MartinBüttner sur l'interprétation des spécifications et sur le fait que certains des exemples ci-dessus sont faux, même au point que l'exemple # 2 est faux (devrait l'être :().

TheSpanishInquisition
la source
Vous ne devriez pas vous alias map?
fier haskeller
1
C'est vrai (économiser 2 octets), mais 10 autres octets peuvent être enregistrés en créant un zinfixe et en le remplaçant replicate (length l) xpar map (const x) l. Haskell n'est-il pas fantastique?
TheSpanishInquisition
Tout à fait. Bon golf! Sur cette note, étant donné que l'application de fonction a la priorité la plus élevée, vous devriez être en mesure de raccourcir (t b)\\(t a)jusqu'à t b\\t a4 octets de plus.
fier haskeller
Ce serait bien s'il y avait du code pour trouver ces endroits où le code peut être raccourci automatiquement ... Cela semble un peu gros cependant.
fier haskeller
Vous avez raison @proudhaskeller, ces paréthèses étaient inutiles. Merci.
TheSpanishInquisition