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)
Needs Lambdabot Haskell since guard
requires Control.Monad
to be imported. Main function is an anonymous function, which I'm told is allowed and it shaves off a couple of bytes.
Thanks to Laikoni for saving seven bytes.
Explanation:
Monads are very handy.
x # y
This is our recursive function that does all the actual work. x
is the number we're accumulating over (the product of the divisors that remain in the value), and y
is the next number we should try dividing into it.
| x == y = [[x]]
If x
equals y
then we're done recursing. Just use x
as the end of the current gozinta chain and return it.
| 1 > 0 =
Haskell golf-ism for "True". That is, this is the default case.
(guard (mod x y < 1) >>
We're operating inside the list monad now. Within the list monad, we have the ability to make multiple choices at the same time. This is very helpful when finding "all possible" of something by exhaustion. The guard
statement says "only consider the following choice if a condition is true". In this case, only consider the following choice if y
divides x
.
(y:) . map (y *) <$> div x y#2)
If y
does divide x
, we have the choice of adding y
to the gozinta chain. In this case, recursively call (#)
, starting over at y = 2
with x
equal to x / y
, since we want to "factor out" that y
we just added to the chain. Then, whatever the result from this recursive call, multiple its values by the y
we just factored out and add y
to the gozinta chain officially.
++
Consider the following choice as well. This simply adds the two lists together, but monadically we can think of it as saying "choose between doing this thing OR this other thing".
x # (y + 1)
The other option is to simply continue recursing and not use the value y
. If y
does not divide x
then this is the only option. If y
does divide x
then this option will be taken as well as the other option, and the results will be combined.
map (1 :) . (# 2)
This is the main gozinta function. It begins the recursion by calling (#)
with its argument. A 1
is prepended to every gozinta chain, because the (#)
function never puts ones into the chains.