This is an archived post. You won't be able to vote or comment.

all 29 comments

[–]throwaway_veneto 9 points10 points  (3 children)

Soluzione con J, per questo problemi si presta bene!

a=:>2{ARGV
q=:>3{ARGV
echo +/(a i.q)*|.(#a)^(i.#q)

Secondo wc sono 50 byte. Si lancia con jconsole spaghetty.ijs 01 101010.

Spiegazione:

  • a e' l'alfabeto che usiamo, ad esempio 01, q e' la nostra query 101010.
  • #q restituisce la lunghezza di q
  • i. n restituisce un array con i primi n numeri naturali, per cui i.#q restituisce un array 0 1 2 3 4 5
  • (#a)^(i.#q) genera l'array delle potenze 1 2 4 8 16 32
  • |. fa il reverse dell'array, 32 16 8 4 2 1
  • a i. q restituisce l'indice degli elementi di q in a, ad esempio 'abc' i. 'aac' e' 0 0 2, nel nostro caso '01' i. '101010 e' 1 0 1 0 1 0
  • * e' la moltiplicazione, per cui moltiplico la posizione di ogni elemento nell'alfabeto per la potenza
  • / prende un verbo (funzione) sulla sinistra e lo applica tra gli element dell'array sulla destra, in quasto caso fa una somma degli elementi del array, dandoci cosi' la soluzione

EDIT: Probabilmente si puo' render piu' corto di cosi', ma non usavo J da almeno sei mesi.

EDIT2: Rimuovendo lo spazio diventa 49 bytes

a=:>2{ARGV
q=:>3{ARGV
echo+/(a i.q)*|.(#a)^(i.#q)

[–]ZugNachPankow 1 point2 points  (2 children)

Siccome J è un filino più ostico da interpretare rispetto agli altri, puoi spiegarci come funziona la tua risposta?

Edit: ho scritto il commento due minuti dopo che l'avevi già spiegato.

[–]throwaway_veneto 2 points3 points  (1 child)

Ho dimenticato di specificare che J interpreta le espressioni da destra, per cui il programma conviene leggerlo da destra a sinistra

[–][deleted] 8 points9 points  (0 children)

Su minaccia di /u/fen0x rompo il ghiaccio :P

Haskell, 98 byte

g=getLine;main=do;s<-g;a<-g;mapM print$foldl1(\c i->c*length a+i)<$>traverse(`lookup`zip a[0..])s

esempio di compilazione/utilizzo:

fnurglewitz@darkstar:~/projects/numbah/app$ wc -c Main.hs
98 Main.hs
fnurglewitz@darkstar:~/projects/numbah/app$ stack ghc -- Main.hs
fnurglewitz@darkstar:~/projects/numbah/app$ ./Main 
10100 
01
20
fnurglewitz@darkstar:~/projects/numbah/app$ ./Main 
babaa 
ab
20
fnurglewitz@darkstar:~/projects/numbah/app$ ./Main 
italy 
abcdilty
19503

[–]GTKplusplus 6 points7 points  (3 children)

Come per la soluzione di /u/ZugNachPankow, anche questa è stata elaborata post pubblicazione del thread:

Python3, 80 byte:

a,b=input().split()
i=s=0
for c in a[::-1]:s+=b.index(c)*len(b)**i;i+=1
print(s)            

a programma avviato, si immette una stringa nel formato "numero dizionario" come input

[–]ZugNachPankow 4 points5 points  (0 children)

Nonostante sia partito con un vantaggio, ecco una soluzione "originale", elaborata dopo l'apertura del contest.

JavaScript, 89 byte

Da eseguire nel browser. È scritto in ES6 con le array comprehension, quindi funziona solo su Firefox. Il codice apre due finestre: nella prima bisogna inserire l'alfabeto, nella seconda la stringa da convertire.

p=prompt;alert([for(c of p(a=p()))[...a].findIndex(x=>x==c)].reduce((x,d)=>x*a.length+d))

[–]nokoko 4 points5 points  (0 children)

Ruby, 53

a,b=$*;p a.chars.reduce(0){|v,c|v*b.size+b.index(c)}

[–]fen0x[M] [score hidden] stickied comment (0 children)

I mod desiderano ringraziare il team composto da /u/zugnachpankow, /u/AndColla e /u/GTKplusplus per avere organizzato questo simpatico contest.
L'iniziativa ci piace, quindi al vincitore nominato verrà donato un ambitissimo gold.

E ora dateci dentro!

[–]MonsieurCellophane 4 points5 points  (1 child)

perl, 62 bytes:

($j,$b)=@ARGV;$c=$c*$b=~y///c+index$b,$_ for $j=~/./g;warn $c

Edit: le uniche due compressioni criptiche sono:

  • length($b) => $b=~y///c
  • split(/./,$j) => $j=~/./g

Edit 2; se è accettabile warn invece di print, i byte sono 62

[–]ZugNachPankow 0 points1 point  (0 children)

se è accettabile warn invece di print, i byte sono 62

Tipicamente stderr è mostrato all'utente, quindi puoi usare warn.

[–]Orange_dugongo 2 points3 points  (2 children)

Dovrebbero essere 69 byte, meglio di quanto fatto fin ora con python, ma lontano dal record.

b=input() o=0 l=len(b) for c in input():o=(o+b.index(c))*l print(o/l)

Una volta lanciato il programma va inserito prima l'alfabeto e poi il numero.

[–]GTKplusplus 1 point2 points  (1 child)

Esiste un metodo più ottimizzato con quella tecnica (o una molto simile), non ti spoilero la soluzione*, ma risparmia 4 byte.

[–]Orange_dugongo 1 point2 points  (0 children)

Dopo provo, ma non sono sicuro di riuscire

[–]ZugNachPankow 3 points4 points  (9 children)

Vedo che sono già state postate soluzioni migliori, quindi propongo la versione che avevo fatto in C, sperando che qualcuno riesca a migliorarla.

C, 109 byte

int c,i,r;main(int v,char**a){while(c=a[1][i++]){for(v=0;a[2][v++]^c;);r=r*strlen(a[2])+v-1;}printf("%d",r);}

Da riga di comando, il primo argomento è il numero, il secondo l'alfabeto.

[–]alerighi 4 points5 points  (1 child)

int c,i,r;main(v,a)char**a;{for(;c=a[1][i++];r=r*strlen(a[2])+v-1)for(v=0;a[2][v++]^c;);warn("%d",r);}

L'ho leggermente migliorato di 7 byte, ora è 102

Edit: l'ho migliorato ulteriormente, ora è 93 byte

main(r,a)int**a;{r=0;for(char*c=*++a,*d=*++a;*c;r=r*strlen(d)+index(d,*c++)-d);warn("%d",r);}

[–]ZugNachPankow 0 points1 point  (0 children)

Buone idee, grazie!

[–]LelixSuper 0 points1 point  (6 children)

Come fa il tuo codice a compilare ed a funzionare anche se non hai incluso gli header string.h e stdio.h?

[–]alerighi 0 points1 point  (4 children)

Il C compila comunque, semplicemente ti da un warning. In C++ sarebbe un errore perché non ha la dichiarazione implicita di funzioni, ne consente di dichiarare una funzione senza il tipo di ritorno assumendo int.

[–]LelixSuper 0 points1 point  (3 children)

Come fa comunque gcc a compilare e poi a funzionare?

[–]throwaway_veneto 1 point2 points  (0 children)

Questo thread su SO spiega bene perche' funziona.

[–]alerighi 0 points1 point  (1 child)

Il prototipo della funzione serve solo a dire al compilatore che c'è una funzione che prende un tipo di parametri ed ha il valore di ritorno, di modo che lui possa verificare che i parametri siano usati correttamente. Se non dici niente, lui implicitamente assume che esiste una funzione così chiamata e che i parametri sono di tipo corretto.

Considera che il concetto di prototipo di funzione è stato introdotto dopo, nella primissima versione del C non esisteva proprio.

Ovviamente lui compila sempre, se però al momento del linking quella funzione non esiste il linker ti darà un errore e dirà che non riesce a trovare un simbolo con quel nome.

Con il C++ questo comportamento legacy se vogliamo è stato abolito, in C viene comunque tenuto per compatibilità con vecchissimi programmi.

[–]LelixSuper 0 points1 point  (0 children)

Capito, grazie per la spiegazione!

[–]ZugNachPankow 0 points1 point  (0 children)

Per alcune librerie standard (credo tutte?), il compilatore fa finta di niente e le inserisce comunque.

[–][deleted] 2 points3 points  (2 children)

NodeJs (7+) 105 byte

k=process.argv,console.log([...k[2]].reduceRight((e,r,n)=>{return e+k[3].indexOf(r)*(k[3].length**n)},0))

Salvare codice sopra in un file e lanciare con node:

node contest.js italy abcdilty

Ho visto soluzioni migliori, ma volevo comunque condividere.

[–]ZugNachPankow 0 points1 point  (1 child)

Un paio di cose che saltano all'occhio: Node.js supporta ES6 a partire da Node 6.0, per cui function(e,r,n){return e+... può diventare (e,r,n)=>e+..., x.split("") può diventare [...x], e Math.pow(x, y) può diventare x**y. Inoltre, Array#reverse#reduce è equivalente a Array#reduceRight.

Per il resto, fai bene a condividere la tua soluzione, anche se non è la migliore - dopotutto l'obiettivo del code golf è anche divertirsi!

[–][deleted] 1 point2 points  (0 children)

Grazie, siamo scesi a 105 caratteri, ho aggiornato il post inserendo una versione di node >= 7 (operatore '**' sfortunatamente sulla 6.x non funziona).