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 guarderfordert Control.Monadimportiert 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. xist die Zahl, über die wir akkumulieren (das Produkt der Divisoren, die im Wert verbleiben), und yist die nächste Zahl, die wir versuchen sollten, darin zu dividieren.
| x == y = [[x]]
Wenn xgleich, ydann sind wir mit der Rekursion fertig. Verwenden Sie es einfach xals 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 guardAnweisung 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 ydividiert wird x.
(y:) . map (y *) <$> div x y#2)
Wenn ysich teilt x, haben wir die Wahl y, die Gozinta-Kette zu ergänzen. In diesem Fall rufen Sie rekursiv (#)beginnend y = 2mit xgleich auf x / y, da wir "herausrechnen" möchten, was ywir 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 yund 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 ysich nicht teilt, xist dies die einzige Option. Wenn dies der yFall ist, xwird 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 1wird jeder gozinta-Kette vorangestellt, weil die (#)Funktion niemals eine in die Ketten einfügt .