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..d4c9b95 100644 --- a/src/sudoku.clj +++ b/src/sudoku.clj @@ -3,56 +3,88 @@ (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) + (<= 1 (value-at board coord))) -(defn row-values [board coord] - nil) +(defn row-values [board [y _]] + (set (map #(value-at board [y %]) (range 9)))) -(defn col-values [board coord] - nil) +(defn col-values [board [_ x]] + (set (map #(value-at board [% x]) (range 9)))) -(defn coord-pairs [coords] - nil) +(defn coord-pairs [dimensions] + (for [pair-x dimensions + pair-y dimensions] + [pair-x pair-y])) -(defn block-values [board coord] - nil) +(defn block-values [board [y x]] + (let [top-left-x (* 3 (int (/ x 3))) + top-left-y (* 3 (int (/ y 3))) + coord-offsets (coord-pairs [0 1 2]) + block-coords (map (fn [[y x]] + [(+ y top-left-y) (+ x top-left-x)]) + coord-offsets)] + (set (map #(value-at board %) block-coords)))) (defn valid-values-for [board coord] - nil) + (if (has-value? board coord) + #{} + (set/difference + all-values + (block-values board coord) + (row-values board coord) + (col-values board coord)))) (defn filled? [board] - nil) + (every? #(>= % 1) + (map #(value-at board %) (coord-pairs (range 9))))) (defn rows [board] - nil) + (map #(row-values board [% 0]) (range 9))) (defn valid-rows? [board] - nil) + (every? #(= 9 (count %)) (rows board))) (defn cols [board] - nil) + (map #(col-values board [0 %]) (range 9))) (defn valid-cols? [board] - nil) + (every? #(= 9 (count %)) (cols board))) (defn blocks [board] - nil) + (map #(block-values board %) + [[0 0] [0 3] [0 6] + [3 0] [3 3] [3 6] + [6 0] [6 3] [6 6]])) (defn valid-blocks? [board] - nil) + (every? #(= 9 (count %)) (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) + (first (filter #(zero? (value-at board %)) + (coord-pairs (range 9))))) (defn solve [board] - nil) + (cond + (and (filled? board) (valid-solution? board)) + board + (filled? board) + '() + :else + (for [empty-point [(find-empty-point board)] + possible-value (valid-values-for board empty-point) + solution (solve (set-value-at board empty-point possible-value))] + solution)))