Perl 69 bajtów
s;.;y/XVI60-9/CLXVIX/dfor$a[$_].="32e$&"%72726;gefor 1..100;print"@a"
Działa na podstawie magicznej formuły. Wyrażenie "32e$&"%72726przekształca każdą cyfrę w następujący sposób:
0 32 32, 1 20 320, 2 32 3200, 3 32 32000, 4 2 29096, 5 56 56, 6 5 560, 7 56 5600, 8 56 56000, 9 ⇒ 50918
Po zastosowaniu tłumaczenia y/016/IXV/otrzymujemy zamiast tego:
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
Reszta cyfr ( 2-57-9) jest usuwana. Należy zauważyć, że to może być poprawiona przez jeden bajt przy użyciu wzoru, co przekłada 012zamiast 016upraszcza /XVI60-9/się /XVI0-9/. Nie udało mi się go znaleźć, ale może będziesz miał więcej szczęścia.
Po przekształceniu jednej cyfry w ten sposób proces powtarza się dla następnej cyfry, dołączając wynik i tłumacząc poprzednie XVIs CLXw tym samym czasie, gdy następuje tłumaczenie nowej cyfry.
Aktualizacja
Wyczerpujące wyszukiwanie nie ujawniło nic krótszego. Znalazłem jednak alternatywne 69-bajtowe rozwiązanie:
s;.;y/XVI0-9/CLXIXV/dfor$a[$_].="57e$&"%474976;gefor 1..100;print"@a"
Ten używa 0-2podstawienia IXV, ale ma moduł dłuższy o jedną cyfrę.
Aktualizacja: 66 65 bajtów
Ta wersja jest wyraźnie inna, więc prawdopodobnie powinienem powiedzieć o niej kilka słów. Formuła, której używa, jest w rzeczywistości o jeden bajt dłużej!
Nie mogąc skrócić formuły dłużej, zdecydowałem się na grę w golfa. Nie trwało długo, zanim przypomniałem sobie mojego starego przyjaciela $\. Po printwydaniu zestawienia jest $\on automatycznie dołączany na końcu danych wyjściowych. Byłem w stanie pozbyć się niewygodnej $a[$_]konstrukcji, aby uzyskać dwubajtową poprawę:
s;.;y/XVI60-9/CLXVIX/dfor$\.="32e$&"%72726;ge,$\=!print$"for 1..100
Znacznie lepiej, ale $\=!print$"wciąż wyglądało to trochę gadatliwie. Potem przypomniałem sobie znalezioną przeze mnie alternatywną formułę równej długości, która nie zawierała liczby 3w żadnej z cyfr. Dlatego powinno być możliwe użycie $\=2+printzamiast tego i zastąpienie wynikowej 3spacją:
s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;ge,$\=2+print for 1..100
Również 67 bajtów, ze względu na niezbędną spację między printi for.
Edycja : Można to poprawić o jeden bajt, przesuwając printdo przodu:
$\=2+print!s;.;y/XVI0-9/CLXIIX V/dfor$\.="8e$&"%61535;gefor 1..100
Ponieważ podstawienie musi zostać całkowicie ocenione przed print, przypisanie do $\będzie nadal występować jako ostatnie. Usunięcie białych znaków między gei forspowoduje wyświetlenie ostrzeżenia o wycofaniu, ale w innym przypadku jest poprawne.
Ale gdyby istniała formuła, która 1nigdzie nie była używana , $\=2+printstaje się $\=printwarta kolejne dwa bajty oszczędności. Nawet gdyby był o jeden bajt dłużej, nadal byłaby to poprawa.
Jak się okazuje, taka formuła istnieje, ale jest o jeden bajt dłuższa niż oryginał, co daje końcowy wynik 65 bajtów :
$\=print!s;.;y/XVI60-9/CLXXI V/dfor$\.="37e$&"%97366;gefor 1..100
Metodologia
Zadano pytanie, w jaki sposób można znaleźć taką formułę. Ogólnie rzecz biorąc, znalezienie magicznej formuły uogólniającej dowolny zestaw danych jest kwestią prawdopodobieństwa. Oznacza to, że chcesz wybrać formę, która najprawdopodobniej da coś podobnego do pożądanego rezultatu.
Sprawdzanie pierwszych kilku cyfr rzymskich:
0:
1: I
2: II
3: III
4: IV
5: V
6: VI
7: VII
8: VIII
9: IX
należy zauważyć pewną prawidłowość. W szczególności, od 0-3, a następnie ponownie od 5-8 , każdy kolejny element zwiększa długość o jedną cyfrę. Gdybyśmy chcieli utworzyć odwzorowanie z cyfr na cyfry, chcielibyśmy mieć wyrażenie, które również zwiększa długość o jedną cyfrę dla każdego kolejnego terminu. Logicznym wyborem jest k • 10 d, gdzie d jest odpowiednią cyfrą, a k jest dowolną stałą całkowitą.
Działa to dla 0-3 , ale 4 musi przerwać wzór. Możemy tutaj zastosować hals na module:
k • 10 d % m , gdzie m jest gdzieś pomiędzy k • 10 3 i k • 10 4 . Spowoduje to pozostawienie zakresu 0-3 nietkniętego i zmodyfikuje 4 tak, aby nie zawierał czterech Is. Jeśli dodatkowo ograniczymy nasz algorytm wyszukiwania tak, że reszta modułowa 5 , nazwijmy to j , jest mniejsza niż m / 1000 , zapewni to, że również będziemy mieć regularność od 5-8 . Rezultat jest mniej więcej taki:
0: k
1: k0
2: k00
3: k000
4: ????
5: j
6: j0
7: j00
8: j000
9: ????
Jak widać, jeśli zastąpimy 0z I, 0-3 i 5-8 są gwarantowane być odwzorowane prawidłowo! Wartości 4 i 9 muszą być jednak brutalnie wymuszone. W szczególności 4 musi zawierać jeden 0i jeden j(w tej kolejności), a 9 musi zawierać jeden 0, a następnie kolejną cyfrę, która nie pojawia się nigdzie indziej. Z pewnością istnieje wiele innych formuł, które przez pewien przypadek mogą przynieść pożądany rezultat. Niektóre z nich mogą być nawet krótsze. Ale nie sądzę, aby były takie, które odniosą tak duży sukces jak ten.
Eksperymentowałem również z wieloma zamiennikami Ii / lub Vz pewnym sukcesem. Ale niestety, nie mniej niż to, co już miałem. Oto lista najkrótszych rozwiązań, jakie znalazłem (liczba rozwiązań o 1-2 bajty większa jest za duża, aby je wymienić):
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