diff --git a/src/sudoku.clj b/src/sudoku.clj index 5254c46..72a09f1 100644 --- a/src/sudoku.clj +++ b/src/sudoku.clj @@ -2,57 +2,95 @@ (: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= 0 (value-at board coord))) (defn row-values [board coord] - nil) + (let [[row col] coord] + (set (nth board row)))) (defn col-values [board coord] - nil) + (let [[row col] coord] + (set (map #(nth % col) board)))) (defn coord-pairs [coords] - nil) + (for [row coords, col coords] + [row col])) (defn block-values [board coord] - nil) + (let [[row col] coord + top (* 3 (quot row 3)) + left (* 3 (quot col 3))] + (set (for [r (range top (+ top 3)) + c (range left (+ left 3))] + (value-at board [r c]))))) (defn valid-values-for [board coord] - nil) + (if (has-value? board coord) + #{} + (set/difference all-values + (row-values board coord) + (col-values board coord) + (block-values board coord)))) (defn filled? [board] - nil) + (-> (mapcat identity board) + set + (contains? 0) + not + )) (defn rows [board] - nil) + (map set board)) (defn valid-rows? [board] - nil) + (every? #(= % all-values) (rows board))) (defn cols [board] - nil) + (->> (apply map vector board) + (map set))) (defn valid-cols? [board] - nil) + (every? #(= % all-values) (cols board))) (defn blocks [board] - nil) + (->> (map #(partition 3 %) board) + (partition 3) + (mapcat #(apply map concat %)) + (map set))) (defn valid-blocks? [board] - nil) + (every? #(= % 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) + (->> (for [r (range 9) + c (range 9)] + [r c]) + (filter #(not (has-value? board %))) + first + )) + +(defn solve-helper [board] + (if-let [ep (find-empty-point board)] + (->> (valid-values-for board ep) + (mapcat #(solve-helper (set-value-at board ep %)))) + (if (valid-solution? board) + [board] + nil + ))) (defn solve [board] - nil) + (first (solve-helper board)))