Biorąc pod uwagę liczbę dodatnią n , wypisz wszystkie wyraźne multiplikatywne partycje nw dowolnym dogodnym formacie.
Mnożnikowa partycja n to zbiór liczb całkowitych, wszystkie większe niż jeden, tak że ich iloczynem jest n . Na przykład 20 ma następujące odrębne partycje multiplikatywne:
2 * 2 * 5
2 * 10
4 * 5
20
Kolejność nie ma znaczenia, więc 2 * 2 * 5
ta sama partycja co 2 * 5 * 2
.
Przykłady:
1 -> {}
2 -> {2}
4 -> {2, 2}, {4}
20 -> {2, 2, 5}, {2, 10}, {4, 5}, {20}
84 -> {2, 2, 3, 7}, {2, 2, 21}, {2, 14, 3}, {2, 6, 7}, {2, 42}, {4, 3, 7}, {28, 3}, {4, 21}, {6, 14}, {12, 7}, {84}
Odpowiedzi:
Brachylog , 16 bajtów
Jest to funkcja (nie pełny program), która przyjmuje na wejściu liczbę dodatnią i generuje wszystkie jej multiplikatywne partycje. (Unikałem także używania jakichkolwiek wbudowanych faktoryzacji głównych w tym rozwiązaniu, głównie dlatego, że nie byłem pewien, czy one pomogą; w pewnym momencie mógłbym również wypróbować bardziej wbudowane rozwiązanie).
Wypróbuj online! (W tym miejscu wokół funkcji dodano dodatkowy kod, aby przekształcić go w pełny program; jeśli podasz funkcję pokazaną powyżej TIO bezpośrednio, uruchomi ona funkcję, ale nigdzie nie wydrukuje swoich wyników, co jest raczej bezużyteczne jako demonstracja .)
Ten program naprawdę mnie rozczarowuje, ponieważ w dużej mierze pracuje nad błędami interpretera Brachylog i brakami w specyfikacji, a nie w rzeczywistości rozwiązuje problem; ale tłumacz jest tym, czym jest. (Nawet przy takim programie interpreter zużywa znacznie więcej pamięci, niż to logicznie powinno, i ulega awarii z powodu wyczerpania pamięci, ale na szczęście przy małych problemach najpierw udaje mu się uzyskać pożądane wyjście.) W hipotetycznej „idealnej wersji Brachylog” możesz po prostu pisać
~*.o.:{>1}a,
, czyli o 4 bajty krócej, ale musiałem dodać dodatkowe ograniczenia, aby nieco pomóc tłumaczowi. (Nie bardzo lubię Brachylog i wolałbym trzymać się Prologa, ale potrzebowałem podobnych wskazówek, aby program działał i są o wiele dłużej pisać. Więc Brachylog to jest.)Wyjaśnienie:
Jak zwykle program Brachylog jest zbiorem ograniczeń; domyślnie pierwsze ograniczenie ogranicza dane wejściowe do nieznanego (które nazywam A ), drugie ograniczenie ogranicza A do drugiego nieznanego B i tak dalej, aż osiągniemy wynik. Niektóre znaki, takie jak
{}
, mogą zmieniać ten ogólny przepływ, więc używam innego zestawu liter (np. X / Y ) do reprezentowania nieznanych w zagnieżdżonych predykatach.Nadal nie jest jasne, jak działa program, więc spróbujmy nieco uprościć ograniczenia. C , D , G , H i I są takie same (i równe mocy wyjściowej). E i F są również takie same (i równe wejściowi). Nasze ograniczenia sprowadzają się do tego:
:{1<}a
potrzebuje lewego argumentu, aby mieć ograniczoną długość, inaczej interpreter przejdzie w nieskończoną pętlę).Nawiasem mówiąc, nie określiłem wyraźnie, że wszystkie elementy wyniku są liczbami całkowitymi, co może wydawać się wymagane; jednak narzędzie do rozwiązywania ograniczeń Brachylog nie jest w stanie obsłużyć liczb całkowitych, więc wygodnie wygeneruje tylko rozwiązania obejmujące liczby całkowite.
Oczywiście „długość danych wyjściowych jest mniejsza niż wartość wejściowa” będzie prawdą, ilekroć dane wyjściowe są multiplikatywną partycją danych wejściowych (ponieważ 2 x > x dla wszystkich nieujemnych x , tj. Dodatnia 2 x ). Możemy więc zignorować to ograniczenie; jest tylko po to, aby dać tłumaczowi Brachylog działającą strategię oceny programu. Inne ograniczenia (że dane wyjściowe są posortowane, że ich iloczyn jest danymi wejściowymi i że wszystkie jego elementy są większe niż 1) są definicją partycji multiplikatywnej, a zatem funkcja ta jest w zasadzie tylko bezpośrednią implementacją pytania.
źródło
Brachylog 1,14 bajtów
Wypróbuj online!
Brachylog 2,
1110 bajtów, wyzwanie dotyczące postdatacji językaWypróbuj online!
Maltysen odpowiedział na to pytanie w 17 bajtach Pytha, więc wymyśliłem 16-bajtowe rozwiązanie Brachylog, które działało, tłumacząc specyfikację pytania na Brachylog. Podczas gdy to robiłem, Dennis napisał 15-bajtowe rozwiązanie Jelly. Musiałem więc zejść do 14 bajtów. Jest to funkcja, która przyjmuje dane wejściowe jako argument i zwraca listę wszystkich partycji (zamiast generatora, jak w moim innym rozwiązaniu).
Jakiś czas po tym, jak napisałem tę odpowiedź, udało nam się wspólnie z Dennisem sprowadzić rozwiązanie Jelly do 11 bajtów. Okazuje się, że pojawiła się nowa wersja Brachylog ze składnią terser; odkłada wyzwanie na później, więc tak naprawdę się nie liczy, ale może zarządzać zbyt 11-bajtową sumą zaraz po wydaniu; późniejsze wersje języka (zainspirowane innymi wyzwaniami) mogą spaść nawet do 10, jak widać tutaj. Oba programy są identyczne, a jedyną różnicą jest składnia.
W przeciwieństwie do mojego innego rozwiązania, które nie wykorzystywało zbyt wiele „golfowych prymitywów”, ale raczej bezpośrednio określało problem, ten ignoruje prawie całą moc ograniczeń Brachylog i robi swoje najlepsze wrażenia galaretki, pisząc łańcuch ograniczeń, dla których lewy argument jest już znany (a zatem ograniczenia po prostu działają jak galaretowe monady, a nie w pełni). Dlatego używa tego samego algorytmu co rozwiązanie Pyth @ Maltysen, co jest prawdopodobnie najłatwiejszym sposobem rozwiązania tego problemu przy użyciu typowych prymitywów golfowych. (Co ciekawe, rozwiązanie „wystarczy podać problem” w mojej drugiej odpowiedzi byłoby krótsze, gdyby nie błędy / braki w interpretatorze Brachylog, pomimo braku użycia prymitywów golfowych. Pewnego dnia muszę napisać „ulepszony Brachylog” w celu znalezienia dobrego rozwiązania tego rodzaju problemu; w miarę gry w golfa Brachylog jest naprawdę bardzo gadatliwy.)
Program składa się z generatora i wokół niego otoki. Po pierwsze, oto wyjaśnienie generatora:
To prawie rozwiązuje problem, ale ostatecznie generujemy wiele partycji wiele razy. Potrzebujemy więc opakowania do deduplikacji rozwiązań:
źródło
Mathematica, 61 bajtów
Definiuje (rekurencyjny) jednoargumentowy operator,
±
który zwraca listę partycji.źródło
Pyth - 17 bajtów
Pobiera wszystkie permutacje pierwszej faktoryzacji, następnie partycjonuje każdą z nich, a następnie tworzy wszystkie partycje, a następnie zachowuje tylko odrębne partycje.
Pakiet testowy .
źródło
Python 2, 70 bajtów
Wyświetla listę posortowanych list. Na przykład
f(20)
jest[[2, 2, 5], [2, 10], [4, 5], [20]]
.źródło
O(n)
i w porównaniu do konkurenta w Pythonie 2 może być bardziejO(n^4)
stylowy - podczas gdy f (998) może zniszczyć pamięć lub sprzęt może umrzeć w trakcie uruchamiania czas około 80 dni z drugim algorytmem, ten tutaj zbiega się po ok. 7 milisekund na mojej maszynie, aby uzyskać wynik[[2, 499], [998]]
. IMO problem może być bardziej że dla zatrzymuje powyższy kod Python 3 ... szczęśliwy golfa :-)N > 998
RecursionError: maximum recursion depth exceeded in comparison
O(n^4)
ogóle wystarcza do przesłania Python2: D Biorąc pod uwagę przypadek testowy 998, mój kod uruchomi się 9 razy i(n+r-1)! / r! / (n-1)!
za każdym razem obliczę krotki, gdzier
rośnie liniowo od 2, a n wynosi9 - 2
. Ale hej, przynajmniej nie musiszGalaretka ,
141311 bajtówWypróbuj online!
Byłem całkiem pewien, że rozwiązanie Jelly @ Dennisa można ulepszyć. Niestety nie udało mi się pobić rekordu Brachylog, ale udało mi się go powiązać. Aktualizacja : Z pomocą @Dennis poprawiono go teraz; Chyba Jelly odbiera koronę.
Ten program jest niezwykle nieefektywny, ma wydajność O (2 n 2 ) (dlatego powyższy przypadek testowy pokazuje go dla wejścia 4). Kończy się szybko na 4, bardzo powoli na 5 i może nie być praktycznie możliwe uruchomienie większej liczby.
Co ciekawe, Brachylog został ulepszony, przechodząc od rozwiązania opisującego problem (w którym Brachylog jest dobry) do rozwiązania wykorzystującego algorytm oparty na faktoryzacji danych wejściowych (w którym Jelly jest dobry); tymczasem rozwiązanie Jelly zostało ulepszone poprzez odejście od jego mocnych stron i powrót do rozwiązania, które właśnie opisuje problem.
Wyjaśnienie:
Ponieważ dane wyjściowe
Ḋx
są sortowane, każda podsekwencja musi być również posortowana, a zatem nie musimy sortować ich indywidualnie. Tak więc „ta sama produkcja w różnych rzędach jest duplikatem” części problemu, a „wszystkie wartości w danych wyjściowych to> 1” część problemu, zostaną rozwiązane przez generację. Poza tym w zasadzie robimy tutaj „znajdź wszystkie listy dla którychP=³
”, co robimy (w niewiarygodnie nieefektywny sposób), generując wszystkie omawiane listy, a następnie filtrując niepoprawne.(Najwyraźniej ktoś musi wymyślić hybrydę Jelly i Brachylog, a także naprawdę dobry solver ograniczający, abyśmy mogli napisać coś podobnego do
{P=³}~
kodu deduplikacji i rozwiązać program o wiele krótszej długości. Może to być w pewnej odległości).źródło
2r
Może stać sięḊ
iP=³$$
może się staćP=¥
.P=¥
nie działa, gdy próbuję go w tłumaczu, chociaż nie jestem całkowicie pewien, dlaczego (logicznie, powinien działać, i to była jedna z rzeczy, które próbowałem pisząc post; po prostu spróbowałem ponownie, aby się upewnić, zdecydowanie nie robi tego, czego się spodziewałem).Ḋ
robi to jednak, więc myślę, że istnieje nasz jednobajtowy zapis :-)µ
z¹
jak dobrze, żeµ
sprawia, że powtarzane zakres nowy lewy argument.³
raczej niż¹
tylko odmiany.)JavaScript (ES6),
7467 bajtówBezpośrednio rozwiązuje problem rekurencyjnie: dla każdej liczby całkowitej m z 2 do N , weźmiemy każdej z przegród n / m z elementem minimalna liczba m (aby uniknąć powielania partycji) i dołączyć m . (Dla każdego m , który nie dzieli n , daje to pustą tablicę, ponieważ żadne liczby całkowite nie mnożą się do dziesiętnej.) Definiujemy podstawowy przypadek pustej tablicy dla 1 , aby uniknąć nieskończonej rekurencji.
źródło
Python2,
198191172180 bajtówPełny program. Można to znacznie poprawić, więc sugestie są bardzo mile widziane!
Wyjścia z zakresu od 1 do 31 (włącznie):
źródło
4 -> {2, 2}, {4}
, którego nie widzę w twoim logu.int(math.log(n,2))
, co spowodowało to. +2 bajty i będzie działać. Dzięki!math
ale używaszmath.log
.len(bin(n))-2
jest krótszy niżint(math.log(n,2))
.Galaretka , 15 bajtów
Wypróbuj online!
źródło
Clojure, 91 bajtów
Przykładowe przebiegi:
Sama wartość jest zwracana jako pojedyncza liczba (nie a
list
), inne pojawiają się jako listy. Nan
końcu można go zastąpić,[n]
aby uczynić go również sekwencją lub(list n)
zrobić z niej listę.źródło
Wolfram Language (Mathematica) ,
585652 bajtówWypróbuj online!
Zaadaptowałem z mojego rozwiązania Mathematica do Divisors Divisors Dividing . Zwraca a
Sequence
partycji.źródło
J, 35 bajtów
Na podstawie rozwiązania ograniczonego czasowo wyzwania faktoryzacji.
Ta wersja jest znacznie bardziej nieefektywna i działa w czasie silnym na podstawie liczby czynników pierwszych. Tworzy partycje, generując liczby czynnikowe.
Wypróbuj online!(Nie próbuj dużych wartości online!)
Wyjaśnienie
źródło
D, 95 bajtów
Tylko rekurencyjne rozwiązanie. W
g(n,r)
,r
jest jak dotąd partycją in
nadal pozostaje wartość do podziału na czynniki. Aby uzyskać każdą nieuporządkowaną partycję tylko raz, sortujemy czynniki wr
kolejności malejącej. Ostatni elementr
zaczyna się2
jako najmniej możliwy czynnik i zostaje zastąpiony przezn
każdą kopię tuż przed każdą operacją wyjściową.Dane
n = 60
wyjściowe są następujące:Wypróbuj online!
źródło
void g(T)(T n,T[]r){for(T i=r[0];i*i<=n;i++)n%i0:r;r.back=n;r.writeln;}g(n,[2])
std.stdio
astd.range
dane wejściowe nie1
powinny nic drukować, nie[1]
.D, 109 bajtów
Wypróbuj online!
źródło