Haskell (Lambdabot), 92 85 байт
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)
Потрібен Lambdabot Haskell, оскільки його guardпотрібно Control.Monadімпортувати. Основна функція - це анонімна функція, яка, як мені кажуть, дозволена, і вона обробляє пару байтів.
Дякуємо Лайконі за збереження семи байтів.
Пояснення:
Монади дуже зручні.
x # y
Це наша рекурсивна функція, яка виконує всю фактичну роботу. x- це число, яке ми накопичуємо (добуток дільників, які залишаються у значенні), і yце наступне число, яке ми повинні спробувати поділити на нього.
| x == y = [[x]]
Якщо xдорівнює, yто ми закінчуємо повторення. Просто використовуйте xяк кінець поточного ланцюжка gozinta і поверніть його.
| 1 > 0 =
Haskell golf-ism для "Правда". Тобто це справа за замовчуванням.
(guard (mod x y < 1) >>
Зараз ми працюємо всередині монади у списку. У монаді списку ми маємо можливість робити кілька варіантів одночасно. Це дуже корисно, коли вичерпавши «все можливе» чогось. У guardзаяві сказано: "Розгляньте наступний вибір лише тоді, коли умова справжня". У цьому випадку враховуйте наступний вибір лише у випадку yрозділення x.
(y:) . map (y *) <$> div x y#2)
Якщо yрозділимо x, ми маємо вибір додати yдо ланцюжка гозінта. У цьому випадку рекурсивно дзвоніть (#), починаючи y = 2з рівня, xрівного x / yтому, що ми хочемо "визначити", що yтільки що додали до ланцюга. Тоді, незалежно від результату цього рекурсивного виклику, множимо його значення на yщойно розроблені нами дані та додаємо yдо ланцюгу gozinta офіційно.
++
Розглянемо також наступний вибір. Це просто додає два списки разом, але монально ми можемо думати про це як про те, щоб сказати: "вибирай між тим, чи робиш цю справу АБО іншою справою".
x # (y + 1)
Інший варіант - просто продовжувати повторення та не використовувати значення y. Якщо yне ділиться, xто це єдиний варіант. Якщо yрозділити, xто цей варіант буде прийнятий, як і інший варіант, і результати будуть об'єднані.
map (1 :) . (# 2)
Це основна функція гозінта. Починається рекурсія з виклику (#)своїм аргументом. A 1є попередньою для кожного ланцюга gozinta, оскільки (#)функція ніколи не ставить їх у ланцюги.