Haskell (Lambdabot), 92 85 octets
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)
A besoin de Lambdabot Haskell car guard
nécessite Control.Monad
d'être importé. La fonction principale est une fonction anonyme, qui, me dit-on, est autorisée et supprime quelques octets.
Merci à Laikoni pour avoir économisé sept octets.
Explication:
Les monades sont très utiles.
x # y
C'est notre fonction récursive qui fait tout le travail réel. x
est le nombre sur lequel nous accumulons (le produit des diviseurs qui restent dans la valeur), et y
est le prochain nombre que nous devrions essayer de diviser en ce nombre.
| x == y = [[x]]
Si x
égaux, y
alors nous avons terminé récursif. Utilisez simplement x
la fin de la chaîne gozinta actuelle et renvoyez-la.
| 1 > 0 =
Haskell golf-ism pour "True". C'est le cas par défaut.
(guard (mod x y < 1) >>
Nous opérons maintenant dans la liste de la monade. Dans la monade de liste, nous avons la possibilité de faire plusieurs choix en même temps. Ceci est très utile pour trouver "tout ce qui est possible" de quelque chose par épuisement. L’ guard
énoncé dit "n’envisagez le choix suivant que si une condition est vraie". Dans ce cas, ne considérez le choix suivant que si y
divise x
.
(y:) . map (y *) <$> div x y#2)
Si y
divise x
, nous avons le choix d'ajouter y
à la chaîne de gozinta. Dans ce cas, appelez récursivement (#)
, en partant y = 2
de x
zéro x / y
, puisque nous voulons "factoriser" ce que y
nous venons d'ajouter à la chaîne. Ensuite, quel que soit le résultat de cet appel récursif, multipliez ses valeurs par celles que y
nous venons de factoriser et ajoutons y
officiellement à la chaîne de gozinta.
++
Considérez également le choix suivant. Cela ajoute simplement les deux listes ensemble, mais monadiquement, nous pouvons penser que "choisir entre faire cette chose OU cette autre chose".
x # (y + 1)
L'autre option consiste simplement à continuer à récursir et à ne pas utiliser la valeur y
. Si y
ne divise pas x
alors c'est la seule option. Si y
divise x
alors cette option sera prise ainsi que l'autre option, et les résultats seront combinés.
map (1 :) . (# 2)
C'est la fonction principale de gozinta. Il commence la récursion en appelant (#)
avec son argument. A 1
est ajouté à chaque chaîne gozinta, car la (#)
fonction ne les met jamais dans les chaînes.