Davide Taviani / Jul 23 2021 / Published
Remix of Clojure by Nextjournal
Solving sudokus using core.logic
{:deps {org.clojure/clojure {:mvn/version "1.10.1"}
org.clojure/core.logic {:mvn/version "1.0.0"}}}
Extensible Data Notation
This notebook is directly from the Examples of core.logic wiki
(ns sudoku
(:refer-clojure :exclude [==])
(:use clojure.core.logic)
(:require [clojure.core.logic.fd :as fd]))
(defn get-square [rows x y]
(for [x (range x (+ x 3))
y (range y (+ y 3))]
(get-in rows [x y])))
(defn bind [var hint]
(if-not (zero? hint)
(== var hint)
succeed))
(defn bind-all [vars hints]
(and* (map bind vars hints)))
(defn sudokufd [hints]
(let [vars (repeatedly 81 lvar)
rows (->> vars (partition 9) (map vec) (into []))
cols (apply map vector rows)
sqs (for [x (range 0 9 3)
y (range 0 9 3)]
(get-square rows x y))]
(run 1 [q]
(== q vars)
(everyg (fd/in % (fd/domain 1 2 3 4 5 6 7 8 9)) vars)
(bind-all vars hints)
(everyg fd/distinct rows)
(everyg fd/distinct cols)
(everyg fd/distinct sqs))))
(def hints
[2 0 7 0 1 0 5 0 8
0 0 0 6 7 8 0 0 0
8 0 0 0 0 0 0 0 6
0 7 0 9 0 6 0 5 0
4 9 0 0 0 0 0 1 3
0 3 0 4 0 1 0 2 0
5 0 0 0 0 0 0 0 1
0 0 0 2 9 4 0 0 0
3 0 6 0 8 0 4 0 9])
;; Print the solution
(->> (sudokufd hints)
(first)
(partition-all 9)
(clojure.pprint/pprint))
6.6s