1
\$\begingroup\$

I'd like to get the code below reviewed on all aspects, specifically I wonder if it's common usage to use let like this, as currently more computations are done in the let statement than in the rest of the code.

Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.

problems/problem6.clj

(ns project-euler.problems.problem6
  (:require [project-euler.shared :as shared]))

(defn sum-square-difference [n]
  {:pre [(number? n)]}
  (let [sum-squares (reduce + (map shared/square (range 1 (inc n))))
        square-sum (shared/square (reduce + (range 1 (inc n))))]
    (- square-sum sum-squares)))

(println (sum-square-difference 100))

shared.clj

(ns project-euler.shared
  (:require [clojure.math.numeric-tower :as math]))

(defn square [n]
  {:pre [(number? n)]}
  (math/expt n 2))
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

As in many of the euler problems, a formula can be derived in whole or part to speed up the runtime. In this case, the formulas below provide O(1) runtime. For this example it's trivial, but imagine it's the sum of the squares of the first 1 billion numbers. Since you are defining your own functions, as I am in my examples, I think it makes sense to provide the most efficient solution so that when these are used in later problems, they won't be a factor affecting performance.

Regarding the use of let, yes, it's often the case that you will bind what you need to in the let binding. You could actually get by with no let at all, but as I have done below and as you did, I think your code is clearer than if you had inlined everything.

(defn sum-of-squares
  "1^2 + 2^2 + 3^2 ... N^2   ==>   N*(N+1)*(2N+1)/6 "
  [n]
    (/ (* n (+ n 1) (+ 1 (* n 2))) 6))

(defn sum-of-naturals
  "1 + 2 + 3 ... N   ==>   N*(N+1)/2 "
  [n]
  (/ (* n (inc n)) 2))

(defn answer []
  (let [sum (sum-of-naturals 100)
        square-of-sum (* sum sum)
        sum-of-square (sum-of-squares 100)]
    (- square-of-sum sum-of-square)))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.