创建包含
:: [(Integer, Integer)]
形式对的无限列表对(m,n)
, 其中m和n中的每一个都是[0 ..]
的成员。另一个要求是(m,n)
是列表的合法成员,然后(elem (m,n) pairs)
应该在有限的时间内返回True
。 违反此要求的对的实现被认为是非解决方案。
****新编辑感谢您的评论,让我们看看我是否可以取得一些进展****
pairs :: [(Integer, Integer)]
pairs = [(m,n) | t <- [0..], m <- [0..], n <-[0..], m+n == t]
这样的东西?我只是不知道它会在有限的时间内返回True。
我觉得问题措辞的方式elem不一定是我答案的一部分。如果你打电话给(elem (m,n) pairs)
,它应该返回true。听起来不对吗?
答案 0 :(得分:8)
忽略helper
方法,你有的列表理解将列出所有对,但元素的顺序是个问题。您将拥有无限多对,例如(0, m)
,后跟无限多对,例如(1, m)
。当然elem
将永远迭代所有(0, m)
对从未到达(1, m)
或(2, m)
等。
我不确定您为何拥有helper
方法 - 使用它,您只需构建[(0,0), (1,1), (2,2), ...]
对的列表,因为您已对m = n
进行了过滤。是那部分要求吗?
像@hammar建议的那样,从0 = m + n
开始并列出对(m,n)。然后列出对(m,n)1 = m + n
。然后,您的列表将显示为[(0,0), (0,1), (1,0), (0,2), (1,1), (2,0), ...]
。
答案 1 :(得分:1)
辅助函数可确保对是[ (0,0) , (1,1) , (2,2) ... ]
形式的列表。
所以elem ( m , n )
对可以实现为:
elem (m , n) _ | m == n = True
| otherwise = False
这是一个恒定时间的实现。
答案 2 :(得分:1)
我首先发布了
Prelude> let pairs = [(m, n) | t <- [0..]
, let m = head $ take 1 $ drop t [0..]
, let n = head $ take 1 $ drop (t + 1) [0..]]
其中,我相信回答了教授设定的三个条件。但是Hammar指出,如果我选择这个列表作为答案,也就是表格(t,t + 1)对的列表,那么我不妨选择列表
repeat [(0,0)]
好吧,这两个似乎都回答了教授的问题,考虑到似乎没有提到列表必须包含 [0 ..]和[0 ..]的所有组合
除此之外,锤子帮助我看到如何列出所有组合,通过从有限列表构建无限列表来促进有限时间内elem的评估。以下是另外两个有限列表 - 比Hammar建议的对角线更简洁 - 似乎构建了[0 ..]和[0 ..]的所有组合:
edges = concat [concat [[(m,n),(n,m)] | let m = t, n <- take m [0..]] ++ [(t,t)]
| t <- [0..]]
*Main> take 9 edges
[(0,0),(1,0),(0,1),(1,1),(2,0),(0,2),(2,1),(1,2),(2,2)]
构造边(t,0..t)(0..t,t)和
oddSpirals size = concat [spiral m size' | m <- n] where
size' = if size < 3 then 3 else if even size then size - 1 else size
n = map (\y -> (fst y * size' + div size' 2, snd y * size' + div size' 2))
[(x, t-x) | let size' = 5, t <- [0..], x <- [0..t]]
spiral seed size = spiral' (size - 1) "-" 1 [seed]
spiral' limit op count result
| count == limit =
let op' = if op == "-" then (-) else (+)
m = foldl (\a b -> a ++ [(op' (fst $ last a) b, snd $ last a)]) result (replicate count 1)
nextOp = if op == "-" then "+" else "-"
nextOp' = if op == "-" then (+) else (-)
n = foldl (\a b -> a ++ [(fst $ last a, nextOp' (snd $ last a) b)]) m (replicate count 1)
n' = foldl (\a b -> a ++ [(nextOp' (fst $ last a) b, snd $ last a)]) n (replicate count 1)
in n'
| otherwise =
let op' = if op == "-" then (-) else (+)
m = foldl (\a b -> a ++ [(op' (fst $ last a) b, snd $ last a)]) result (replicate count 1)
nextOp = if op == "-" then "+" else "-"
nextOp' = if op == "-" then (+) else (-)
n = foldl (\a b -> a ++ [(fst $ last a, nextOp' (snd $ last a) b)]) m (replicate count 1)
in spiral' limit nextOp (count + 1) n
*Main> take 9 $ oddSpirals 3
[(1,1),(0,1),(0,2),(1,2),(2,2),(2,1),(2,0),(1,0),(0,0)]
构建长度'大小'的顺时针螺旋平方,叠加在hammar的对角线算法上。
答案 3 :(得分:0)
我相信您的任务的解决方案是:
pairs = [(x,y) | u <- [0..], x <- [0..u], y <-[0..u] , u == x+y]