Biorąc pod uwagę ściśle dodatnią liczbę całkowitą, zwróć możliwie najkrótszą liczbę rzymską, używając tylko reguły addytywnej. Dane wyjściowe muszą składać się z zera lub więcej z każdego ze znaków MDCLXVI
w tej kolejności. Dlatego liczba 14
musi być podana XIIII
zamiast XIV
.
Wartości liczbowe znaków to M
= 1000, D
= 500, C
= 100, L
= 50, X
= 10, V
= 5, I
= 1.
Przykłady
3
→ III
4
→ IIII
9
→ VIIII
42
→ XXXXII
796
→ DCCLXXXXVI
2017
→ MMXVII
16807
→ MMMMMMMMMMMMMMMMDCCCVII
4 -> IIII
jest9 -> VIIII
również zamiastIX
?VIIII
jest jedynym dozwolonym wyjściem dla 9.Odpowiedzi:
Zwykły angielski ,
10591025678641451399 bajtówZapisano 34 bajty, usuwając pułapkę błędów. Następnie zaoszczędzono 384 bajty, grając w golfa. Następnie zapisano 190 bajtów, łącząc operację dzielenia z operacją dołączania („z”) w nowej operacji („p”). Następnie zaoszczędzono 52 bajty, grając w golfa.
Oto niezakończona wersja ostatecznego kodu plus pułapka błędu dla liczby ujemnej:
źródło
APL (Dyalog) ,
2522 bajtówWypróbuj online!
źródło
/
) zamiast reshape (⍴
), dzięki czemu możesz wyciąć każdy z nich i redukcję catenate (¨
i,/
).⎕
) i użyć commute (⍨
), aby usunąć parens i compose (∘
).{}
∇f∇
Siatkówka oka ,
5742 bajtówPrzekształca się w jednoargumentowy, a następnie łapczywie zastępuje wiązki
I
sz wyższymi nominałami w kolejności.Wypróbuj online
Zaoszczędź 15 bajtów dzięki Martinowi
źródło
I
jednostki?Python 2 , 64 bajty
Wypróbuj online!
Zamiast tworzyć ciąg wyjściowy od początku, łapczywie biorąc największą część, tworzy go od końca. Na przykład liczba
I
jestn%5
, następnie liczbaV
jestn/5%2
itd. Jest to konwersja mieszanej zasady z kolejnymi stosunkami naprzemiennie 5 i 2.Oto iteracyjny odpowiednik:
Python 2 , 68 bajtów
Wypróbuj online!
The
M
„S muszą być traktowane oddzielnie, ponieważ każda liczba z nich może być obecny jako że nie ma większych cyfr. Zatem po przypisaniu innych wartości miejsca, pozostała wartość jest konwertowana naM
's.Dla porównania chciwa strategia (69 bajtów):
Python 2 , 69 bajtów
Wypróbuj online!
Bieżąca wartość cyfry
d
jest dzielona przez 2 lub 5, aby utworzyć następną cyfrę. Wartośćd%3
powiedz nam, który: jeślid%3==1
, podziel przez2
; a jeślid%3==2
podziel przez 5.źródło
Mathematica, 81 bajtów
Jawne użycie wartości i wyprowadzenie odpowiednich cyfr wydaje się dłuższe o jeden bajt:
źródło
FromRomanNumeral@r
Excel,
236193161 bajtów43 bajty zapisane dzięki @ BradCW tym momencie odpowiedź naprawdę należy całkowicie do @ BradC . Zapisano kolejne 32 bajty.
Sformatowany:
źródło
CONCATENATE
z&
pomiędzy poszczególnymi elementami iQUOTIENT
zINT(A/B)
.REPT
że liczba jest już obcięta, jeśli nie jest liczbą całkowitą , dzięki czemu możesz zaoszczędzić 30 bajtów, usuwając każdy z nichINT()
. Zapisz 2 więcej zastępując zarówno1000
z1E3
(choć Excel nie wydają się chce utrzymać to w ten sposób raz trafisz enter).1E3
zachowanie. Odpowiedź zaktualizowana.Perl 5 , 66 bajtów
65 bajtów kodu +
-p
flaga.Wypróbuj online!
Bez zmiany liczby bajtów
MDCLXVI=~/./g
można go zastąpićM,D,C,L,X,V,I
; i--$|?2:5
przez$|--*3+2
.Znacznie dłużej ( 99 bajtów ) jest:
źródło
CJam ,
3528 bajtów-7 bajtów dzięki Martinowi Enderowi
Wypróbuj online!
Wyjaśnienie
źródło
C #, 127 bajtów
Oświadczenie potrójnie czysto zakodowane przy użyciu rekurencji.
Wersja pełna / sformatowana:
źródło
n>0
jest po prostun
.int
nie można niejawnie rzutować na abool
.05AB1E ,
292625 bajtówWypróbuj online!
Wyjaśnienie
źródło
JavaScript (ES6),
817569 bajtówZaoszczędź 6 bajtów dzięki @Neil za przeniesienie odpowiedzi @ Jörga Hülsermanna
Zaoszczędź 6 bajtów dzięki @Shaggy
Przypadki testowe:
Pokaż fragment kodu
źródło
n%=x
wewnątrzrepeat
metody, aby zapisać kilka bajtów.n=>'MDCLXVI'.replace(/./g,(c,i)=>c.repeat(n/a,n%=a,a/=i%2?5:2),a=1e3)
/// , 50 bajtów
Wypróbuj online!
Pobiera dane wejściowe jednoargumentowe, a ja (ab) używam pola stopki na TIO do wprowadzania danych, więc dane wyjściowe poprzedzone są nową linią.
źródło
Python 3 ,
100 97 96 94 93 9190 bajtówdef
; tablica jako parametr domyślny zmniejszyła przestrzeń wcięcia; usunięto niechcianą deklarację zmienneja%=
skrót(a//i)
usunięto nawiasy klamrowe[]
kosztem jednego miejsca wcięcia, oszczędzając w ten sposób 1 bajt.Wypróbuj online!
źródło
a%=i
jest bajt krótszy :)b
jako zmienną w funkcji. To eliminuje konieczność stosowania nawiasów -b=1000,500,100,50,10,5,1
Cubix , 69
7480bajtówWypróbuj online!
Watch It Running
Udało mi się to jeszcze bardziej skompresować, ale nadal jest trochę przykrych, bezużytecznych, szczególnie na górnej twarzy.
52"IVXLCDM"U
umieść na stosie niezbędne dzielniki i postacie. 5 i 2 zostaną wykorzystane do zmniejszenia wartości div / mod, a znaki zostaną odrzucone po użyciu.UIN0/&0\&,/U
U odwraca się do górnej powierzchni i rozpoczyna długą trasę, aby zdobyć dane wejściowe i wcisnąć 1000 na stos. Dokonuje się początkowego podziału i zawraca sięr
do następnego fragmentu kodu. To był obszar, na którym szukałem oszczędności.,r%ws;rr
początek pętli divmod. dzielenie liczb całkowitych, obracaj mod wyniku, a następnie zmieniaj kolejność stosu, aby zmniejszyć wejście, dzielnik prądu i podzielić wynik.3tus
przenieś obecną postać na górę i zamień ją wynikiem podziału.!vsoUs(0;U
to jest pętla drukowania. podczas gdy wynik div jest większy niż 0, zamień z wyjściem postaci, zamień z powrotem, zmniejsz, wypchnij 0 i upuść. Na 0 przekieruj na stos pop (usuń wynik podziału) i wokół kostki.\u;pwpsq,!@Urq;u
z odrobiną przekierowania usuwa to postać ze stosu, przenosi 5 i 2 na szczyt, zamienia je i spycha z powrotem w dół. Pozostałe służą do zmniejszenia dzielnika. Zatrzymaj, jeśli zmniejszy się do 0, w przeciwnym razie przesuń 5 lub 2 na dół i ponownie wejdź w pętlę.źródło
Mathematica, 130 bajtów
źródło
Python 2 ,
10990 bajtówWypróbuj online!
źródło
1000
może być1e3
(jeśli nie masz nic przeciwko temu, że jest to float, co nie powinno stanowić problemu)float
i nie można pomnożyć ciągu przez liczbę zmiennoprzecinkową: cPHP , 70 bajtów
Wypróbuj online!
źródło
T-SQL, 164 bajty
Dodano podział wiersza tylko w celu odczytu.
Ta wersja jest znacznie dłuższa (230 znaków), ale wydaje się bardziej „podobna do SQL”:
Tworzy tabelę m ze wszystkimi odwzorowaniami wartości char, a następnie wykonuje pętle, wyszukując największą wartość <= liczbę, łącząc pasujący znak.
źródło
Japt , 34 bajty
Przetestuj online!
źródło
JavaScript (ES6), 65 bajtów
Funkcja rekurencyjna.
W jaki sposób?
Drugie rekurencyjne połączenie
f(n-a)
naprawdę powinno byćf(n-a,a)
. Pominięcie drugiego parametrua
ii
ponowne zainicjowanie (odpowiednio do 1000 i 0) za każdym razem, gdy do wyniku końcowego dołączana jest nowa cyfra rzymska. Powoduje to większą rekurencję niż jest to konieczne, ale nie zmienia wyniku funkcji i oszczędza 2 bajty.Przypadki testowe
Pokaż fragment kodu
źródło
J ,
2623 bajtów3 bajty zapisane dzięki Adámowi.
Wypróbuj online!
Podobnie do odpowiedzi APL wzasadzie to samo.źródło
#.inv
zamiast#:
?#.inv
instead of#:
, since something like2 #: 4
is0
, whilst2 #.inv 4
is1 0 0
#
is/
;~
is⍨
;$
is⍴
;&
is∘
;#:
is⊤
. The only difference is that you use infinity_
while you could use0
like the APL answer.Batch, 164 bytes
Takes input on STDIN.
źródło
Oracle SQL, 456 bytes
Outputs:
Please note the actual size of the line is 460bytes, because it includes the input number (2849).
Ungolfed:
How it works: I calculate how many of each letter I need, by calculating the most I can get to with the higher value one (infinity for M), and then doing an integer division between the current letter's value and the result of that.
E.g. 2348, how many
C
s do I need?trunc((2348-mod(2348,500))/100)
= 3.Then, I
listagg
that letter together 3 times (exploitingCONNECT BY
to generate the 3 rows I need). Finally, Ilistagg
everything together.Kinda bulky, but most of it is the
select from dual
s in the conversion table and I can't really do much about that...źródło
Java (OpenJDK 8),
119118 bytesTry it online!
Saved a byte thanks to @TheLethalCoder
źródło
v
andi
in the first for loop to save a byte?Charcoal,
61 5046 bytesTry it online!
Explanation:
źródło
Nν
is one byte shorter thanANν
,¬‹
is one byte shorter than subtracting 1, and if you use÷
(IntDivide) instead of∕
(Divide) then you can useφ
as the outer loop condition. However, I think you can get it down to 40 bytes by looping overMDCLXVI
directly instead.C++, 272 Bytes
źródło
C, 183 Bytes
Same algorithm as before, just using plain c arrays instead of an std::map, partially inspired by @xnor's answer and using a string to store the letters.
źródło
Common Lisp, 113 bytes
This is an anonymous function, returning the result as a string.
Ungolfed, with descriptive variable names and comments:
CL has built-in Roman numeral formatter. Sadly it doesn't work for numbers larger than 3999.
źródło
Charcoal, 34 bytes
Originally based on @CarlosAlego's answer. A port of @xnor's Python solution is also 34 bytes:
Edit: A port of @xnor's other Python solution turns out to be 33 bytes!
Try it online! Link is to verbose version of code. Note that I've used
⁺׳﹪φ³±¹
instead of⁻׳﹪φ³¦¹
because the deverbosifier is currently failing to insert the separator.źródło