Project Euler 24

http://projecteuler.net/index.php?section=problems&id=24


例えば、0〜3で10番目の順列を考える。先頭の数字を選ぶと残りは3!通りだから、9を6で割ると1で余りは3。同様に2!で割って1余り1。1!で割って1余り0。これで[1,1,1,0]というリストができる。そこで可能な数字のインデックスの並びということができる。階乗の計算をするのは美しくないので、実際には逆から求めている。
先頭の可能な数字は[0,1,2,3]だから、1。ここから1を取り除いて、[0,2,3]。このインデックス1は、2。ここから2を取り除いて、[0,3]。インデックス1は3。残りは[0]。
結局、1230となる。


n = 10^6
div_list m 9 = [ div m 9 ] ++ [ mod m 9 ]
div_list m k = (div_list (div m k) (k + 1)) ++ [ mod m k ]

convert [] [] = []
convert (p:ps) b = [ b!!p ] ++ (convert ps (filter (/= (b!!p)) b))

a = div_list (n - 1) 1
main = print(foldl (\x y -> x * 10 + y) 0 (convert a [0..9]))