„Schemat rymów” to ciąg liter a
do z
, dzięki czemu pierwsze wystąpienia znaków są w porządku rosnącym (bez przerw), zaczynając od a
. Na przykład (z zaznaczonymi pierwszymi wystąpieniami):
abccdbebdcfa
^^^ ^ ^ ^
Liczba schematów rymów długości N
jest podana przez liczby Bell B(N)
. ( OEIS A000110 )
Wyzwanie
Twoim zadaniem jest zaimplementowanie wyliczenia tych schematów rymów, tj. Bijective mapping od liczb całkowitych do schematów rymów. Otrzymujesz dodatnią liczbę całkowitą N <= 26
, a także nieujemną liczbę całkowitą 0 <= i < B(N)
. Alternatywnie możesz użyć zakresu 1 <= i <= B(N)
. Powinieneś wypisać schemat rymów długości N
, tak że każdy i
daje inny ciąg znaków.
Możesz napisać program lub funkcję, pobierając dane wejściowe przez STDIN (lub najbliższą alternatywę), argument wiersza poleceń lub argument funkcji i wypisując wynik przez STDOUT (lub najbliższą alternatywę), wartość zwracaną funkcji lub parametr funkcji (wyjściowej).
Możesz używać zarówno małych jak i wielkich liter (konsekwentnie).
Twój kod musi być w stanie obsłużyć każdy ważny wkład w rozsądnym czasie (np nie więcej niż kilka godzin za N = 26
, najgorszym przypadku i
). Powinno to pozwolić na rozwiązania skalowane wykładniczo za pomocą N
(dla małych zasad), nawet w wolnych językach, ale zabraniać rozwiązań skalowanych liniowo za pomocą i
(tj B(N)
.). W szczególności oznacza to, że nie możesz po prostu powtarzać wszystkich prawidłowych schematów rymów, N
dopóki nie odrzucisz i
schematów.
Obowiązują standardowe zasady gry w golfa .
Przykłady
Dokładne przypisanie i
do schematów (tj. Kolejność schematów dla danego N
) zależy od Ciebie. Ale powiedzmy, że wybrałeś porządek leksykograficzny, twoje rozwiązanie powinno odpowiadać poniższej tabeli (z -
oznaczeniem nieprawidłowych danych wejściowych):
N\i 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 a - - - - - - - - - - - - - -
2 aa ab - - - - - - - - - - - - -
3 aaa aab aba abb abc - - - - - - - - - -
4 aaaa aaab aaba aabb aabc abaa abab abac abba abbb abbc abca abcb abcc abcd
Oto krótki skrypt CJam, który generuje wszystkie prawidłowe schematy wierszy dla dowolnej długości (ale nie próbuj więcej niż 10, bo poczekaj chwilę).
Powiązane wyzwania
źródło
N
), pod warunkiem, że nie okaże się to dość trywialne i byłem po prostu zbyt głupi, aby go znaleźć.Odpowiedzi:
CJam,
6866 bajtówWypróbuj online.
To mój pierwszy program CJam. Zaczęło życie jako port mojego rozwiązania Perla i początkowo miało ponad 130 bajtów. Dalsze sugestie dotyczące gry w golfa są mile widziane.
Podobnie jak w moim programie Perl, składa się on z dwóch części.
Debugować tablic stworzonych przez Part 1 Dodaj
]_`o~
pomiędzy Parts 1 & 2. Jeżeli n jest5
, macierze będzie wyglądać następująco:[[1 1 1 1 1 1] [1 2 3 4 5] [2 5 10 17] [5 15 37] [15 52]]
. Wskaźniki 0 w każdej tablicy nie są używane, po prostu ułatwiają to, że nie trzeba obliczać przesunięć. Tablice są obliczane w następujący sposób:Przechowuje kopię starej tablicy podczas obliczania następnej. Tablice są odczytywane i odrzucane w odwrotnej kolejności przez część 2.
źródło
Python 2, 153
Wykorzystuje porządek alfabetyczny i indeksowanie oparte na 0.
Niech
l
oznacza długość sufiksu liter ia
liczbę różnych liter użytych w poprzedniej części. Następnie funkcja,p(l,a)
która oblicza liczbę sposobów wyboru pozostałych liter, może mieć 40 bajtów:Jest to jednak zbyt wolne dla wyzwania, więc zamiast tego niezbędne wartości są wstępnie obliczane i zapisywane w
u
tablicy. Na każdym etapie obliczeń, jeśli następną literą jesta
już używana litera , n = k * p (l - 1, a) + n ', gdzie k jest literą alfabetu o indeksie 0, a n' wynosi wartośćn
następnego wywołania funkcji, która zawiera informacje o pozostałych literach. Jeśli używana jest nowa litera, to n = a * p (l - 1, a) + n ' .źródło
Haskell (GHC 7.10), 150 bajtów
Operator
n # i
obliczai
schemat długości rymu th (indeksowany od zera)n
. Działa w operacjach O (n²) (big-integer), wykorzystując leniwe, nieskończone listy Haskella do automatycznego zapamiętywania. Przykładowe przebiegi:(Jeśli maksymalna N to 25 zamiast 26,
.fromEnum
można je usunąć, ponieważ B (25) mieści się w wersji 64-bitowejInt
).źródło
Perl 257 + 1 (flaga -p) = 258Perl 182 + 10 (flagi -pMbignum) = 192
Dzięki dev-nul za uratowanie wielu bajtów! Teraz przepisałem go na podstawie tego, czego nauczyłem się podczas tworzenia wersji CJam.
Oblicza rym w kolejności alfabetycznej, 0 indeksowane.
Dwie części: część 1 ma
12890 bajtów i oblicza macierz dla części 2. Część 2 ma12992 bajtów i wykonuje kilka prostych obliczeń matematycznych w celu obliczenia każdej litery.Gdybym mógł pozbyć się macierzy i zastąpić ją dwoma prostymi liczbami, mógłbym obliczyć jedną ścieżkę przez macierz dla każdej liczby i zaoszczędzić dużo bajtów!Najwyraźniej ten pomysł nie działa!Niestety nie wyświetla odpowiednich rymów dla wartościi
wyższych niż 9007199254740992, ale działa pięknie dla niskich wartości!Dodałem bibliotekę Bignum kosztem 11 bajtów.Jest uruchamiany z wiersza poleceń za pomocąperl -pMbignum bell-rhyme.pl
.-pMbignum
= 10 bajtów. Jest również bardzo szybki dla każdej wartości wejściowej.źródło
Oracle SQL 11.2,
412284283 bajtówNiestety osiąga długość do 8. Każda większa wartość powoduje: ORA-01489: wynik konkatenacji łańcucha jest zbyt długi
Nie grał w golfa
Widok generuje: i litery w kolumnie a i ich wartość w b.
Widok rekurencyjny v przyjmuje ciąg budowany jako parametr v, wartość ostatniej litery użytej w c oraz wartość największej litery użytej w n. Parametr n jest równy długości łańcucha bez zduplikowanej litery, to jest to, dla czego służy wyrażenie regularne.
Litera jest ważna, jeśli jej wartość wynosi <= wartość największej już użytej litery lub jest to kolejna litera, która zostanie użyta.
Jakoś kwerenda potrzebuje części LENGTH (s) <: n do uruchomienia, brakuje mi czegoś w sposobie działania kwerendy.
Główny WYBÓR zajmuje się odfiltrowaniem nieprawidłowych danych wejściowych i krótszych ciągów znaków zbudowanych przed osiągnięciem docelowej długości.
Wersja 412 bajtów
Nie próbuj kwerendy 412 bajtów z 26. To przełącza bazę danych w tryb zastrzeżony, przynajmniej w mojej wersji xe działającej w kontenerze dokera na Macbooku. Mógłbym przymierzyć exadata w pracy, ale niestety nadal muszę zarabiać na życie.
źródło
Mathematica, 136 bajtów
Dla kompletności, oto moja referencyjna implementacja gry w golfa. W przeciwieństwie do istniejących odpowiedzi, nie działa to w czasie wielomianowym (jest wykładniczy w
N
przypadku podstawy 2), ale spełnia ograniczenie czasowe (najgorszy przypadek trwałby jeszcze za pół godziny).Chodzi o to:
Dla każdego schematu rymów możemy zidentyfikować pozycje, w których zwiększa się jak dotąd maksymalny znak:
Możemy traktować te oznaczenia jako liczbę binarną, co ułatwia iterację wszystkich takich struktur. Musimy iterować od 2 n-1 do 2 n (lub na odwrót), skąd pochodzi wykładnicza złożoność czasu.
i
, odejmujemy jąi
. W przeciwnym razie znaleźliśmy strukturę żądanego schematu wierszyków.i
(lub to, co z niej pozostanie) jako liczbę o mieszanej podstawie, gdzie wagi cyfr są określone przez liczbę dozwolonych znaków na pozostałych pozycjach.Zastanawiam się, czy pozwoliłoby to na krótsze rozwiązanie w niektórych innych przesłanych językach, ponieważ nie wymaga to żadnej zapamiętywania ani wstępnego obliczenia.
źródło