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)
Necesita Lambdabot Haskell ya que guardrequiereControl.Monad ser importado. La función principal es una función anónima, que me han dicho que está permitida y elimina un par de bytes.
Gracias a Laikoni por guardar siete bytes.
Explicación:
Las mónadas son muy útiles.
x # y
Esta es nuestra función recursiva que hace todo el trabajo real. xes el número sobre el que estamos acumulando (el producto de los divisores que permanecen en el valor), y yes el siguiente número en el que deberíamos intentar dividirlo.
| x == y = [[x]]
Si xes igual, yentonces hemos terminado de recurrir. Solo xúselo como el final de la cadena actual de gozinta y devuélvalo.
| 1 > 0 =
Haskell golf-ism para "Verdadero". Es decir, este es el caso predeterminado.
(guard (mod x y < 1) >>
Estamos operando dentro de la lista mónada ahora. Dentro de la lista de mónadas, tenemos la capacidad de tomar múltiples decisiones al mismo tiempo. Esto es muy útil cuando se encuentra "todo lo posible" de algo por agotamiento. La guarddeclaración dice "solo considere la siguiente opción si una condición es verdadera". En este caso, solo considere la siguiente opción si se ydivide x.
(y:) . map (y *) <$> div x y#2)
Si se ydivide x, tenemos la opción de agregar ya la cadena de gozinta. En este caso, llame recursivamente (#), comenzando de nuevo y = 2con xigual a x / y, ya que queremos "factorizar" lo que yacabamos de agregar a la cadena. Luego, cualquiera que sea el resultado de esta llamada recursiva, multiplique sus valores por los yque acabamos de factorizar y yagreguemos oficialmente a la cadena de gozinta.
++
Considere la siguiente opción también. Esto simplemente agrega las dos listas juntas, pero monádicamente podemos pensar que dice "elegir entre hacer esto o lo otro".
x # (y + 1)
La otra opción es simplemente continuar recurriendo y no usar el valor y. Si yno se divide x, esta es la única opción. Si se ydivide, xentonces se tomará esta opción, así como la otra opción, y los resultados se combinarán.
map (1 :) . (# 2)
Esta es la función principal de gozinta. Comienza la recursión llamando (#)con su argumento. A 1se antepone a cada cadena de gozinta, porque la (#)función nunca los pone en las cadenas.