简体   繁体   English

haskell 递增对的无限列表

[英]haskell infinite list of incrementing pairs

Create an infinite list pairs :: [(Integer, Integer)] containing pairs of the form (m,n) , where each of m and n is a member of [0 ..] .创建一个无限列表对:: [(Integer, Integer)]其中包含形式为(m,n) ,其中 m 和 n 中的每一个都是[0 ..]的成员。 An additional requirement is that if (m,n) is a legit member of the list, then (elem (m,n) pairs) should return True in finite time.另一个要求是,如果(m,n)是列表的合法成员,则(elem (m,n) pairs)应在有限时间内返回True An implementation of pairs that violates this requirement is considered a non- solution.违反此要求的对的实现被视为非解决方案。

****Fresh edit Thank you for the comments, Lets see if I can make some progress**** ****新鲜编辑谢谢你的评论,让我看看我是否可以取得一些进展****

    pairs :: [(Integer, Integer)]
    pairs = [(m,n) | t <- [0..], m <- [0..], n <-[0..], m+n == t]

Something like this?像这样的东西? I just don't know where it's going to return True in finite time.我只是不知道它会在有限的时间内返回 True 。

I feel the way the question is worded elem doesn't have to be part of my answer.我觉得问题的措辞方式 elem 不必成为我答案的一部分。 Just if you call (elem (m,n) pairs) it should return true.只要您调用(elem (m,n) pairs)它就应该返回 true。 Sound right?听起来对吗?

Ignoring the helper method, the list comprehension you have will list out all pairs but the order of elements is a problem.忽略helper方法,您拥有的列表理解列出所有对,但元素的顺序是一个问题。 You'll have a infinitely many pairs like (0, m) which are followed by infinitely many pairs like (1, m) .你会有无限多的对,比如(0, m)后面跟着无限多的对,比如(1, m) Of course elem will forever iterate all the (0, m) pairs never reaching (1, m) or (2, m) etc.当然elem将永远迭代所有(0, m)对永远不会到达(1, m)(2, m)等。

I'm not sure why you have the helper method -- with it, you are only building a list of pairs like [(0,0), (1,1), (2,2), ...] because you've filtered on m = n .我不知道为什么你有helper方法——有了它,你只构建了一个像[(0,0), (1,1), (2,2), ...]这样的对列表,因为你已经过滤了m = n Was that part of the requirements?那是要求的一部分吗?

Like @hammar suggested, start with 0 = m + n and list out the pairs (m, n).就像@hammar 建议的那样,从0 = m + n并列出对 (m, n)。 Then list pairs (m, n) where 1 = m + n .然后列出对 (m, n) 其中1 = m + n Then your list will look like [(0,0), (0,1), (1,0), (0,2), (1,1), (2,0), ...] .然后你的列表看起来像[(0,0), (0,1), (1,0), (0,2), (1,1), (2,0), ...]

The helper function ensures that pairs is a list of the form [ (0,0) , (1,1) , (2,2) ... ] .辅助函数确保对是[ (0,0) , (1,1) , (2,2) ... ]形式的列表。

So elem ( m , n ) pairs can be implemented as:所以elem ( m , n )对可以实现为:

elem (m , n) _ |  m == n    = True
               |  otherwise = False

This is a constant time implementation.这是一个恒定时间的实现。

I first posted我第一次发帖

Prelude> let pairs = [(m, n) | t <- [0..]
                     , let m = head $ take 1 $ drop t [0..] 
                     , let n = head $ take 1 $ drop (t + 1) [0..]]

Which, I believed answered the three conditions set by the professor.其中,我相信满足了教授设定的三个条件。 But hammar pointed out that if I chose this list as an answer, that is, the list of pairs of the form (t, t+1), then I might as well choose the list但是hammar指出,如果我选择这个列表作为答案,即形式为(t, t+1)的对列表,那么我还不如选择列表

repeat [(0,0)] 

Well, both of these do seem to answer the professor's question, considering there seems to be no mention of the list having to contain all combinations of [0..] and [0..].好吧,考虑到似乎没有提到必须包含 [0..] 和 [0..] 的所有组合的列表,这两个似乎都回答了教授的问题。

That aside, hammer helped me see how you can list all combinations, facilitating the evaluation of elem in finite time by building the infinite list from finite lists.除此之外,hammer 帮助我了解了如何列出所有组合,通过从有限列表构建无限列表来促进有限时间内对 elem 的评估。 Here are two other finite lists - less succinct than Hammar's suggestion of the diagonals - that seem to build all combinations of [0..] and [0..]:以下是另外两个有限列表——不如 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)]

which construct the edges (t, 0..t) (0..t, t), and构造边 (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)]

which build clockwise spirals of length 'size' squared, superimposed on hammar's diagonals algorithm.它构建了长度为“大小”平方的顺时针螺旋,叠加在 hammar 的对角线算法上。

我相信您的任务的解决方案是:

pairs = [(x,y) | u <- [0..], x <- [0..u], y <-[0..u] , u == x+y]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM