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)))