Project Euler #24 in Haskell
我正试图用Haskell解决Project Euler的问题,但我在24时被吸引了。
我试图用阶乘来解决这个问题,但最后三位数字不起作用,下面是我的代码:
1 2 3 4 5 6 7 8 9 10 11
| import Data.List
fact n = product [n, n -1 .. 1]
recur :: Int -> Int -> [Int] -> [Int]
recur x y arr
| y > 1 = arr !! d : recur r (y -1) (delete (arr !! d ) arr )
| otherwise = arr
where d = x ` div` fact y
r = x ` mod` fact y
main ::IO()
main = print(recur 1000000 9 [0.. 9]) |
(我知道它现在不是真正的"功能性的")。我设法得到了结果[2,7,8,3,9,1,4,5,0,6],而我无意中得出的正确答案是2783915460。
我只想知道为什么这个算法在最后三位数不起作用。谢谢。
- (delete (arr !! d) arr)不是从列表中删除元素的正确方法。
- 您是否测试过较小的情况,即您的函数以词典编纂顺序生成所有排列?
- @一般来说,是的,但是这里的选择列表中没有重复项,所以没关系。
- @当然,只要你的"好"的概念意味着1。获取列表(o(d))的元素,2。删除该元素(D比较,加上列表重建)。它真的是一个合理的方法来删除一个你已经知道其索引的元素吗?
- @从整体正确性的角度来看,bipll"OK"。(你看不到,但我也否决了你的评论)。:)@op,正确的方法是使用splitAt。
- 旁注:您要使用divMod(resp.quotRem当你需要div和mod(quot和rem在同一个号码上时。这通常是两个以上的一个师的行动。
对于该算法,未经修正的divMod是错误的。你需要
1 2 3 4
| dvm x facty | r == 0 = (d -1, facty )
| otherwise = (d, r )
where
(d, r ) = divMod x facty |
相反:
1 2 3 4
| recur x y arr
.......
.......
where (d, r) = x `dvm` fact y |
号
我们不能有零个组合来向左。零表示无。
另外,模式保护条件也应更改为y > 0。只有当剩余选项列表的长度为1(此时,y为0)时,才没有其他选项可供选择,我们只使用剩下的最后一个可用数字。
- 也可以写入dvm x facty = let (d, r) = divMod (x-1) facty in (d, r+1)。
- 不过,看起来不那么清晰,也更模糊了。
- 不是真的。在这种形式下,在下一个迭代中,r+1被反馈为x,在这里,我们用divMod和x-1进行divMod运算,这样我们就可以看到+1和-1相互抵消,所以如果我们刚开始用999999而不是1000000运算,就可以使用普通的divMod,因为我们应该开始计算从0改为1。