Список с числами, цифры которых составляют всего 2, 4, 6

#haskell

#haskell

Вопрос:

Задача состоит в том, чтобы сгенерировать список с числами, цифры которых составляют всего 2,4,6.

Пример:[2,4,6,22,24,26,42,44,46,62,64,66,222,224,226,…]

Я уже решил эту задачу с помощью грубой силы:

 numberHasOnly246 :: Integer -> Bool
numberHasOnly246 0 = False
numberHasOnly246 n = result 
  where
    result = helper True (abs n)
helper :: Bool -> Integer -> Bool
helper result n 
  | (div n 10 == 0) = condition amp;amp; result
  | (div n 10 > 0)  = helper (condition amp;amp; result) (div n 10) 
  where
    condition = mod n 10 == 4 || mod n 10 == 6 || mod n 10 == 2

series246 :: [Integer]
series246 = numbers[1..] 
  where
    numbers(e : ls) = e : (numbers [ x | x <- ls, (numberHasOnly246 x == True)])
  

Но, похоже, это решение слишком медленное.
Кроме того, я читал, что в Haskell существует метод завязывания узлов для создания бесконечных списков, но здесь я не могу найти, как решить его, связав узел. Подходит ли этот метод здесь?

Комментарии:

1. вместо генерации и тестирования вы можете просто сгенерировать числа таким образом, чтобы они содержали 2, 4 и 6.

Ответ №1:

Вместо подхода «генерировать и тестировать» вы можете генерировать только допустимые числа.

Для одной цифры это, таким образом:

 digits :: [Int]
digits = [2, 4, 6]
  

для чисел мы можем использовать рекурсию здесь:

 numbers = [ 10*t   d | t <- (0:numbers), d <- digits ]
  

Вот t , таким образом, значения, которые мы умножаем на 10, и мы начинаем 0 . d это цифры, которые мы затем можем добавить. Таким образом, это дает нам:

 Prelude> numbers
[2,4,6,22,24,26,42,44,46,62,64,66,222,224,226,242,244,246,262,264,266,422,424,426,442, …