Opis wyzwania
Mieliśmy kilka wyzwań związanych z sekwencją Look-and-say . Szybkie przypomnienie:
- Sekwencja zaczyna się
1
, - Kolejne warunki tej sekwencji są generowane przez wyliczenie każdej grupy powtarzających się cyfr z poprzedniego terminu,
Tak więc pierwsze kilka warunków to:
1 "one"
11 "one one" (we look at the previous term)
21 "two ones"
1211 "one two, one one"
111221 "one one, one two, two ones"
312211 "three ones, two twos, one one"
Teraz zróbmy to samo, ale zamiast tego użyj cyfr rzymskich . Zaczynamy odI
i przestrzegamy tych samych zasad (zamiast tego stosujemy zasadę liczenia cyfr do znaków, więc czytamy IVX
jako one one, one five, one ten
zamiast one four, one ten
lub w inny sposób):
I "one"
II "one one"
III "two ones" = "II" + "I"
IIII "three ones" = "III" + "I"
IVI "four ones" = "IV" + "I"
IIIVII "one one, one five, one one"
IIIIIVIII "three ones, one five, two ones" = ("III" + "I") + ("I" + "V") + ("II" + "I")
Biorąc pod uwagę dodatnią liczbę całkowitą N
:
- Wypisz pierwsze
N
cyfry tej sekwencji (jakikolwiek rozsądny separator również jest w porządku["I", "II", "III", ...]
- Wyjściowy
N
element tej sekwencji (może być indeksowany 0).
Pamiętaj, aby twój kod był jak najkrótszy, ponieważ jest to wyzwanie dla golfa !
EDYCJA: Uważam, że zawsze istnieje jeden standardowy / preferowany sposób wyrażania liczb całkowitych jako cyfr rzymskich (jak 95
-> XCV
zamiastVC
). Kilka konwerterów cyfr rzymskich, które znalazłem w Internecie, potwierdza moje zdanie. W razie wątpliwości skorzystaj z konwertera online , ponieważ wyszczególnienie wszystkich możliwych przypadków brzegowych i szczegółowych zasad pisania cyfr rzymskich nie jest celem tego wyzwania.
EDIT2: @PeterTaylor i @GregMartin wskazał, że tylko liczby mniejsze lub równe 5
są wyświetlane w kolejności, więc nie trzeba się martwić o dwuznaczności cyframi rzymskimi (numery 1
- 8
są I
, II
, III
, IV
, V
, VI
, VII
, i VIII
)
źródło
4
/IV
/IIII
? Lub95
/XCV
/VC
? Nie zawsze może istnieć wyjątkowy sposób wyrażenia liczby całkowitej, ale jestem pewien, że zawsze jest preferowany (standardowy) - popraw mnie, jeśli się mylę.Odpowiedzi:
Perl, 49 bajtów
Obejmuje +1 dla
-p
Uruchom z indeksem 0 na STDIN, np
ecce.pl
:Magiczne formuły są takie magiczne.
Normalnie użyłbym,
($_=//)x$'
aby kontrola pętli była o jeden bajt krótsza, ale ocena na tej stronie daje handicap 2, więc kończy się o 1 bajt dłużej. Na starszych perlach możesz wcześniej upuścić przestrzeńfor
. Niektóre wersje Perla zmuszają cię do dodania finału;
aby zamknąć transliterację. Ale to, co podano powyżej, to kod, który działa w moim systemie.Wyjaśnienie
Praca wstecz od rozwiązania do kodu:
Potrzebne nam transformacje ciągów:
Każda zamiana kończy się powtarzającym się znakiem. Otrzymam sekwencję tych samych znaków za pomocą wyrażenia regularnego
/(.)\1*/
, więc można to zrobić przez dołączenie$1
. Część przed->
jest w$&
. Z tym nadal potrzebuję:Napisz
I
jako1
iV
jako 9:Dzieląc poprzednią część
->
przez powtarzającą się cyfrę, staje się to:Więc teraz powtórzony oryginał
V
nie jest już wyjątkiem. Chcę więc wyrażenie, które sprawi, że tak się stanie:Można to zrobić za pomocą prostego modułu 182:
(to jeszcze dostaje
IIIIII
się doVI
prawa, choć nie jest potrzebne tutaj)Pozostaje tylko zainicjowanie zmiennej roboczej
1
dla indeksu 0, powtórzenie transformacji w pętli, a na końcu zastąpienie1
przezI
i9
przezV
1
,9
I182
jest to jedyny parametr kombinacja dla których ten proste prace formule.źródło
Mathematica,
1139083 bajtówPodziękowania dla Martina Endera za sugestie, które zmniejszyły długość o ponad 25%!
Pochwalanie się poleceniami wysokiego poziomu w Mathematica.
Czysta funkcja, przyjmująca argument N i wysyłająca N-ty element tej (0-indeksowanej) sekwencji, jako listę znaków. Rozłóż się trochę:
Zewnętrzne
Nest
iteruje środkową funkcję czteroliniową, zaczynając od{"I"}
N razy. Wiersz 4 dzieli listę znaków wejściowej cyfry rzymskiej na serie podobnych znaków, zlicza każdą serię za pomocąTally
i umieszcza liczby przed znakami, które liczą. Wiersz 3 renderuje liczby jako cyfry rzymskie, a następnie dzieli te cyfry rzymskie na listy znaków. TheFlatten
Polecenie zmniejsza całej listy-of-listy do listy jednowymiarowa.Oto początkowa wersja:
źródło
@@@
zamiast/@
możesz użyć#
i#2
zamiast#[[1]]
i#[[2]]
. Ponadto listy znaków są akceptowalnymi typami ciągów, dzięki czemu można z nimi pracować i unikać ich używaniaCharacters@
.@@@
skrót podobny do tego! Jeśli chodzi o listy znaków będących akceptowalnymi typami ciągów (które, jak się zgadzam, skróciłyby kod): czy jest post na tej stronie, na który możesz wskazać mi opisujące standardy społeczności?Characters
wątki automatycznie, abyś mógł ich użyć@
,Reverse@#&
jest oczywiście taki sam jak zwykłyReverse
, w którym to przypadku również nie potrzebujesz tych nawiasów. Notacja przedrostka (w przypadkuFlatten
) niczego nie zapisuje, jeśli musisz dodać nawiasy, aby działała. Łącząc wszystkie:Nest[Flatten[Characters@{RomanNumeral@#,#2}&@@@Reverse@@@Tally/@Split@#]&,{"I"},#]&
CJam (
3330 bajtów)Demo online
Kluczem do poprawności wdrożenia jest następujące twierdzenie:
Jeśli pierwsza generacja to
I
, żadna długość serii nie jest większa niż pięćLemat: jeśli jest to pierwsza generacja
I
, żaden ciąg nie zawieraVVV
. Dowodem jest sprzeczność. Załóżmy, że istnieje pierwszy indeks,n
dla któregon
zawiera th generacjaVVV
. Jeśli to sięVVV
psuje,(a)V VV
to konwersja z poprzedniej generacji jest zła: tak powinno być(a+5)V
. Tak musi byćVV V(d)
, a poprzednie pokolenie zawierałoVVVVV
, co stoi w sprzeczności z wyboremn
.Załóżmy teraz, że istnieje pierwszy indeks,
m
dla któregom
zawiera th generacja...IIIIII...
. Pamiętaj, że nie może być innych cyfr niżI
iV
w ciągu, ponieważ żadna poprzednia generacja miała serię dziewięciuI
s lub dziewięćV
sekund. Co najwyżej czteryI
s pochodzą z seriiI
s poprzedniego łańcucha, więc odpowiednia sekcja poprzedniego łańcucha musi...IIIVV...
dawać... IIII IIV ...
. PonieważVV
generacjam-1
nie pochodziVVVVV
(patrz lemat), drugaV
musi być ciągiem cyfrI
, więc w generacjim-1
mamy...IIIVVI...
. A ponieważ chcemy, aby początkoweI
s dawałyIIII
a nieIVI
lubVI
, jest poprzedzony albo początkiem ciągu, albo znakiemV
.Jeśli mamy
(...V)?IIIVVI...
z pokoleniemm-1
, co mamy z pokoleniemm-2
? Zauważyliśmy już, żeVV
gen.m-1
należy przeanalizować jako(a)V V(I)
.Załóżmy, że weźmiemy
a=2
:(...V)?I IIV VI...
Właściwie to musi być...VI IIV VI...
, chociaż to prowadzenieV
może być częściąIV
; tak w poprzedniej generacji mamy albo(...V)? IIII VV IIIII...
albo(...V)? IIIII VV IIIII
. Tak czy inaczej, mamy z tym problemVVIIIII
: drugiV
musi być ciągiem, ale następnie...VI IIII...
wymaga następnej pary (ciąg, cyfra) z tą samą cyfrą.Więc to musi być
a=1
:(...V)?II IV VI...
. Ponieważ pokoleniem
jest pierwszym z sześciu runI
s, który musi być(...V)? II IV VI...
tak, że pokoleniem-2
to(...V)? I V IIIII...
....VIVIIIII...
jest niemożliwe: jednak zdecydujemy się zinterpretować sekundę, w wynikuV
czego otrzymamy dwie kolejne pary (długość, cyfra) o tej samej cyfrze.Dlatego generacja
m-2
musi być^IVIIIII...
parsowana jako^IV IIII I(V)...
lub^IV III II(V)...
. Dają one odpowiednio generacjęm-3
jako^V III V ...
lub^V II VV...
.Ale jeśli spojrzymy na początek ciągów zaczynających się od pierwszego, który zaczyna się od
V
, otrzymujemy cykl:i tak nie zawsze zaczyna się generacja albo
VIIIV
alboVIIVV
. Musimy stwierdzić, że takich nie mam
.Sekcja
źródło
Python 3, 195 bajtów
Na cyfrach rzymskich marnowanych jest wiele bajtów, więc prawdopodobnie trzeba tam zagrać w golfa.
Dzięki @ El'endiaStarman, @ Sherlock9 i @Shooqie
Ideone to!
źródło
for v,i in(5,"V"),(4,"IV"),(1,"I")
for v,i in(5,"V"),(4,"IV"),(1,"I"):a,x=divmod(x,v);r+=i*a
zapisuje bajt.i
(jak wfor i in range(...)
). Próbowałem się bawić,exec
ale ta1
metoda ucieczki w metodzie „pod” wydaje się zepsuć kod, nie udało mi się znaleźć obejścia.range
R,
110107 bajtówas.roman
w połączeniu zrle
ułatwia to. Wykrywanie nadużyć i wbudowane zachowanie kota<<-
oszczędza kilka bajtów.Pobiera N z konsoli. Wyprowadza pierwsze 2 do N warunki sekwencji (które moim zdaniem mieszczą się w specyfikacji ...)
źródło
JavaScript (ES6), 107
Funkcja rekurencyjna zwracająca N-ty termin na podstawie 0
Test
źródło
Perl 6 , 62 bajtów
Anonimowa funkcja akceptująca indeks zerowy.
Wykorzystuje fakt, że liczby rzymskie wyższe niż 5 nie są potrzebne, ponieważ jedynymi grupami powtarzających się cyfr, które mogą wystąpić, są:
( spróbuj online )
źródło