Loops haskell中关于两个变量的迭代
好的,继续解决上的问题,我仍然开始学习Haskell和编程 我需要找到能被数字1:20整除的最小数 所以我从以下几点开始:Loops haskell中关于两个变量的迭代,loops,haskell,recursion,Loops,Haskell,Recursion,好的,继续解决上的问题,我仍然开始学习Haskell和编程 我需要找到能被数字1:20整除的最小数 所以我从以下几点开始: divides :: Int -> Int -> Bool divides d n = rem n d == 0 divise n a | divides n a == 0 = n : divise n (a+1) | otherwise = n : divise (n+1) a 我希望它继续向上移动n的值,直到1神奇地被[
divides :: Int -> Int -> Bool
divides d n = rem n d == 0
divise n a | divides n a == 0 = n : divise n (a+1)
| otherwise = n : divise (n+1) a
我希望它继续向上移动n的值,直到1神奇地被[1..20]整除。但这不起作用,现在我被困在哪里从这里开始。我假设我需要使用: [1..20]
对于a的值,我不知道如何实现这一点。最近我自己解决了Euler问题,我很想发表我的答案,但现在我将弃权。)
现在,你的节目流程有点混乱,听起来像风水人。基本上,你试着做一件事:增加n直到1..20除以n。但实际上,您应该将其视为两个步骤 目前,您的代码是这样的:“如果a不除以n,则增量n。如果a不除以n,则增量a”。但这不是你想让它说的 你想(我想)说“增量n,看看它是否除以[Edit:用所有数字1..20]。如果不是,再增量n,然后再测试,等等。”然后,你想做的是做一个子测试:一个取一个数字的子测试,用1..20测试它,然后返回一个结果 希望这有帮助!享受欧拉问题的乐趣
编辑:我真的,真的应该记住所有的单词。好吧,最近我自己解决了欧拉问题,我很想发表我的答案,但现在我将弃权。:)
现在,你的节目流程有点混乱,听起来像风水人。基本上,你试着做一件事:增加n直到1..20除以n。但实际上,您应该将其视为两个步骤 目前,您的代码是这样的:“如果a不除以n,则增量n。如果a不除以n,则增量a”。但这不是你想让它说的 你想(我想)说“增量n,看看它是否除以[Edit:用所有数字1..20]。如果不是,再增量n,然后再测试,等等。”然后,你想做的是做一个子测试:一个取一个数字的子测试,用1..20测试它,然后返回一个结果 希望这有帮助!享受欧拉问题的乐趣
编辑:我真的,真的应该记住所有的单词。好吧,作为一种算法,这有点糟糕 对不起 但是你被名单误导了。我认为您要做的是迭代所有可用的数字,直到找到一个
[1..20]
中的所有数字都可以分割的数字。在上面的实现中,如果a不除以n,则永远不会返回并检查b
算法的任何简单实现都将是:
lcmAll :: [Int] -> Maybe Int
lcmAll nums = find (\n -> all (divides n) nums) [1..]
(使用Data.List.find
和Data.List.all
)
更好的算法是使用foldl找到lcm的成对:
lcmAll :: [Int] -> Int
lcmAll = foldl lcmPair 1
lcmPair :: Int -> Int -> Int
lcmPair a b = lcmPair' a b
where lcmPair' a' b' | a' < b' = lcmPair' (a+a') b'
| a' > b' = lcmPair' a' (b + b')
| otherwise = a'
lcmAll::[Int]->Int
lcmAll=foldl lcmPair 1
lcmPair::Int->Int->Int
lcmPair a b=lcmPair'a b
其中lcmPair'a'b'| a'b'=lcmPair'a'(b+b')
|否则=a'
当然,您可以使用前奏曲中的lcm
功能,而不是lcmPair
这是因为任何一组数字的最小公倍数都与[其中两个数字的最小公倍数]和[其余数字的最小公倍数]相同。作为一种算法,这有点糟糕 对不起 但是你被名单误导了。我认为您要做的是迭代所有可用的数字,直到找到一个
[1..20]
中的所有数字都可以分割的数字。在上面的实现中,如果a不除以n,则永远不会返回并检查b
算法的任何简单实现都将是:
lcmAll :: [Int] -> Maybe Int
lcmAll nums = find (\n -> all (divides n) nums) [1..]
(使用Data.List.find
和Data.List.all
)
更好的算法是使用foldl找到lcm的成对:
lcmAll :: [Int] -> Int
lcmAll = foldl lcmPair 1
lcmPair :: Int -> Int -> Int
lcmPair a b = lcmPair' a b
where lcmPair' a' b' | a' < b' = lcmPair' (a+a') b'
| a' > b' = lcmPair' a' (b + b')
| otherwise = a'
lcmAll::[Int]->Int
lcmAll=foldl lcmPair 1
lcmPair::Int->Int->Int
lcmPair a b=lcmPair'a b
其中lcmPair'a'b'| a'b'=lcmPair'a'(b+b')
|否则=a'
当然,您可以使用前奏曲中的lcm
功能,而不是lcmPair
这是因为任何一组数字的最小公倍数与[其中两个数字的最小公倍数]和[其余数字的最小公倍数]的最小公倍数相同。函数“divisie”从不停止,它没有基本大小写。这两个分支都调用divisie,因此它们都是递归的。您还可以使用函数
对
进行除法,就像它将返回一个int(如rem
那样),但它返回一个Bool
我看你已经开始把问题分成几个部分了,这通常有助于理解并使它更容易阅读
另一件有帮助的事情是编写函数的类型。如果您的函数可以工作,但不确定其类型,请尝试ghci中的:i myFunction
。在这里,我修复了除法中的类型错误(尽管仍然存在其他错误):
你想让它返回一个列表吗
让你去解决问题,试着把问题进一步分成几个部分。下面是一个简单的方法:
检查一个数是否能被另一个数整除的函数。这是您的函数
一种函数,用于检查一个数是否可被所有数除[1..20]
尝试迭代所有数字并在#2中的函数上尝试它们的函数
函数“divisie”从不停止,它没有基本大小写。这两个分支都调用divisie,因此它们都是递归的。您还可以使用函数进行除法
,就好像它将返回一个int(如