Loops 仅在haskell中使用递归的乘积n=(a^2)*(a^3)的数目

Loops 仅在haskell中使用递归的乘积n=(a^2)*(a^3)的数目,loops,haskell,recursion,nested,iteration,Loops,Haskell,Recursion,Nested,Iteration,在Haskell中,我想知道对于给定的数字n,给定的n=(a^2)*(a^3),有多少对a,b。我必须给出数字,它应该返回成对的数字。例如: Main> count 24 0 Main> count 72 1 Main> count 256 2 Main> count 4096 3 Main> count 46656 4 到目前为止,我只做了一个程序,对于一个数字n,求出n=(a^2)*(a^3)的所有可能组合的总和。例如,对于n=2,(1^2+1^3)+(1^2

在Haskell中,我想知道对于给定的数字n,给定的
n=(a^2)*(a^3)
,有多少对a,b。我必须给出数字,它应该返回成对的数字。例如:

Main> count 24
0
Main> count 72
1
Main> count 256
2
Main> count 4096
3
Main> count 46656
4
到目前为止,我只做了一个程序,对于一个数字n,求出
n=(a^2)*(a^3)
的所有可能组合的总和。例如,对于
n=2
(1^2+1^3)+(1^2+2^3)+(2^2+2^3)+(2^2+1^3)
。有什么建议吗?我被要求在没有列表的情况下执行此程序

sumF :: (Int->Int)->Int->Int
sumF f 0 = 0
sumF f n = sumF f (n-1) + f n



sumF1n1n :: (Int->Int->Int)->Int->Int
sumF1n1n f 0 = 0
sumF1n1n f n = sumF1n1n f (n-1)
    +sumF (\i -> f i n) (n-1)
    +sumF (\j -> f n j) (n-1)
    +f n n

func :: Int->Int->Int
func 0 0 = 0
func a b = res
    where
    res = (a^2*b^3)

call :: Int->Int
call n = sumF1n1n func n

如果只想使用递归,首先必须找到一种方法来枚举一个范围内的所有对。例如,对于范围
(a,b)
您想要
[(0,0)、(0,1)、(0,a)、(1,0)、(1,0)、(1,b)、(1,b)、(a,b)]
。第一个想法是从
(a,b)
开始,减少
a
直到它达到
0
,然后用
(a,b-1)
等重新启动

我们可以试试这样:

-- doesn't work
couples 0 0 = [(0,0)]
-- what to do when a reaches 0?   v
couples 0 b = [(0,b)] ++ couples *?* (b-1)
couples a b = [(a,b)] ++ couples (a-1) b
a
达到
0
时,我们希望从
a
的初始值重新启动,并将
b
减少1。因此,我们必须存储
a
的初始值:

couples' 0 0 _ = [(0,0)]
-- use max_a to set the restart
couples' 0 b max_a = [(0,b)] ++ couples' max_a (b-1) max_a
couples' a b max_a = [(a,b)] ++ couples' (a-1) b max_a
它的工作原理是:

couples a b = couples' a b a
main = print $ couples 3 2
-- [(3,2),(2,2),(1,2),(0,2),(3,1),(2,1),(1,1),(0,1),(3,0),(2,0),(1,0),(0,0)]
现在,我们不需要所有的夫妇,只需要那些验证
a*a*b*b==n
的夫妇。(注意:我排除了
(0,0)
对,因为我假设
n/=0
。如果
n==0
,那么您有很多解决方案!)

这很简单:

call' _ 0 0 _ = []
call' n 0 b max_a = call' n max_a (b-1) max_a
call' n a b max_a = (if n==a*a*b*b*b then [(a,b)] else []) ++ call' n (a-1) b max_a
如果我写:

call n = call' n max max max
        where max = (ceiling.sqrt.fromIntegral) n
我得到以下结果:

call 24
-- []
call 72
-- [(3,2)]
call 256
-- [(2,4),(16,1)]
call 4096
-- [(1,16),(8,4),(64,1)]
call 46656
-- [(1,36),(8,9),(27,4),(216,1)]
如果只需要计数,请使用以下命令:

call' _ 0 0 _ = 0
call' n 0 b max_a = call' n max_a (b-1) max_a
call' n a b max_a = (if n==a*a*b*b*b then 1 else 0) + call' n (a-1) b max_a
对于记录,您可以使用列表理解来执行此操作:

Prelude> couples a b = [(i,j)| i<-[0..a], j<-[0..b]]
Prelude> couples 3 2
[(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2),(3,0),(3,1),(3,2)]
Prelude>耦合a b=[(i,j)|我调用n=[(a,b)|让max=(天花板.sqrt.fromIntegral)n,调用72
[(3,2)]
序曲>呼叫256
[(2,4),(16,1)]
前奏曲>呼叫4096
[(1,16),(8,4),(64,1)]
前奏曲>呼叫46656
[(1,36),(8,9),(27,4),(216,1)]
Prelude> call n = [(a,b)| let max = (ceiling.sqrt.fromIntegral) n, a<-[0..max], b<-[0..max], n==a*a*b*b*b]
Prelude> call 24
[]
Prelude> call 72
[(3,2)]
Prelude> call 256
[(2,4),(16,1)]
Prelude> call 4096
[(1,16),(8,4),(64,1)]
Prelude> call 46656
[(1,36),(8,9),(27,4),(216,1)]