diff --git a/src/sudoku.clj b/src/sudoku.clj index 5254c46..1077153 100644 --- a/src/sudoku.clj +++ b/src/sudoku.clj @@ -3,56 +3,108 @@ (def board identity) +(def all-values #{1 2 3 4 5 6 7 8 9}) + +(def all-indexes #{0 1 2 3 4 5 6 7 8}) + (defn value-at [board coord] - nil) + (get-in board coord)) (defn has-value? [board coord] - nil) + ((complement zero?) (value-at board coord))) (defn row-values [board coord] - nil) + (let [[row col] coord] + (set (map #(value-at board [row %]) + all-indexes)))) (defn col-values [board coord] - nil) + (let [[row col] coord] + (set (map #(value-at board [% col]) + all-indexes)))) -(defn coord-pairs [coords] - nil) +(defn coord-pairs [coord-sequence] + (for [row coord-sequence + col coord-sequence] + [row col])) (defn block-values [board coord] - nil) + (let [[row col] coord + reducer (fn [x] (if (== 0 (mod x 3)) + x + (recur (dec x)))) + [top left] [(reducer row) (reducer col)]] + (set (for [r [0 1 2] + c [0 1 2]] + (value-at board + [(+ top r) (+ left c)]))))) (defn valid-values-for [board coord] - nil) + (if (has-value? board coord) + #{} + (set/difference all-values (set/union (row-values board coord) + (col-values board coord) + (block-values board coord))))) (defn filled? [board] - nil) + (every? (partial has-value? board) + (for [row all-indexes + col all-indexes] + [row col]))) (defn rows [board] - nil) + (map (partial row-values board) + (for [row all-indexes] + [row 0]))) (defn valid-rows? [board] - nil) + (every? (partial = all-values) + (rows board))) (defn cols [board] - nil) + (map (partial col-values board) + (for [col all-indexes] + [0 col]))) (defn valid-cols? [board] - nil) + (every? (partial = all-values) + (cols board))) (defn blocks [board] - nil) + (map (partial block-values board) + (for [row [0 3 6] + col [0 3 6]] + [row col]))) (defn valid-blocks? [board] - nil) + (every? (partial = all-values) + (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) + (let [all-coords (coord-pairs all-indexes)] + (first (drop-while (partial has-value? board) + all-coords)))) + +(defn solve-helper [board] + (if (filled? board) + (if (valid-solution? board) + [board] + []) + (let [coord (find-empty-point board)] + (for [value (valid-values-for board coord) + solution (solve-helper (set-value-at board + coord + value))] + solution)))) (defn solve [board] - nil) + (first (solve-helper board))) +