Haskell (Lambdabot), 92 85 Bytes
x#y|x==y=[[x]]|1>0=(guard(mod x y<1)>>(y:).map(y*)<$>div x y#2)++x#(y+1)
map(1:).(#2)
Benötigt Lambdabot Haskell da guard
erfordert Control.Monad
importiert werden. Die Hauptfunktion ist eine anonyme Funktion, von der mir gesagt wurde, dass sie zulässig ist und ein paar Bytes abschneidet.
Vielen Dank an Laikoni für das Speichern von sieben Bytes.
Erläuterung:
Monaden sind sehr praktisch.
x # y
Dies ist unsere rekursive Funktion, die die gesamte eigentliche Arbeit erledigt. x
ist die Zahl, über die wir akkumulieren (das Produkt der Divisoren, die im Wert verbleiben), und y
ist die nächste Zahl, die wir versuchen sollten, darin zu dividieren.
| x == y = [[x]]
Wenn x
gleich, y
dann sind wir mit der Rekursion fertig. Verwenden Sie es einfach x
als Ende der aktuellen Gozinta-Kette und senden Sie es zurück.
| 1 > 0 =
Haskell Golf-Ismus für "True". Das heißt, dies ist der Standardfall.
(guard (mod x y < 1) >>
Wir arbeiten jetzt in der Listenmonade. Innerhalb der Listenmonade haben wir die Möglichkeit, mehrere Entscheidungen gleichzeitig zu treffen. Dies ist sehr hilfreich, wenn Sie durch Erschöpfung "alles Mögliche" für etwas finden. In der guard
Anweisung heißt es: "Betrachten Sie die folgende Auswahl nur, wenn eine Bedingung erfüllt ist." Berücksichtigen Sie in diesem Fall nur die folgende Auswahl, wenn y
dividiert wird x
.
(y:) . map (y *) <$> div x y#2)
Wenn y
sich teilt x
, haben wir die Wahl y
, die Gozinta-Kette zu ergänzen. In diesem Fall rufen Sie rekursiv (#)
beginnend y = 2
mit x
gleich auf x / y
, da wir "herausrechnen" möchten, was y
wir gerade zur Kette hinzugefügt haben. Unabhängig vom Ergebnis dieses rekursiven Aufrufs multiplizieren Sie dann die Werte, indem Sie die Gozinta-Kette offiziell ausklammern y
und ergänzen y
.
++
Betrachten Sie auch die folgende Auswahl. Dies addiert einfach die beiden Listen, aber wir können uns das monadisch so vorstellen, als ob wir "wählen, ob wir dieses Ding oder dieses andere Ding machen".
x # (y + 1)
Die andere Möglichkeit besteht darin, einfach weiter zu rekursieren und den Wert nicht zu verwenden y
. Wenn y
sich nicht teilt, x
ist dies die einzige Option. Wenn dies der y
Fall ist, x
wird diese Option ebenso wie die andere Option verwendet und die Ergebnisse werden kombiniert.
map (1 :) . (# 2)
Dies ist die Hauptfunktion von gozinta. Es beginnt die Rekursion, indem es (#)
mit seinem Argument aufruft . A 1
wird jeder gozinta-Kette vorangestellt, weil die (#)
Funktion niemals eine in die Ketten einfügt .