Home / Computer science / N-queens / Solve with home-grown SAT solver
Solution formatter
(defun my-queens-chess-position (variable size)
"Return a file-rank string for SOLUTION."
(let ((file (+ ?a (mod (1- variable) size)))
(rank (- size (/ (1- variable) size))))
(format "%c%d" file rank)))
(defun my-queens-chess-pieces (solution)
"Return a list of piece-file-rank strings for SOLUTION."
(let ((size (truncate (sqrt (length solution)))))
(mapcan (pcase-lambda (`(,variable . ,value))
(when (= value 1)
(list (concat "q" (my-queens-chess-position variable size)))))
solution)))
(defun my-queens-render-solution (solution)
"Return LaTeX source code that renders SOLUTION."
(let ((size (truncate (sqrt (length solution)))))
(format "\\chessboard[smallboard, maxfield=%s, setpieces={%s}]"
(my-queens-chess-position size size)
(string-join (sort (my-queens-chess-pieces solution)) ", "))))
(defun my-queens-render-solutions (solutions)
"Return LaTeX source code that renders SOLUTIONS."
(string-join
(append '("\\begin{flushleft}")
(mapcar (lambda (solution)
(concat " " (my-queens-render-solution solution)))
solutions)
'("\\end{flushleft}"))
"\n"))
(ert-deftest my-queens-render-solutions/size-2 ()
(should (equal (my-queens-render-solutions '(((1 . 1) (2 . 0)
(3 . 0) (4 . 1))))
"\\begin{flushleft}
\\chessboard[smallboard, maxfield=b2, setpieces={qa2, qb1}]
\\end{flushleft}")))
(ert-deftest my-queens-render-solutions/size-2/different ()
(should (equal (my-queens-render-solutions '(((1 . 0) (2 . 1)
(3 . 1) (4 . 0))))
"\\begin{flushleft}
\\chessboard[smallboard, maxfield=b2, setpieces={qa1, qb2}]
\\end{flushleft}")))
(ert-deftest my-queens-render-solutions/size-2/multiple ()
(should (equal (my-queens-render-solutions '(((1 . 1) (2 . 0)
(3 . 0) (4 . 1))
((1 . 0) (2 . 1)
(3 . 1) (4 . 0))))
"\\begin{flushleft}
\\chessboard[smallboard, maxfield=b2, setpieces={qa2, qb1}]
\\chessboard[smallboard, maxfield=b2, setpieces={qa1, qb2}]
\\end{flushleft}")))
(ert-deftest my-queens-render-solutions/size-3 ()
(should (equal (my-queens-render-solutions '(((1 . 0) (2 . 0) (3 . 0)
(4 . 0) (5 . 0) (6 . 0)
(7 . 0) (8 . 0) (9 . 1))))
"\\begin{flushleft}
\\chessboard[smallboard, maxfield=c3, setpieces={qc1}]
\\end{flushleft}")))