# Sudoku & Mathematica - Part I Visualization

1506 Views
|
0 Replies
|
4 Total Likes
|
 A quick search on GitGub shows more than 20k repositories for the query "sudoku".There are many Mathematica packages that attempt to solve a Sudoku. But, many of those approaches don't fully utilize all Mathematica capabilities. In special: Pattern Matching and Boxes.Boxes are a very useful concept since it helps us build custom notation. See for example Dirac's Bra-Ket notation and Einstein "summation" notation. Although simple "notations" per se, they have helped gain further insight and made things clearly easier.Since Mathematica has this 2D-input functionality, we should use it, thus making the code and experience less clunky.In this Part I, I'll show how to easily create this new notation using MakeBoxes. The Notebook to follow along is attached.We'll first create two functions: SudokuMatrixQ and SudokuMaskQ, that tests if a given sudoku-matrix/mask is valid, where a mask is a matrix that separates the grid into groups, which will be shown later. SudokuMatrixQ[square:{{__Integer}..}] := (SquareMatrixQ@square) && (Min@square >= 0) && (Max@square <= Length@square) SudokuMatrixQ[___] := False SudokuMaskQ[mask:{{0..}..}] := SquareMatrixQ@mask SudokuMaskQ[mask_?SudokuMatrixQ] := Function[list, (* The masked elements need to be equal-sized *) Equal[##1, Length@mask] & @@ MinMax@list ][ (* The number of times a element appears *) Last /@ Tally@DeleteCases[Flatten@mask, 0] ] SudokuMaskQ[___] := False Since in StandardForm, matrices are now shown as matrices, but rather as 1D input. Let's fix this: Sudoku /: MakeBoxes[Sudoku[square_?SudokuMatrixQ, mask_?SudokuMaskQ], StandardForm] := Module[{gridBox}, gridBox = RowBox@{"(", GridBox@#, ")"} &; TemplateBox[{ gridBox@Map[ToBoxes, square, {2}], gridBox@Map[ToBoxes, mask, {2}] }, "Sudoku", DisplayFunction :> (RowBox@{"Sudoku", "[", #1, "]"} &), InterpretationFunction :> (RowBox@{"Sudoku", "[", RowBox@{#1, ",", #2}, "]"} &), Tooltip -> Automatic ] ] Where the contents of the matrix can be editable and the mask-matrix is hidden, for visualization purposes. Sudoku /: MakeBoxes[Sudoku[square_?SudokuMatrixQ, mask_?SudokuMaskQ], TraditionalForm] := Module[{n = Length@square, pos}, TemplateBox[{GridBox[ Map[ToBoxes, square, {2}] /. "0" -> StyleBox["\[CenterDot]", GrayLevel[0.65]], GridBoxAlignment -> {"Columns" -> {{Center}}, "Rows" -> {{Center}}}, GridBoxFrame -> {"ColumnsIndexed" -> {{{1, -1}, {1, -1}} -> True}}, GridBoxItemSize -> {}, ColumnsEqual -> True, RowsEqual -> True, GridBoxBackground -> {"Columns" -> {{GrayLevel[0.9]}}, "Rows" -> {{GrayLevel[0.9]}}, "ItemsIndexed" -> Flatten@Table[pos = Position[mask, i]; If[Length@pos == 0, Nothing, Thread[pos -> Opacity[0.7, Blend[{RGBColor[0.43, 0.98, 1], RGBColor[ 0.73, 0.89, 0.42], RGBColor[1, 0.57, 0.33], RGBColor[0.69, 0.54, 0.80]}, (i - 1)/(n - 1)]]]] , {i, n}]}], ToBoxes@square, ToBoxes@mask }, "Sudoku", DisplayFunction :> (#1 &), InterpretationFunction :> (RowBox@{"Sudoku", "[", RowBox@{#2, ",", #3}, "]"} &), Editable -> False, Selectable -> False, Tooltip -> Automatic ] ] Which gives a very nice representation of the puzzle for arbitrary masks. Attachments: Answer