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..2e23144 100644 --- a/src/sudoku.clj +++ b/src/sudoku.clj @@ -2,57 +2,113 @@ (:require [clojure.set :as set])) (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 (zero? (get-in board coord)))) (defn row-values [board coord] - nil) + (set (get board (get coord 0)))) (defn col-values [board coord] - nil) + (set (map (fn [row] (get row (get coord 1))) board))) (defn coord-pairs [coords] - nil) + (for [row coords + column coords] + (vector row column))) + +(defn block-row [coord] + (cond + (contains? #{0 1 2} (get coord 0)) #{0 1 2} + (contains? #{3 4 5} (get coord 0)) #{3 4 5} + (contains? #{6 7 8} (get coord 0)) #{6 7 8})) + +(defn block-col [coord] + (cond + (contains? #{0 1 2} (get coord 1)) #{0 1 2} + (contains? #{3 4 5} (get coord 1)) #{3 4 5} + (contains? #{6 7 8} (get coord 1)) #{6 7 8})) (defn block-values [board coord] - nil) + (set (for [row (block-row coord) + column (block-col coord)] + (value-at board (vector row column))))) (defn valid-values-for [board coord] - nil) + (if (zero? (value-at board coord)) + (set/difference all-values + (set/union (row-values board coord) + (col-values board coord) + (block-values board coord))) + #{})) (defn filled? [board] - nil) + (not (contains? + (set (map (fn [coord] + (value-at board coord)) + (coord-pairs (range 0 9)))) + 0))) (defn rows [board] - nil) + (map (fn [row] + (row-values board [row 0])) + (range 0 9))) (defn valid-rows? [board] - nil) + (empty? (filter (fn [row] + (not= all-values row)) + (rows board)))) (defn cols [board] - nil) + (map (fn [column] + (col-values board [0 column])) + (range 0 9))) (defn valid-cols? [board] - nil) + (empty? (filter (fn [column] + (not= all-values column)) + (cols board)))) (defn blocks [board] - nil) + (for [row [0 3 6] + column [0 3 6]] + (block-values board (vector row column)))) (defn valid-blocks? [board] - nil) + (empty? (filter (fn [block] + (not= all-values block)) + (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 (fn [coord] + (zero? (value-at board coord))) + (for [row (range 0 9) + column (range 0 9)] + (vector row column))))) + +(defn board-solver [board solutions] + (let [empty-point (find-empty-point board)] + (if empty-point + (for [elem (valid-values-for board empty-point) + solution (board-solver + (set-value-at board empty-point elem) + solutions)] + solution) + (if (valid-solution? board) + (conj solutions board) + solutions)))) (defn solve [board] - nil) + (first (board-solver board [])))