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$&"%72726trasforma 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 012invece 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 XVIs precedenti CLXcontemporaneamente 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-2sostituzione 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 printviene 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 3in nessuna delle sue trasformazioni di cifre. Quindi, dovrebbe essere possibile utilizzare $\=2+printinvece e sostituire il risultato 3con 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 printe for.
Modifica : questo può essere migliorato di un byte, spostando printin 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 gee forgenererà un avviso di deprecazione, ma è altrimenti valida.
Ma, se esistesse una formula che non utilizzava un 1punto qualsiasi, $\=2+printdiventa $\=printun 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 Isecondi. 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 0con 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 0e 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 Ie / o Vcon 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