Napisz program liczący od 1 do 100 cyframi rzymskimi i wydrukuj te liczby na standardowym wyjściu. Każda z liczb musi być oddzielona spacjami.
Nie można użyć żadnej wbudowanej funkcji do przekształcenia na cyfry rzymskie ani zewnętrznej aplikacji lub biblioteki.
Pożądanym rezultatem jest
I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII XXXIX XL XLI XLII XLIII XLIV XLV XLVI XLVII XLVIII XLIX L LI LII LIII LIV LV LVI LVII LVIII LIX LX LXI LXII LXIII LXIV LXV LXVI LXVII LXVIII LXIX LXX LXXI LXXII LXXIII LXXIV LXXV LXXVI LXXVII LXXVIII LXXIX LXXX LXXXI LXXXII LXXXIII LXXXIV LXXXV LXXXVI LXXXVII LXXXVIII LXXXIX XC XCI XCII XCIII XCIV XCV XCVI XCVII XCVIII XCIX C
Ponieważ jest to wyzwanie dla golfa, wygrywa najkrótszy kod .
Odpowiedzi:
Perl 69 bajtów
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łada012
zamiast016
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
sCLX
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:
Ten używa
0-2
podstawieniaIXV
, ale ma moduł dłuższy o jedną cyfrę.Aktualizacja:
6665 bajtówTa 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
$\
. Poprint
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ę: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 liczby3
w żadnej z cyfr. Dlatego powinno być możliwe użycie$\=2+print
zamiast tego i zastąpienie wynikowej3
spacją:Również 67 bajtów, ze względu na niezbędną spację między
print
ifor
.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 :
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:
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:Jak widać, jeśli zastąpimy
0
zI
, 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ć jeden0
i jedenj
(w tej kolejności), a 9 musi zawierać jeden0
, 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 / lubV
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ć):źródło
HTML + JavaScript + CSS (137)
HTML (9)
JavaScript (101)
CSS (27)
Wydajność
...
Demo na JSBin
źródło
document.write('<ol>'+"<li style='list-style:upper-roman'/>".repeat(100)+'</ol>')
(ES6)document.write("<li style='list-style:upper-roman'/>".repeat(100))
Python 116
lepszy golfowy kod odpowiedzi scleavera:
źródło
Python, 139
źródło
C,
177160147 znakówIstnieją krótsze rozwiązania, ale żadne w C, więc oto moja próba.
Nowe rozwiązanie, zupełnie inne od mojego poprzedniego:
Poprzednie rozwiązanie (160 znaków):
Logika:
1.
f
wypisuje liczbę od 1 do 10.c
użyte cyfry, które mogą byćIVX
lubXLC
. Raz nazywany dziesiątkami raz.2. Jeśli
n%5==0
- nic nie drukuj lubc[n/5]
który jestI
lubV
(lubL
lubC
).3. Jeśli
n%4==4
-4
lub9
- wydrukujI
(lubX
), przezn+1
.4. Jeśli
n>4
- wydrukuj5
(tj.V
LubL
), ton-5
.5. Jeśli
n<4
- wydrukujI
wtedyn-1
(tj.n
RazyI
).źródło
f(c,n){printf("%.*s",n%5>3?2:n%5+n/5,"XLXXXCIVIIIX "+c+(n%5>3?n%4*4:2-n/5));}main(i){for(;i<100;f(12,4))f(0,i/10),f(6,i++%10);puts("C");}
JavaScript, 123
Zainspirowany dłuższą wersją natknąłem się na polską grupę dyskusyjną (przynajmniej Chrome myślał, że to polska).
źródło
Q (
8180)2. cięcie:
1. cięcie:
źródło
Python, 168
Wyjaśnienie
Korzystając z tych wartości, weź największą wartość nie większą niż n i odejmij ją od n. Powtarzaj, aż n wynosi 0.
źródło
r=lambda n,l,v:n and(n<v[0]and r(n,l[1:],v[1:])or l[0]+r(n-v[0],l,v))or""
zapisuje dwie postacie. W przeciwnym razie bardzo miło.Ruby 1.9,
140132To dosłownie liczy się od 1 do 100 cyframi rzymskimi. Zaczyna się od pustego ciągu, a następnie wykonuje pętlę przez dopisywanie „I”, a następnie wielokrotnie stosuje serię reguł podstawiania, skutecznie dodając 1.
Edycja: Dodano numer wersji, ponieważ
?I
działa tylko w wersji 1.9, i wykorzystał zmiany @ Howarda do przycięcia niektórych postaci.źródło
r while
->0while
,r.sub!(*q)
->r.sub! *q
. Możesz także przeciągnąć wydruk w pętli i użyć100.times{...}
zamiast instrukcji map.(%w[IIII VIV XXXX LXL]<</(.)((?!\1)[^I])\1/).zip(%w(IV IX XL XC)<<'\2')
zapisuje 7 znaków.Ruby 112 znaków
Zasadniczo za pomocą
to_roman
metody opisanej tutaj , ale za pomocą zwięzłej tablicy dla zwięzłości.źródło
Mathematica
159 150142Wbudowany w roztworze :
IntegerString
38 znakówźródło
perl 205
Gra w golfa:
źródło
MUMPS 184
Ten sam algorytm jak @ cardboard_box, od którego wziąłem wyjaśnienie dosłownie -
Wyjaśnienie
Korzystając z tych wartości, weź największą wartość nie większą niż n i odejmij ją od n. Powtarzaj, aż n wynosi 0.
źródło
R , 85 bajtów
Wypróbuj online!
Używa losowej
utils
zmiennej pakietowej,.romans
aby uzyskać wartości liczb rzymskich, ale sama dokonuje konwersji; wbudowane podejście miałoby 20 bajtów:cat(as.roman(1:100))
źródło
cat(paste(as.roman(1:100)))
lub po prostuas.roman(1:100)
. Dziwne.cat
wskazują, że wykonuje mniejszą konwersjęprint
i działa tylko naatomic
wektorach - więc to wyjaśnia!APL 128
Próbowałem rozwiązania indeksowania w APL:
Może być o 4 bajty krótszy na początku indeksu 0 zamiast 1, ale prawdziwym kosmicznym świnią jest generowanie macierzy indeksów poprzez:
Jak dotąd nie byłem w stanie generować wskaźników w locie!
źródło
LaTeX (138)
źródło
Python, 125
źródło
PHP,
3837 bajtów<ol type=I><?=str_repeat("<li>",100);
-1 bajt dzięki @manatwork
Ten sam pomysł, co odpowiedź Patryka , ale w bardziej zwartym języku. Bije Mathematica !
Wypróbuj online!
źródło
;
, a następnie nie ma potrzeby?>
.VBA (Excel), 245 bajtów
utworzono funkcję powtarzania i zamiany - 91 bajtów
Function s(a,b):s=String(a,b):End Function Function b(x,y,z):b=Replace(x,y,z):End Function
za pomocą bezpośredniego okna ( 154 bajtów )
p="I":for x=1to 100:?b(b(b(b(b(b(b(b(s(x,p),s(100,p),"C"),s(90,p),"XC"),s(50,p),"L"),s(40,p),"XL"),s(10,p),"X"),s(9,p),"IX"),s(5,p),"V"),s(4,p),"IV"):next
źródło
Java (OpenJDK 8) , 152 bajty
Wypróbuj online!
Wyjaśnienie:
źródło
TeX, 354 bajty
Kilka wyjaśnień: TeX zapewnia wbudowane polecenie
\romannumeral
do konwersji liczb na cyfry rzymskie. Ponieważ pytanie nie pozwala na użycie wbudowanych funkcji, powyższy kod jest golfową wersją tego samego algorytmu, z którego korzysta oryginalny kompilator TeXa Knutha\romannumeral
(patrz TeX: Program , § 69print_roman_int
) ponownie zaimplementowany w TeX.Ponieważ chce pozostawić czytelnikowi radość z zastanawiania się, jak ten kod działa, Knuth odmawia wyjaśnienia tej części kodu. Więc pójdę za tym i dam po prostu nie zmienioną i nieco zmodyfikowaną wersję, która jest bliższa oryginałowi niż powyższy kod:
źródło