(See the version sequence of the problem along with the lazy solution in the second update of this answer below.)
(defn square [n]
(* n n))
;; generalises easily to larger numbers of arguments
(defn sum-of-larger-squares [x y z]
(apply + (map square (take 2 (reverse (sort [x y z]))))))
;; shorter; generalises easily if you want
;; 'the sum of the squares of all numbers but n smallest'
(defn sum-of-larger-squares [x y z]
(apply + (map square (drop 1 (sort [x y z])))))
Update:
To expand on the comments above, the first generalized version for the version is:
(defn sum-of-larger-squares [n & xs]
(apply + (map square (take n (reverse (sort xs))))))
The second version simply summarizes the version that Arthur published meanwhile:
(defn sum-of-larger-squares [n & xs]
(apply + (map square (drop n (sort xs)))))
, , , SO... , , ( ). "" , , , , . , , .
2:
, (, ) . , :
(use 'clojure.contrib.seq-utils) ; recently renamed to clojure.contrib.seq
(defn moving-sum-of-smaller-squares [pred n nums]
(map first
(reductions (fn [[current-sum [x :as current-xs]] y]
(if (pred y x)
(let [z (peek current-xs)]
[(+ current-sum (- (* z z)) (* y y))
(vec (sort-by identity pred (conj (pop current-xs) y)))])
[current-sum
current-xs]))
(let [initial-xs (vec (sort-by identity pred (take n nums)))
initial-sum (reduce + (map
[initial-sum initial-xs])
(drop n nums))))
clojure.contrib.seq-utils ( c.c.seq) lib reductions. iterate , ( seq , , ).
:
user> (moving-sum-of-smaller-squares < 2 [9 3 2 1 0 5 3])
(90 13 5 1 1 1)
;; and to prove laziness...
user> (take 2 (moving-sum-of-smaller-squares < 2 (iterate inc 0)))
(1 1)
;; also, 'smaller' means pred-smaller here -- with
;; a different ordering, a different result is obtained
user> (take 10 (moving-sum-of-smaller-squares > 2 (iterate inc 0)))
(1 5 13 25 41 61 85 113 145 181)
, (moving-sum-of-smaller-squares pred n & nums) seq n seq , "pred-smallest" pred. pred= > n .
, , , , , , .
, ; , , seqs n , (, ).