【问题标题】:haskell infinite list of incrementing pairshaskell 递增对的无限列表
【发布时间】:2013-03-13 02:44:40
【问题描述】:

创建一个无限列表对 :: [(Integer, Integer)],其中包含 (m,n) 形式的对, 其中 m 和 n 都是 [0 ..] 的成员。一个额外的要求是如果(m,n) 是列表的合法成员,则(elem (m,n) pairs) 应在有限时间内返回True。 违反此要求的对的实现被视为非解决方案。

****新鲜编辑感谢cmets,让我看看我是否可以取得一些进展****

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

这样的?我只是不知道它会在有限时间内返回 True。

我觉得问题的措辞 elem 不必成为我回答的一部分。如果您调用(elem (m,n) pairs),它应该返回true。听起来对吗?

【问题讨论】:

  • 提示:一次生成一条对角线。设置t = x + y 并为[0..] 中的每个t 生成所有对(x, y)。由于每个 t 只有有限数量的对,这将满足要求。
  • 我喜欢这种方法。除了我不确定如何实现它。
  • 不过滤,只生成mn 的可能值。对于固定的tm 可以拥有的最高值是多少?一旦你选择了tm,你就可以使用t = m + n直接计算n
  • 您确定您对问题的解释正确吗? (m,n) 的列表是什么意思?也许问题是生成所有mn 满足helper m n == True(m,n) 对(即,当您制作 列表时,您知道helper 是什么)?
  • 在您的上一次修订中,这个问题不再有意义(因为几乎所有内容都已被删除)。我把它回滚了;不确定您的意图是什么(如果您确实想说“这里已经完成,请不要再回答”,那么不要修改您的问题,而只需接受最有帮助的答案)。

标签: list haskell infinite


【解决方案1】:

忽略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), ...]

【讨论】:

  • 只指定了要求。我不认为我需要它。我如何实现一个这样做的列表???使用 list comp 并让 't' 在 m 和 n 递增时逐步上升?
  • 是的,您很可能拥有[(m,_) | t &lt;- [0..], m &lt;- _]。试着从那开始,看看你能不能填空。
  • 试过了,关注真值。
【解决方案2】:

辅助函数确保pairs是[ (0,0) , (1,1) , (2,2) ... ]形式的列表。

所以elem ( m , n ) 对可以实现为:

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

这是一个恒定时间的实现。

【讨论】:

  • 这里的下划线功能是什么?我现在将更新我的代码。
  • @johnstamos:这是一种通配符模式,它不会将elem 的第二个参数绑定到名称。这是因为此实现实际上并不需要查看列表来检查成员资格。
  • 您可以在此处消除模式匹配中的守卫:elem (m, n) _ = m == n 就足够了。
  • 这仍然是 helper 的一部分吗?
  • 如果这是一个家庭作业,我会假设你不能提供你自己对elem 的定义。相反,您可能应该使用 Prelude 中的 elem 编写 pairs 以满足要求。
【解决方案3】:

我第一次发帖

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..] 的 all 组合.

除此之外,hammer 帮助我了解了如何列出所有组合,通过从有限列表构建无限列表来促进在有限时间内对 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 的对角线算法上。

【讨论】:

  • 这只会生成(t, t+1)形式的对。
  • 问题是生成所有对自然数,这样对于任何给定的对,它都可以在列表中的某个有限索引处找到。
  • @hammar 我相信我回答了三个条件:(1) 无限列表对 :: [(Integer, Integer)],(2) 包含 (m,n) 形式的对,其中每个m 和 n 的成员是 [0 ..] 的成员,并且 (3) elem (m,n) 对) 应该在有限时间内返回 True。我没有吗?
  • 例如elem (0, 0) pairs在有限时间内不会返回True
  • 由于这显然是家庭作业,我一直试图避免给出解决方案,但这里是:[(x, t-x) | t &lt;- [0..], x &lt;- [0..t]]
【解决方案4】:

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

pairs = [(x,y) | u &lt;- [0..], x &lt;- [0..u], y &lt;-[0..u] , u == x+y]

【讨论】:

  • @ali_homsi 你的函数输出的模式是,第一个数字:0, 0 1, 0 1 2, 0 1 2 3,第二个数字0, 1 0, 2 1 0, 3 2 1 0。压缩时,它们是您的输出。它是笛卡尔积,非常适合。 diag xs ys = [ (m,n) | i&lt;- [1..], (m,n) &lt;- zip [0..i] [i,i-1..0] ]
猜你喜欢
  • 2017-02-10
  • 2017-09-28
  • 1970-01-01
  • 2015-01-10
  • 2016-09-11
  • 1970-01-01
  • 2011-08-16
  • 2012-10-04
  • 1970-01-01
相关资源
最近更新 更多