2016-03-06 2 views
0

сказать, что я хочу, чтобы создать ленивую последовательность всех чисел от 1 до m которых их наибольший общий делитель с m равно 1:Ленивых-сл генератор с использованием диапазона в Clojure

(def m 38941629971148227236N) 
(def possible-e 
    (lazy-seq (filter #(= 1 (gcd % m)) (range 1 m))) 
) 

, то я могу take последовательность, такая как

(take 10 possible-e) 
=> (1 3 5 7 9 11 13 15 17 19) 

но когда я пытаюсь сделать то же самое по-другому, все не работает. Я думаю, что это вычисление всех чисел, так как он принимает, как всегда, чтобы напечатать что-нибудь:

(def possible-e 
    (lazy-seq (filter #(= 1 (gcd % m)) (reverse (range 1 m)))) 
) 

, почему это не работает точно так же? какое решение?

ответ

2

Проблема здесь:

(reverse (range 1 m)) 

Прежде чем ваш код может перейти к filter он должен вычислить полный range. Вы можете использовать range с отрицательным шагом вместо:

(def possible-e 
    (lazy-seq (filter #(= 1 (gcd % m)) (range (dec m) 0 -1))) 
) 
+0

это интересный трюк. благодаря – Yar

1

Расширенная комментарий:

  • filter ленив, поэтому lazy-seq является излишним в обоих случаях.
  • Не . Сделать possible-e функцией с аргументом m.

Таким образом мы получаем

(defn possible-e [m] 
    (filter #(= 1 (gcd % m)) (range 1 m))) 

(def m 38941629971148227236N) 

и

(defn possible-e [m] 
    (filter #(= 1 (gcd % m)) (reverse (range 1 m))))