lxndio

Journal of my ideas, thoughts and projects.


Clojure: Generate perfect numbers

Today I am starting my Clojure series in this blog. From  now on I will occasionally take a problem and implement it in Clojure  for then describing to you how my solutions works.
Today I've came up with a functional solution in Clojure to calculate perfect numbers (which I also posted on Rosetta Code). [...] a perfect number is a positive integer that is equal to the sum  of its proper positive divisors, that is, the sum of its positive  divisors excluding the number itself [...] (Wikipedia 01.07.2016). But let's have a look at the solution (of which I am quite proud of by the way):  

(defn perfect? [n]
    (= (reduce + (filter #(zero? (rem n %)) (range 1 n))) n))

As you may be able to see this is just a function to check whether a  number is a perfect number or not. To print out a list of perfect  numbers you have to call this command (in the REPL or by putting it into  a new function):  

(doseq [i (range 1 1000000) :when (perfect? i)]
    (println i))

Today we will be analysing the function perfect?. As we can see here the basic thing perfect? does is checking whether its calculation equals the parameter n or not:  

(defn perfect? [n]
    (= CALCULATION n))

This calculation exists of the reduce function which applies a function, in this case + to each element in a list. That means that we add all elements in the list that is being created by (filter #(zero? (rem n %)) (range 1 n)) together.
The filter function creates a lazy sequence of all items in a list for which the given predicate is true. In this case #(zero? (rem n %)) is the predicate and it is being tested for true for all entries in (range 1 n) (a list from 1 to n-1). In English you could say the whole block like:  "Create a list of all numbers from 1 to n which do not produce a  remainder when being divided by n."
Now we have the list of all divisors of n except itself. All values of this list are being added using the reduce function. After checking whether the result is equal n you know whether n is a perfect number or not. Till then,
lxndio