| |
| | (ns e2-24-25-26-27-28-29
(:use clojure.test))
| | (deftest test-print-list
(is (= (list 1 (list 2 (list 3 4))) [1 [2 [3 4]]])))
| | (deftest test-get-7
(is (= (first (rest (first (rest (rest [1 3 [5 7] 9])))))
7))
(is (= (first (first [[7]]))
7))
; This is MADNESS!
; No! THIS! IS! DEEPLY NESTED LIST!
(is (= (first (rest (first (rest (first (rest (first (rest (first (rest (first (rest [1 [2 [3 [4 [5 [6 7]]]]]]))))))))))))
7)))
| | (def x [1 2 3])
(def y [4 5 6])
| | (deftest test-xy
; both arguments of (concat) are seqs
(is (= (concat x y) [1 2 3 4 5 6]))
; (cons) expects the first argument to be a value and the second - a seq
(is (= (cons x y) [[1 2 3] 4 5 6]))
; both arguments of (list) are values
(is (= (list x y) [[1 2 3] [4 5 6]])))
| | (defn deep-reverse [xs]
(if (empty? xs) nil
; sequential? returns true for VECTORS as well as for other seqs
; while seq? is false for VECTORS
(if (sequential? (first xs))
(concat (deep-reverse (rest xs)) [(deep-reverse (first xs))])
(concat (deep-reverse (rest xs)) [(first xs)]))))
| | (deftest test-deep-reverse
(is (= (deep-reverse [[1 2] [3 4]]) [[4 3] [2 1]])))
Flattens the given tree structure.
| | (defn fringe
[t]
(if (empty? t) nil
(if (sequential? (first t))
(concat (fringe (first t)) (fringe (rest t)))
(cons (first t) (fringe (rest t))))))
| | (deftest test-fringe
(is (= (fringe [[1 2] [3 4]]) [1 2 3 4]))
(is (= (fringe [[[1 2] [3 4]][[1 2] [3 4]]]) [1 2 3 4 1 2 3 4])))
| | (defn make-mobile [l r]
[l r])
| | (defn make-branch [len structure]
[len structure])
| | (defn left-branch [m]
(first m))
| | (defn right-branch [m]
(second m))
| | (defn branch-len [b]
(first b))
Returns either the mobile connected to this branch or the weigth of the branch
| | (defn branch-structure
[b]
(second b))
| | (defn weight? [b]
(number? b))
| | (defn branch-weight [b]
(letfn [(weight [b result]
(let [structure (branch-structure b)]
(if (weight? structure)
(+ result structure)
(+ (weight (left-branch structure) result) (weight (right-branch structure) result)))))]
(weight b 0)))
| | (defn total-weight [m]
(+ (branch-weight (left-branch m)) (branch-weight (right-branch m))))
| | (def *mob1* (make-mobile (make-branch 1 5) (make-branch 1 10)))
| | (def *mob2* (make-mobile (make-branch 1 5)
(make-branch 1 (make-mobile (make-branch 2 4)
(make-branch 1 4)))))
| | (def *mob3* (make-mobile (make-branch 4 5)
(make-branch 1 (make-mobile (make-branch 2 10)
(make-branch 2 10)))))
| | (deftest test-total-weight
(is (= (total-weight *mob1*) 15))
(is (= (total-weight *mob2*) (+ 5 4 4))))
I bumped into a difficulty while solving this problem, as I didn't really understand what it meant
for a binary mobile to be balanced. You need to calculate a torque not only for a branch which contains
the weight, but for the branches which contain sub-mobiles too. It may be obvious for you, but it wasn't
obvious for me.
| |
| | (defn torque [b]
(* (branch-weight b) (branch-len b)))
| | (def balanced?)
| | (defn branch-balanced? [b]
(let [structure (branch-structure b)]
(if (weight? structure) true
(balanced? structure))))
| | (defn balanced? [m]
(and (= (torque (left-branch m)) (torque (right-branch m)))
(branch-balanced? (left-branch m))
(branch-balanced? (right-branch m))))
| | (deftest test-balanced?
(is (not (balanced? *mob1*)))
(is (balanced? *mob3*)))
| |