Haskell (Lambdabot), 92 85 byte
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)
Kebutuhan Lambdabot Haskell sejak guard
membutuhkan Control.Monad
harus diimpor. Fungsi utama adalah fungsi anonim, yang saya diberitahu diizinkan dan memangkas beberapa byte.
Terima kasih kepada Laikoni karena telah menghemat tujuh byte.
Penjelasan:
Monad sangat berguna.
x # y
Ini adalah fungsi rekursif kami yang melakukan semua pekerjaan yang sebenarnya. x
adalah angka yang kita akumulasikan (produk dari pembagi yang tetap dalam nilainya), dan y
merupakan angka berikutnya yang harus kita coba bagi ke dalamnya.
| x == y = [[x]]
Jika x
sama y
maka kita sudah selesai berulang. Cukup gunakan x
sebagai akhir dari rantai gozinta saat ini dan kembalikan.
| 1 > 0 =
Haskell golf-isme untuk "True". Artinya, ini adalah kasus default.
(guard (mod x y < 1) >>
Kami beroperasi di dalam daftar monad sekarang. Dalam daftar monad, kami memiliki kemampuan untuk membuat banyak pilihan sekaligus. Ini sangat membantu ketika menemukan "semua kemungkinan" dari sesuatu dengan kelelahan. The guard
pernyataan mengatakan "hanya mempertimbangkan pilihan berikut jika kondisi benar". Dalam hal ini, hanya pertimbangkan pilihan berikut jika y
membelah x
.
(y:) . map (y *) <$> div x y#2)
Jika y
memang memecah x
, kami memiliki pilihan untuk menambahkan y
ke rantai gozinta. Dalam hal ini, secara rekursif panggilan (#)
, mulai lagi dari awal di y = 2
dengan x
sama dengan x / y
, karena kita ingin "faktor luar" yang y
kita hanya ditambahkan ke rantai. Lalu, apa pun hasil dari panggilan rekursif ini, gandakan nilainya dengan yang y
baru saja kami y
pertimbangkan dan tambahkan ke rantai gozinta secara resmi.
++
Pertimbangkan pilihan berikut juga. Ini hanya menambahkan dua daftar bersama, tetapi secara monadis kita dapat menganggapnya sebagai mengatakan "pilih antara melakukan hal ini ATAU hal lain ini".
x # (y + 1)
Opsi lainnya adalah terus berulang dan tidak menggunakan nilainya y
. Jika y
tidak membagi x
maka ini adalah satu-satunya pilihan. Jika y
tidak membagi x
maka opsi ini akan diambil serta opsi lainnya, dan hasilnya akan digabungkan.
map (1 :) . (# 2)
Ini adalah fungsi utama gozinta. Itu memulai rekursi dengan memanggil (#)
dengan argumennya. A 1
ditambahkan ke setiap rantai gozinta, karena (#)
fungsi tidak pernah menempatkan orang ke dalam rantai.