diff --git a/.travis.yml b/.travis.yml index 455f3c0..45c29f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: clojure -lein: lein2 -script: lein2 midje :config .midje-grading-config.clj +lein: lein +script: lein midje :config .midje-grading-config.clj jdk: - openjdk7 notifications: diff --git a/src/sudoku.clj b/src/sudoku.clj index 5254c46..46c036d 100644 --- a/src/sudoku.clj +++ b/src/sudoku.clj @@ -3,56 +3,92 @@ (def board identity) +(def all-values #{1 2 3 4 5 6 7 8 9}) + (defn value-at [board coord] - nil) + (get-in board coord)) (defn has-value? [board coord] - nil) + (not (== 0 (value-at board coord)))) (defn row-values [board coord] - nil) + (let [[row _] coord] + (set (get board row)))) (defn col-values [board coord] - nil) + (let [[_ col] coord] + (set (map (fn [row] (get row col)) board)))) (defn coord-pairs [coords] - nil) + (vec (for [row coords + col coords] + [row col]))) -(defn block-values [board coord] - nil) +(defn block-coords [coord] + (cond + (<= coord 2) [0 1 2] + (<= coord 5) [3 4 5] + :else [6 7 8])) +(defn block-values [board coord] + (let [[row col] coord] + (set (for [x (block-coords row) + y (block-coords col)] + (value-at board [x y]))))) + (defn valid-values-for [board coord] - nil) + (if (has-value? board coord) + #{} + (let [used-values (set/union (row-values board coord) + (col-values board coord) + (block-values board coord))] + (set/difference all-values used-values)))) (defn filled? [board] - nil) + (let [all-coords (coord-pairs (range 9)) + board-values (set (map (fn [coord] (value-at board coord)) all-coords))] + (not (contains? board-values 0)))) (defn rows [board] - nil) - -(defn valid-rows? [board] - nil) + (map (fn [row] (row-values board [row 0])) (range 9))) (defn cols [board] - nil) - -(defn valid-cols? [board] - nil) + (map (fn [col] (col-values board [0 col])) (range 9))) (defn blocks [board] - nil) + (map (fn [coord] (block-values board coord)) (coord-pairs [0 3 6]))) + +(defn valid-sets? [sets] + (every? (fn [set] (= all-values set)) sets)) + +(defn valid-rows? [board] + (valid-sets? (rows board))) + +(defn valid-cols? [board] + (valid-sets? (cols board))) (defn valid-blocks? [board] - nil) + (valid-sets? (blocks board))) (defn valid-solution? [board] - nil) + (and (valid-rows? board) (valid-cols? board) (valid-blocks? board))) (defn set-value-at [board coord new-value] - nil) + (assoc-in board coord new-value)) (defn find-empty-point [board] - nil) + (loop [all-coords (coord-pairs (range 9))] + (let [coord (first all-coords)] + (if (not (has-value? board coord)) + coord + (recur (rest all-coords)))))) (defn solve [board] - nil) + (if (filled? board) + (if (valid-solution? board) + board + ()) + (let [empty-point (find-empty-point board)] + (for [possible-value (valid-values-for board empty-point) + solution (solve (set-value-at board empty-point possible-value))] + solution))))