私が最初に投稿した
Prelude> let pairs = [(m, n) | t <- [0..]
, let m = head $ take 1 $ drop t [0..]
, let n = head $ take 1 $ drop (t + 1) [0..]]
それは、教授が設定した3つの条件に答えたと思います。しかし、hammarは、このリストを答えとして選択した場合、つまり(t、t + 1)の形式のペアのリストを選択した場合は、リストを選択した方がよいと指摘しました。
repeat [(0,0)]
[0..]と[0..]のすべての組み合わせをリストに含める必要があるという言及がないように思われることを考えると、これらは両方とも教授の質問に答えているようです。
それはさておき、hammerは、すべての組み合わせをリストする方法を理解するのに役立ち、有限リストから無限リストを作成することで、有限時間でのelemの評価を容易にしました。[0..]と[0..]のすべての組み合わせを構築しているように見える、他の2つの有限リスト(Hammarの対角線の提案よりも簡潔ではありません)を次に示します。
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)]
これは、長さ「サイズ」の2乗の時計回りのスパイラルを構築し、ハンマーの対角線アルゴリズムに重ね合わせます。