Congratulazioni per aver ottenuto la reputazione di 10.000!


19

Dopo che @ MartinBüttner ha raggiunto esattamente 10.000 reputazione , ora abbiamo tre file complete di 10k utenti sulla pagina degli utenti ! Ora, dato che siamo tutti programmatori qui, ci piace automatizzare le cose invece di eseguirle manualmente. La tua sfida è scrivere un programma per congratularmi automaticamente con i nuovi utenti 10k.

specificazione

Ingresso

L'input sarà costituito da nrighe di numeri separati da spazi. (Se lo desideri, puoi anche prendere un unico elenco separato da virgole di numeri separati da spazi, se ciò rende il tuo codice più breve.) Ad esempio:

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

O:

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

Ogni elenco di numeri rappresenta un elenco di valori di reputazione degli utenti in un solo giorno.

Produzione

L'output sarà lo stesso numero di nrighe (o un elenco separato da virgole della stessa lunghezza). Ogni riga / voce di elenco sarà:

  • :D se c'era un utente la cui reputazione è appena diventata> = 10.000.
    • Più spazi separati da spazio :Dse c'erano più utenti che hanno incontrato o superato il conteggio dei 10.000 rappresentanti. Ad esempio, :D :D :Dper 3 nuovi utenti 10k.
  • :( e quindi interrompere l'output ulteriore se l'input è ambiguo o impossibile (ne parleremo più avanti nella prossima sezione).
  • niente se nessuna di queste condizioni è vera.

Ambiguità

È possibile che l'input sia ambiguo. Ai fini di questa sfida, assumiamo che:

  • Il limite di reputazione è di 200 al giorno, ignorando accetta e taglie e simili per il bene della sfida.
  • Gli utenti non possono perdere la reputazione (di nuovo per semplicità e per la sfida).

L'input è considerato ambiguo quando è impossibile determinare quali valori di reputazione corrispondono a quale utente. Ad esempio, nell'input 10 20,30 40, non è possibile stabilire se l'utente con 10 rep è diventato l'utente con 30 rep o l'utente con 40 rep.

L'input è considerato impossibile quando gli utenti di un giorno non possono essere diventati gli utenti del giorno successivo. Ad esempio, nell'input 10 20,310 320, questa situazione è chiaramente impossibile perché gli utenti non avrebbero potuto guadagnare 300 reputazione in un giorno. È anche impossibile perdere la reputazione degli utenti.

Custodie per bordi

  • I valori di reputazione iniziale possono iniziare da qualsiasi cosa (ovvero un utente può iniziare con 1337 reputazione).
  • Non c'è output per la prima riga / voce dell'elenco.
  • L'input sarà sempre sintatticamente valido, il che significa che i valori di reputazione saranno sempre numeri interi positivi, ci sarà sempre la stessa quantità di valori di reputazione per riga / elemento dell'elenco, ecc.
  • I valori di reputazione non sono ordinati; possono essere in qualsiasi ordine.

Casi test

Ingresso: 9900,10000
Uscita::D

Ingresso: 9900 9950 9910,10100 9950 9910,10300 10150 10110
Uscita::D,:D :D

Ingresso: 10 20 30,42 10 20,10 242 20,442 42 10,0 0 0,442 42 10
Uscita:,,,:(

Ingresso: 10 20,15 25,15 25
Uscita:,,

Ingresso: 9999 9998 9997,10000 9998 9997,10000 10000 9997,10300 10000 10000
Uscita::D,:D,:(

Ingresso: 100,90,80,70
Uscita::(

Ingresso: 10000 10000 10000 9999,10000 10000 10000 10000,10010 10020 10030 10040
Uscita::D,:(

Ingresso: 9999 9998 9997 9996,10196 10197 10198 10199,10399 10199 10197 10196
Uscita::D :D :D :D,


@ MartinBüttner Ah, non me ne sono accorto. Risolto
Maniglia della porta

Anche il primo passo in questo esempio è ambiguo.
Martin Ender,

1
Considerando che l'esempio 4 non è ambiguo.
Martin Ender,

(i.e. a user can start with 1337 reputation).Mi è piaciuto questo coz che era il mio rappresentante ... wel 5 min fa fino a quando qualcuno ha annullato una delle mie risposte xD
Teun Pronk

Nell'esempio 5, il passaggio 2 è anche ambiguo (quale utente 10k è quale?). Lo stesso vale per l'esempio 7 (a meno che non si aggiunga una regola secondo cui gli utenti discernenti di pari livello sono irrilevanti, ma come si fa a sapere quale utente era quale il primo giorno, se ha legato con qualcun altro in seguito?)
Martin Ender

Risposte:


12

Rubino, 209 byte

Modifica: sono passato a Ruby che lo ha abbreviato di circa il 30%. Vedi la cronologia delle modifiche per la versione originale di Mathematica. Suppongo che i risparmi principali derivino dal fatto che Ruby permutationnon ignora le posizioni scambiate di elementi identici (che ho dovuto ingannare Mathematica).

Questo utilizza il formato separato da nuova riga.

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'essenza è questa:

  • Ottieni tutte le coppie consecutive di giorni.
  • Ottieni tutte le permutazioni del primo giorno e sottrale ognuna dal giorno corrente.
  • Elimina tutti i risultati che contengono differenze negative o maggiori di 200.
  • Se il numero di permutazioni rimanenti non è 1, emettere :(.
  • Altrimenti, genera quanti :Dne sono i nuovi utenti 10k.
  • Alla fine, rilascia tutti i giorni dopo il primo :(.

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

Penso che sia una bellissima catena di enumeratori. :)

PS: È strano che io sia stato il primo a inviare una risposta a questo?


8
Non penso sia strano. Qualcosa mi dice che hai il vantaggio sul campo di casa;)
Calvin's Hobbies

Quindi questo fallirà alcuni degli esempi nella domanda, giusto?
Cruncher,

@Cruncher Fallirà quelli che penso siano sbagliati secondo le specifiche (come ho già detto nei commenti). Se Doorknob decide di cambiare le specifiche invece di correggere gli esempi, suppongo che dovrò rielaborarlo.
Martin Ender,

@ MartinBüttner Questo è quello che ho pensato. Sto solo confermando :)
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

Una piccola spiegazione: l'algoritmo è molto simile a quello usato da MartinBüttner, tranne quello su nubcui ho riflettuto. Si noti che la differenza elenco viene utilizzato per lavorare fuori quanti reputazione valori sono 10000 o più grandi nel giorno n + 1 rispetto al giorno n: t b\\t a.

Concordo anche con MartinBüttner sull'interpretazione delle specifiche e che alcuni degli esempi sopra riportati sono sbagliati, anche al punto che l'esempio n. 2 è sbagliato (dovrebbe essere :().


Non dovresti alias map?
orgoglioso haskeller il

1
Esatto (salvataggio di 2 byte), ma è possibile salvare altri 10 byte effettuando zinfix e sostituendoli replicate (length l) xcon map (const x) l. Haskell non è fantastico?
TheSpanishInquisition

lo è di sicuro. Bel golf! In tal senso, perché l'applicazione funzioni ha la precedenza più alta, si dovrebbe essere in grado di ridurre (t b)\\(t a)a t b\\t a, golf di più 4 byte.
orgoglioso haskeller il

Sarebbe bello se ci fosse del codice per trovare questi luoghi in cui il codice può essere abbreviato automaticamente ... Sembra un po 'grande di un progetto però.
orgoglioso haskeller il

Hai ragione @proudhaskeller, quelle paretesi erano inutili. Grazie.
TheSpanishInquisition
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.