Я первый отправил
Prelude> let pairs = [(m, n) | t <- [0..]
, let m = head $ take 1 $ drop t [0..]
, let n = head $ take 1 $ drop (t + 1) [0..]]
Который, я верил, ответил на три условия, установленные профессором. Но Хаммар отметил, что если я выбрал этот список в качестве ответа, то есть, список пар вида (т, т + 1), то я мог бы также выбрать список
repeat [(0,0)]
Ну, как из них, кажется, отвечают на вопрос профессора, учитывая, что нет упоминания о списке, который должен содержать все комбинаций [0 ..] и [0 ..].
В этом случае молот помог мне увидеть, как вы можете перечислить все комбинации, облегчая оценку элем за конечное время, построив бесконечный список из конечных списков. Вот еще два конечных списка - менее сжатые, чем предложение Хамарга о диагоналях, которые, кажется, строят все комбинации [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)]
, которые построить края (т, 0..t) (0..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)]
которые строят по часовой стрелке спирали длиной 'размер' в квадрате, наложенные по алгоритму диагоналей хаммера.
Подсказка: Создайте их по одной диагонали за раз. Установите 't = x + y' и сгенерируйте все пары' (x, y) 'для каждого' t' в '[0 ..]'. Поскольку для каждого 't' существует только конечное число пар, это будет определять требования. – hammar
Мне нравится этот метод. Кроме того, я не уверен, как его реализовать. –
Вместо фильтрации генерируйте только возможные значения для 'm' и' n'. Для фиксированного 't', что может быть наибольшее значение' m'? После того, как вы выбрали 't' и' m', вы можете использовать 't = m + n' для вычисления' n' напрямую. – hammar