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$&"%72726
przekształ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 012
zamiast 016
upraszcza /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 XVI
s CLX
w 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-2
podstawienia 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 print
wydaniu 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 3
w żadnej z cyfr. Dlatego powinno być możliwe użycie $\=2+print
zamiast tego i zastąpienie wynikowej 3
spacją:
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 print
i for
.
Edycja : Można to poprawić o jeden bajt, przesuwając print
do 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 ge
i for
spowoduje wyświetlenie ostrzeżenia o wycofaniu, ale w innym przypadku jest poprawne.
Ale gdyby istniała formuła, która 1
nigdzie nie była używana , $\=2+print
staje się $\=print
warta 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 I
s. 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 0
z 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 0
i 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 I
i / lub V
z 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