Perl 69 byte
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Funziona con la formula magica. L'espressione "32e$&"%72726
trasforma ogni cifra nel modo seguente:
0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Dopo aver applicato la traduzione y/016/IXV/
, abbiamo invece questo:
0⇒32, 1⇒32 I , 2⇒32 II , 3⇒32 III , 4⇒29 I 9 V , 5⇒5 V , 6⇒5 VI , 7⇒5 VII , 8⇒5 VIII , 9⇒5 I 9 X 8
Il resto delle cifre ( 2-57-9
) vengono rimosse. Si noti che questo potrebbe essere migliorata un byte utilizzando una formula che traduce 012
invece 016
, semplificando /XVI60-9/
al /XVI0-9/
. Non sono riuscito a trovarne uno, ma forse avrai più fortuna.
Una volta che una cifra è stata trasformata in questo modo, il processo si ripete per la cifra successiva, aggiungendo il risultato e traducendo le XVI
s precedenti CLX
contemporaneamente alla traduzione per la nuova cifra.
Aggiorna La
ricerca esaustiva non ha rivelato niente di più breve. Tuttavia, ho trovato una soluzione alternativa a 69 byte:
s;.;y/XVI0-9/CLXIXV/dfor$a[$_].="57e$&"%474976;gefor 1..100;print"@a"
Questo utilizza una 0-2
sostituzione per IXV
, ma ha un modulo più lungo di una cifra.
Aggiornamento: 66 65 byte
Questa versione è notevolmente diversa, quindi dovrei probabilmente dire qualche parola al riguardo. La formula che utilizza è in realtà un byte in più!
Incapace di abbreviare la formula più di quello che è, ho deciso di giocare a golf quello che avevo. Non passò molto tempo che mi ricordai del mio vecchio amico $\
. Quando print
viene emessa una dichiarazione, $\
viene automaticamente aggiunta alla fine dell'output. Sono stato in grado di liberarmi della $a[$_]
costruzione scomoda per un miglioramento di due byte:
s;.;y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726;ge,$\=!print$"for 1..100
Molto meglio, ma $\=!print$"
sembrava ancora un po 'prolisso. Ho poi ricordato una formula alternativa di uguale lunghezza che avevo trovato che non conteneva il numero 3
in nessuna delle sue trasformazioni di cifre. Quindi, dovrebbe essere possibile utilizzare $\=2+print
invece e sostituire il risultato 3
con uno spazio:
s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;ge,$\=2+print for 1..100
Anche 67 byte, a causa dello spazio bianco necessario tra print
e for
.
Modifica : questo può essere migliorato di un byte, spostando print
in primo piano:
$\=2+print!s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;gefor 1..100
Poiché la sostituzione deve essere valutata completamente prima di print
, l'assegnazione a $\
verrà comunque eseguita per ultima. La rimozione dello spazio tra ge
e for
genererà un avviso di deprecazione, ma è altrimenti valida.
Ma, se esistesse una formula che non utilizzava un 1
punto qualsiasi, $\=2+print
diventa $\=print
un risparmio di altri due byte. Anche se fosse più lungo di un byte, sarebbe comunque un miglioramento.
A quanto pare, esiste una formula del genere, ma è più lunga di un byte rispetto all'originale, con un punteggio finale di 65 byte :
$\=print!s;.;y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366;gefor 1..100
Metodologia
Alla domanda è stato chiesto come si potrebbe andare a trovare una tale formula. In generale, trovare una formula magica per generalizzare qualsiasi insieme di dati è una questione di probabilità. Cioè, vuoi scegliere una forma che è il più probabile possibile per produrre qualcosa di simile al risultato desiderato.
Esporre i primi numeri romani:
0:
1: I
2: II
3: III
4: IV
5: V
6: VI
7: VII
8: VIII
9: IX
c'è un po 'di regolarità da vedere. In particolare, da 0-3 e poi di nuovo da 5-8 , ogni termine successivo aumenta in lunghezza di un numero. Se volessimo creare una mappatura da cifre a numeri, vorremmo avere un'espressione che aumenti anche in lunghezza di una cifra per ogni termine successivo. Una scelta logica è k • 10 d dove d è la cifra corrispondente e k è qualsiasi costante intera.
Funziona per 0-3 , ma 4 deve interrompere il modello. Quello che possiamo fare qui è virare su un modulo:
k • 10 d % m , dove m è da qualche parte tra k • 10 3 e k • 10 4 . Questo lascerà intatto l'intervallo 0-3 e modificherà 4 in modo tale che non contenga quattro I
secondi. Se limitiamo ulteriormente il nostro algoritmo di ricerca in modo tale che il residuo modulare di 5 , chiamiamolo j , sia inferiore a m / 1000 , ciò assicurerà che anche la regolarità sia compresa tra 5-8 . Il risultato è qualcosa del genere:
0: k
1: k0
2: k00
3: k000
4: ????
5: j
6: j0
7: j00
8: j000
9: ????
Come puoi vedere, se sostituiamo 0
con I
, 0-3 e 5-8 sono tutti garantiti per essere mappati correttamente! Tuttavia, i valori per 4 e 9 devono essere forzati brutalmente. In particolare, 4 deve contenere uno 0
e uno j
(in quell'ordine) e 9 deve contenere uno 0
, seguito da un'altra cifra che non appare da nessun'altra parte. Certamente, ci sono un certo numero di altre formule, che per un caso di coincidenza potrebbero produrre il risultato desiderato. Alcuni potrebbero anche essere più brevi. Ma non credo che ci siano quelli che hanno le stesse probabilità di successo come questo.
Ho anche sperimentato più sostituzioni per I
e / o V
con un certo successo. Ma ahimè, niente di più breve di quello che avevo già. Ecco un elenco delle soluzioni più brevi che ho trovato (il numero di soluzioni 1-2 byte più pesanti sono troppe da elencare):
y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726
y/XVI0-9/CLXIXV/dfor$\.="57e$&"%474976
y/XVI0-9/CLXIVXI/dfor$\.="49e$&"%87971
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%10606 #
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%15909 # These are all essentially the same
y/XVI0-9/CLXIIXIV/dfor$\.="7e$&"%31818 #
y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535 # Doesn't contain 3 anywhere
y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366 # Doesn't contain 1 anywhere