/ / Обобщаващ Clojure решение на Euler # 1 - clojure, функционално програмиране

Обобщаващо решение на Clojure за Euler # 1 - clojure, функционално програмиране

Q = Намерете сумата на всички кратни на 3 или 5 под 1000.

Най-прост отговор

(reduce + (filter #(or (== (mod % 3) 0) (== (mod % 5) 0)) (range 1000)))

Опитвате се за общ отговор като следване

(reduce + (list-nums-divisible-by-all-divisors N div1 div2 ...))
(defn list-nums-divisible-by-all-divisors
[num & divisors]
(let [myfn (create-fn divisors)]
(filter myfn (range num))))

Ето създаване-fn за 2 делителя

(defn create-fn
[div1 div2]
#(or (== (mod % div1) 0) (== (mod % div2) 0)))

Как да напиша create-fn за променлив брой делители?

Това ли е правилният подход за справяне с това? Имам чувството, че вероятно бих използвал оператора -> или - >> вместо този начин.

Също така мисля, че това се превръща в общ въпрос. Може ли човек да създаде и върне функция, използвайки променлив брой аргументи, които след това могат да бъдат използвани като анонимна функция (с друго ниво на аргументи)?

Благодаря предварително :-)

Отговори:

2 за отговор № 1

Препоръчвам да отидете малко по-подробно, да изградите няколко предикати и след това да ги комбинирате, като използвате every-pred, Тази функция изгражда един предикат от няколко, доста удобно.

Първо, започнете с функция за делимост:

(defn divisible-by? [n]
(fn [x]
(zero? (rem x n))))

Кърингът просто означава, че за да имаме функция "вземаща два аргумента", първо приемаме един аргумент и след това изграждаме функция, която взема втория аргумент. Те се използват като

((divisible-by? 3) 6) ;;-> true

В този случай искаме това поведение, защото искаме map функция, която създава унарни предикати, като така:

(defn create-fn [divisors]
(apply every-pred (map divisible-by? divisors)))