Perl 69 Bytes
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Arbeitet nach einer magischen Formel. Der Ausdruck "32e$&"%72726
transformiert jede Ziffer auf folgende Weise:
0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Nach Anwenden der Übersetzung y/016/IXV/
haben wir stattdessen Folgendes :
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
Die restlichen Ziffern ( 2-57-9
) werden entfernt. Beachten Sie, dass diese durch einen Byte verbessert werden könnte eine Formel unter Verwendung der übersetzt 012
statt 016
, die Vereinfachung /XVI60-9/
zu /XVI0-9/
. Ich konnte keinen finden, aber vielleicht hast du mehr Glück.
Sobald eine Ziffer auf diese Weise transformiert wurde, wird der Vorgang für die nächste Ziffer wiederholt, wobei das Ergebnis angehängt und die vorherigen XVI
s zur CLX
gleichen Zeit übersetzt werden, zu der die Übersetzung für die neue Ziffer erfolgt.
Update Die
ausführliche Suche ergab keine kürzeren Ergebnisse. Ich habe jedoch eine alternative 69-Byte-Lösung gefunden:
s;.;y/XVI0-9/CLXIXV/dfor$a[$_].="57e$&"%474976;gefor 1..100;print"@a"
Dieser verwendet eine 0-2
Substitution für IXV
, hat aber ein Modulo, das eine Ziffer länger ist.
Update: 66 65 Bytes
Diese Version unterscheidet sich erheblich, daher sollte ich wahrscheinlich ein paar Worte dazu sagen. Die verwendete Formel ist tatsächlich ein Byte länger!
Da ich die Formel nicht mehr verkürzen konnte, entschied ich mich, das, was ich hatte, herunterzuspielen. Es dauerte nicht lange, bis ich mich an meinen alten Freund erinnerte $\
. Wenn eine print
Anweisung ausgegeben wird, $\
wird sie automatisch an das Ende der Ausgabe angehängt. Ich konnte die umständliche $a[$_]
Konstruktion für eine Zwei-Byte-Verbesserung loswerden :
s;.;y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726;ge,$\=!print$"for 1..100
Viel besser, aber das $\=!print$"
sah immer noch ein bisschen wortreich aus. Ich erinnerte mich dann an eine alternative Formel gleicher Länge, die ich gefunden hatte und die die Zahl 3
in keiner ihrer Zifferntransformationen enthielt . Daher sollte es möglich sein, $\=2+print
stattdessen Folgendes zu verwenden und das Ergebnis 3
durch ein Leerzeichen zu ersetzen :
s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;ge,$\=2+print for 1..100
Auch 67 Bytes, aufgrund des notwendigen Leerzeichens zwischen print
und for
.
Bearbeiten : Dies kann um ein Byte verbessert werden, indem das print
nach vorne verschoben wird:
$\=2+print!s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;gefor 1..100
Da die Substitution vor dem vollständig ausgewertet werden muss print
, wird die Zuweisung zu $\
immer noch als letztes erfolgen. Wenn Sie das Leerzeichen zwischen ge
und entfernen, for
wird eine Warnung angezeigt, die jedoch ansonsten gültig ist.
Aber wenn es eine Formel gäbe, die 1
nirgendwo eine verwendet, würden $\=2+print
sich $\=print
für weitere zwei Bytes Einsparungen ergeben. Selbst wenn es ein Byte länger wäre, wäre es immer noch eine Verbesserung.
Wie sich herausstellt, gibt es eine solche Formel, die jedoch ein Byte länger ist als das Original, was zu einer Endbewertung von 65 Bytes führt :
$\=print!s;.;y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366;gefor 1..100
Methodik
Die Frage wurde gestellt, wie man eine solche Formel finden könnte. Im Allgemeinen ist es eine Frage der Wahrscheinlichkeit, eine Zauberformel zur Verallgemeinerung eines beliebigen Datensatzes zu finden. Das heißt, Sie möchten eine Form auswählen, die mit größter Wahrscheinlichkeit zu einem ähnlichen Ergebnis wie das gewünschte führt.
Prüfung der ersten römischen Ziffern:
0:
1: I
2: II
3: III
4: IV
5: V
6: VI
7: VII
8: VIII
9: IX
Es gibt eine gewisse Regelmäßigkeit zu sehen. Insbesondere von 0 bis 3 und dann wieder von 5 bis 8 wird jeder aufeinanderfolgende Term um eine Ziffer länger. Wenn wir eine Zuordnung von Ziffern zu Zahlen schaffen wollten, würden wir einen Ausdruck haben , die auch durch eine Ziffer für jeden folgenden Ausdruck in der Länge zunimmt. Eine logische Wahl ist k · 10 d, wobei d die entsprechende Ziffer ist und k eine beliebige Ganzzahlkonstante ist.
Dies funktioniert für 0-3 , aber 4 muss das Muster brechen. Was wir hier tun können, ist ein Modulo anzuheften:
k · 10 d % m , wobei m irgendwo zwischen k · 10 3 und k · 10 4 liegt . Dadurch bleibt der Bereich 0-3 unverändert, und 4 wird so geändert, dass er keine vier I
Sekunden enthält. Wenn wir unseren Suchalgorithmus zusätzlich so einschränken, dass der modulare Rest von 5 , nennen wir es j , kleiner als m / 1000 ist , wird sichergestellt, dass wir auch eine Regelmäßigkeit von 5-8 haben . Das Ergebnis ist ungefähr so:
0: k
1: k0
2: k00
3: k000
4: ????
5: j
6: j0
7: j00
8: j000
9: ????
Wie Sie sehen können, wenn wir ersetzen 0
mit I
, 0-3 und 5-8 sind alle garantiert korrekt abgebildet werden! Die Werte für 4 und 9 müssen allerdings brachial erzwungen werden. Insbesondere muss 4 eins 0
und eins j
(in dieser Reihenfolge) enthalten, und 9 muss eins enthalten 0
, gefolgt von einer anderen Ziffer, die an keiner anderen Stelle erscheint. Sicher gibt es eine Reihe anderer Formeln, die durch einen Zufall das gewünschte Ergebnis erzielen könnten. Einige von ihnen können sogar kürzer sein. Aber ich glaube nicht, dass es welche gibt, die genauso erfolgreich sind wie diese.
Ich experimentierte auch mit mehrfachem Ersatz für I
und / oder V
mit einigem Erfolg. Aber leider nichts kürzer als das, was ich schon hatte. Hier ist eine Liste der kürzesten Lösungen, die ich gefunden habe (die Anzahl der 1-2 Bytes schwereren Lösungen ist zu groß, um sie aufzulisten):
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