]> git.rkrishnan.org Git - sicp.git/blob - src/sicp/ex2_42.clj
Solution to 4.33. This had been difficult to get right, though conceptually it was
[sicp.git] / src / sicp / ex2_42.clj
1 (ns sicp.ex2_42
2   (:use [sicp.ch2-2 :only (enumerate-interval accumulate append flatmap)]))
3
4 (declare safe? empty-board adjoin-position)
5
6 (defn queens [board-size]
7   (let [f (fn queen-cols [k]
8             (if (= k 0)
9               (list empty-board)
10               (filter
11                (fn [positions] (safe? k positions))
12                (flatmap
13                 (fn [rest-of-queens]
14                   (map (fn [new-row]
15                          (adjoin-position new-row k rest-of-queens))
16                        (enumerate-interval 1 board-size)))
17                 (queen-cols (- k 1))))))]
18     (f board-size)))
19
20 (def empty-board nil)
21
22 (defn adjoin-position [row col pos]
23   (cons row pos))
24
25 (defn get-row [pos]
26   (first pos))
27
28 (defn safe? [col positions]
29   (loop [this-row (first positions)
30          pos      (rest positions)
31          offset  1]
32     (if (empty? pos)
33       true
34       (let [new-row (first pos)]
35         (if (or (= this-row new-row)
36                 (= (+ this-row offset) new-row)
37                 (= (- this-row offset) new-row))
38           false
39           (recur this-row (rest pos) (inc offset)))))))