Łańcuchy Gozinta
(Zainspirowany projektem Euler # 606 )
Łańcuch gozinty dla n jest sekwencją, w {1,a,b,...,n}
której każdy element prawidłowo dzieli następny. Na przykład istnieje osiem różnych łańcuchów gozinty dla 12:
{1,12}, {1,2,12}, {1,2,4,12}, {1,2,6,12}, {1,3,12}, {1,3,6,12}, {1,4,12} and {1,6,12}.
Wyzwanie
Napisz program lub funkcję, która akceptuje dodatnią liczbę całkowitą ( n > 1
) i wyświetla lub zwraca wszystkie odrębne łańcuchy gozinta dla podanej liczby.
- Porządek w łańcuchach ma znaczenie (rosnąco), porządek łańcuchów nie.
- Jeśli istnieje taka szansa, nie możesz użyć wbudowanego rozwiązania, które rozwiązuje wyzwanie.
- To jest golf golfowy .
Edycja: usuwanie 1
jako potencjalny wkład.
code-golf
sequence
arithmetic
Parasol
źródło
źródło
[[1]]
, powiedziałbym, że jeśli[1,1]
jest gozintą,1
to[1,1,12]
jest gozintą taką,12
jaka jest[1,1,1,12]
i teraz możemy już nie „zwróć wszystko ...”2|4
czyta się „dwa idą na cztery”, czyli „dwa gozinta cztery”.Odpowiedzi:
Python 3 ,
6865 bajtówEdycja: -3 bajty dzięki @notjagan
Wypróbuj online!
Wyjaśnienie
Każdy łańcuch gozinty składa się z liczby
x
na końcu łańcucha, z przynajmniej jednym dzielnikiem po jego lewej stronie. Dla każdego dzielnikk
ox
łańcuchach[1,...,k,x]
są różne. Możemy zatem dla każdego dzielnikak
znaleźć wszystkie swoje odrębne łańcuchy gozinta i dołączaniax
do końca z nich, aby uzyskać wszystkie odrębne łańcuchy gozinta zk
bezpośrednio z lewej stronyx
. Odbywa się to rekursywnie ażx = 1
gdzie[[1]]
zostanie zwrócony, ponieważ wszystkie łańcuchy gozinta rozpocząć 1, co oznacza, że rekurencja mają najniższy.Kod staje się tak krótki dzięki zrozumieniu listy w Pythonie, umożliwiając podwójną iterację. Oznacza to, że wartości znalezione w
f(k)
można dodać do tej samej listy dla wszystkich różnych dzielnikówk
.źródło
Łuska , 13 bajtów
Nieco inne podejście do H.PWiza , choć wciąż brutalne. Wypróbuj online!
Wyjaśnienie
Podstawową ideą jest połączenie wszystkich podsekwencji
[1,...,n]
i podzielenie wyniku na listy podrzędne, w których każdy element dzieli następny. Spośród nich przechowujemy te, które zaczynają się1
, kończąn
i nie zawierają duplikatów. Odbywa się to za pomocą wbudowanego „rangify”…
. Następnie pozostaje odrzucić duplikaty.źródło
Galaretka ,
98 bajtówWypróbuj online!
Używa techniki podobnej do mojej odpowiedzi Japt , a zatem działa bardzo szybko na większych przypadkach testowych.
Jak to działa
źródło
Mathematica, 77 bajtów
Tworzy miejsce, w
Graph
którym wierzchołki należą doDivisors
danych wejściowych#
, a krawędzie reprezentują odpowiednią podzielność, a następnie znajdujeAll
ścieżki od wierzchołka1
do wierzchołka#
.źródło
Galaretka , 12 bajtów
Monadyczny link akceptujący liczbę całkowitą i zwracający listę list liczb całkowitych.
Wypróbuj online!
W jaki sposób?
Chcemy, aby wszystkie posortowane listy unikatowych liczb całkowitych między jednym a N były takie, że pierwsza to jedna, ostatnia to N, a wszystkie pary dzielą się. Kod osiąga ten filtr, sprawdzając, czy kryteria podziału parami są spełnione w porównaniu z zestawem mocy danego zakresu, ale tylko wybierając te z maksymalnymi sumami różnic przyrostowych (te, które zaczynają się od jednego, a kończą na N, będą miały suma różnic przyrostowych N-1, inne będą miały mniej).
źródło
<slice>2<divisible>\<each>
: PƝ
zamiast `2` dla 11 bajtów .Japt , 17 bajtów
Przetestuj online!
Co dziwne, wygenerowanie wyniku w postaci ciągu było o wiele łatwiejsze niż wygenerowanie go jako tablicy tablic ...
Wyjaśnienie
źródło
¬
sztuczkę! : p¬
jest jednym z powodów, dla których zaimplementowałem kilka funkcji, które w zasadzie „wykonują X bez argumentów lub Y z prawdziwymi argumentami”: PMathematica, 60 bajtów
Korzysta z nieudokumentowanej formy wielu argumentów
Divisible
, gdzieDivisible[n1,n2,...]
zwracaTrue
jeślin2∣n1
,n3∣n2
itdFalse
. Itd. Bierzemy wszystkoSubsets
z listyDivisors
wejścia#
, a potem wróć doCases
formy{1,___,#}
takiej, któraDivisible
dajeTrue
oReverse
sekwencji D dzielników.źródło
Divisible
zasadzie jest wbudowane narzędzie do weryfikacji łańcucha gozinta?Haskell, 51 bajtów
Rekurencyjnie znajdź łańcuchy właściwych dzielników gozinta i dołącz
n
.Wypróbuj online!
źródło
1
. Skoro wspólnie postanowiliśmy zwolnić1
, czy możesz zaoszczędzić 10 bajtów, usuwając tę skrzynkę?1
nie jest specjalnym przypadkiem dla tego algorytmu, jest potrzebny jako podstawowy przypadek rekurencji. Samo drugie równanie definiujące może zwrócić tylko pustą listę.[[1]]
jako bazę.Haskell (Lambdabot),
9285 bajtówPotrzebuje Lambdabot Haskell, ponieważ
guard
wymagaControl.Monad
importu. Główna funkcja jest funkcją anonimową, o której, jak mi powiedziano, jest dozwolona i goli kilka bajtów.Dzięki Laikoni za zaoszczędzenie siedmiu bajtów.
Wyjaśnienie:
Monady są bardzo przydatne.
To jest nasza funkcja rekurencyjna, która wykonuje całą rzeczywistą pracę.
x
to liczba, nad którą się kumulujemy (iloczyn dzielników, które pozostają w wartości) iy
jest następną liczbą, którą powinniśmy spróbować podzielić.Jeśli
x
jest równyy
, to zakończyliśmy rekurencję. Wystarczy użyćx
jako końca bieżącego łańcucha gozinta i zwrócić go.Haskell golf-ism dla „True”. To jest przypadek domyślny.
Działamy teraz na liście monad. W ramach monady listy mamy możliwość dokonywania wielu wyborów jednocześnie. Jest to bardzo pomocne przy znajdowaniu „wszystkiego, co możliwe” czegoś przez wyczerpanie. W
guard
oświadczeniu jest napisane: „rozważ następujący wybór tylko wtedy, gdy spełniony jest warunek”. W takim przypadku rozważ tylko następujący wybór, jeśliy
dzielix
.Jeśli
y
dzielix
, mamy do wyboru dodaniey
do łańcucha gozinta. W tym przypadku, rekurencyjnie zadzwonić(#)
, wychodząc na coy = 2
sięx
równax / y
, ponieważ chcemy „czynnik out”, którey
po prostu dodaje się do łańcucha. Następnie, bez względu na wynik tego rekurencyjnego wezwania, pomnóż jego wartości przezy
właśnie uwzględnione iy
oficjalnie dodaj do łańcucha gozinta.Rozważ również następujący wybór. To po prostu dodaje obie listy razem, ale monadycznie możemy myśleć o tym jako o powiedzeniu „wybierz między robieniem tego, a tym innym”.
Inną opcją jest po prostu kontynuowanie rekurencji i nie używanie wartości
y
. Jeśliy
nie dzieli,x
jest to jedyna opcja. Jeśliy
dzieli,x
to ta opcja zostanie wzięta, podobnie jak druga opcja, a wyniki zostaną połączone.Jest to główna funkcja gozinta. Rozpoczyna rekursję od wywołania
(#)
z argumentem. A1
jest dołączane do każdego łańcucha gozinta, ponieważ(#)
funkcja nigdy nie umieszcza jednych w łańcuchach.źródło
mod x y==0
można skrócić domod x y<1
. Ponieważ funkcje anonimowe są dozwolone, twoja główna funkcja może być zapisana bez użycia punktu jakomap(1:).(#2)
.Haskell,
10710095 bajtówMoże jest lepszy warunek zakończenia (próbował czegoś takiego
ale jest dłuższy). Kontrola
1
wydaje się być ostrożna, ponieważ powtarzanie szorowania1
lub duplikaty (nub
nie wPrelude
) to więcej bajtów.Wypróbuj online.
źródło
(>>=h)
dla(concatMap h)
u
JavaScript (Firefox 30-57), 73 bajty
Dogodnie
n%0<1
jest to fałsz.źródło
Galaretka , 17 bajtów
Wypróbuj online!
źródło
1
jest jednak nieoczekiwany. Nie udało mi się znaleźć ostatecznego wyniku1
, ale założyłem, że tak[[1]]
. Nie mogę powiedzieć na pewno, że[1,1]
jest to nieprawidłowe, z wyjątkiem tego, że wszystkie inne wyniki zwiększają sekwencje. Myśli?;€
z;Q¥€
).Mathematica, 104 bajty
źródło
FreeQ[...]
może zostaćAnd@@BlockMap[#∣#2&@@#&,#,2,1]
Developer
PartitionMap :: nlen: - Nie znaleziono tekstu wiadomości - >> `` dlaczego?BlockMap
używa tejDeveloper`PartitionMap
funkcji wewnętrznie, ale ponieważ jest to funkcja programisty, nie ma komunikatów o błędach. Błąd jest spowodowany przez listy zawierające 1 lub 0 elementów, z którymi nie można tworzyć 2-partycji.Mathematica, 72 bajty
Wyjaśnienie
Znajdź wszystkie dzielniki wejścia.
Wygeneruj wszystkie podzbiory z tej listy.
Wybierz wszystkie etui, które pasują do wzoru ...
Począwszy od 1, a kończąc na
<input>
...i spełnia warunek ...
Lewy element dzieli prawy element dla wszystkich 2-partycji listy, przesunięcie 1.
źródło
TI-BASIC, 76 bajtów
Wyjaśnienie
Mógłbym zapisać kolejne 5 bajtów, jeśli można wyjść z błędem zamiast z wdziękiem, usuwając zaznaczenie Ans> 1 i warunek pętli. Ale nie jestem pewien, czy to dozwolone.
źródło
Mathematica
8677 bajtówBrutalna siła z definicji.
Żałując, że nie istnieje krótszy sposób na porównanie parami elementów sekwencyjnych listy.
Dzięki @Jenny_mathy i @JungHwanMin za sugestie oszczędzające 9 bajtów
źródło
FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&]
(jako drugiego argumentu), aby przejść do 82 bajtówAnd@@BlockMap[#∣#2&@@#&,#,2,1]
Łuska ,
1716 bajtów-1 bajt, dzięki Zgarb
Wypróbuj online!
źródło
50
dane wejściowe i upłynął limit czasu. Jaki jest sens twojego podejścia?o`:⁰:1
może być`Je1⁰
PHP
147141Edytowano, aby usunąć zbędny test
Wyjaśnił:
15 znaków płyty kotłowej :(
Zainicjuj wynik ustawiony na
[[1]]
tak, jak każdy łańcuch zaczyna się od 1. To również prowadzi do obsługi 1 jako danych wejściowych.Dla każdej liczby od 2 do
$i
przedłużymy każdy łańcuch w naszym zestawie o bieżącą liczbę, jeśli będzie to gozinta , a następnie dodamy rozszerzony łańcuch do naszego zestawu wyników.Odfiltruj nasze łańcuchy pośrednie, które tego nie zrobiły
$i
10 znaków płyty kotłowej :(
źródło
Matematyka
Odpowiedź jest zapisywana w pamięci podręcznej dla dodatkowych połączeń.
źródło