Вот мой быстрый, более подход Haskell-y, , использующий ваш алгоритм :
Prelude> let divisibleByUpTo i n = all (\x -> (i `rem` x) == 0) [1..n]
Prelude> take 1 $ filter (\x -> snd x == True) $ map (\x -> (x, divisibleByUpTo x 4)) [1..]
[(12,True)]
divisibleByUpTo возвращает логическое значение, если число i
делится на каждое целое число вплоть до n
, аналогично вашей функции divides
.
Следующая строка, вероятно, выглядит довольно трудно для новичка на Haskell, поэтому я объясню это по крупицам:
Начиная справа, у нас есть map (\x -> (x, divisibleByUpTo x 4)) [1..]
, который говорит для каждого числа x
от 1 и выше, введите divisibleByUpTo x 4
и верните его в кортеже (x, divisibleByUpTo x 4)
. Я использую кортеж, чтобы мы знали, какое число делится точно.
Слева от этого у нас есть filter (\x -> snd x == True)
; то есть возвращать только те элементы, где второй элемент кортежа - True
.
И в самом левом утверждении мы take 1
, потому что в противном случае у нас был бы бесконечный список результатов.
Это займет довольно много времени для значения 20. Как и другие говорили, вам нужен лучший алгоритм - подумайте, как получить значение 4, хотя наши «входные» числа были 1-2-3-4 в конечном итоге ответом было только произведение 3 * 4. Подумайте, почему 1 и 2 были «исключены» из уравнения.