NAME
Regexp::Sudoku - Solve Sudokus with regular expressions.
SYNOPSIS
use Regexp::Sudoku;
my $sudoku = Regexp::Sudoku:: -> new -> init
-> set_clues (<<~ '--');
5 3 . . 7 . . . .
6 . . 1 9 5 . . .
. 9 8 . . . . 6 .
8 . . . 6 . . . 3
4 . . 8 . 3 . . 1
7 . . . 2 . . . 6
. 6 . . . . 2 8 .
. . . 4 1 9 . . 5
. . . . 8 . . 7 9
--
my $subject = $sudoku -> subject;
my $pattern = $sudoku -> pattern;
if ($subject =~ $pattern) {
for my $row (1 .. 9) {
for my $col (1 .. 9) {
print $+ {"R${r}C${c}"}, " ";
}
print "\n";
}
}
DESCRIPTION
This module takes a Sudoku (or variant) as input, calculates a subject and pattern, such that, if the pattern is matched agains the subject, the match succeeds if, and only if, the Sudoku has a solution. And if it has a solution %+
is populated with the values of the cells of the solved Sudoku.
After constructing, initializing and constructing a Sudoku object using new
, init
and various set_*
methods (see below), the object can be queried with subject
and pattern
. subject
returns a string, while pattern
returns a pattern (as a string).
Once the subject has been matched against the pattern, 81 (or rather N ** 2
for an N x N
Sudoku) named captures will be set: R1C1
.. R1C9
.. R9C1
.. R9C9
. These correspond to the values of the cells of a solved Sudoku, where the cell in the top left is named R1C1
, the cell in the top right R1C9
, the cell in the bottom left R9C1
and the cell in the bottom right R9C9
. In general, the cell on row r
and column c
is named RrCc
. Named captures are available in %+
(see perlvar).
For regular, 9 x 9
Sudokus, one would just call new
, init
and set_clues
. Various variants need to call different methods.
Unless specified otherwise, all the methods below return the object it was called with; this methods can be chained.
Main methods
new ()
This is a class method called on the Regexp::Sudoku
package. It takes no arguments, and just returns an uninitialized object. (Basically, it just calls bless
for you).
init ()
init
initializes the Sudoku object. This method must be called on the return value of new
before calling any other methods.
init
takes one, optional, (named) argument.
size => INTEGER
-
Usually, Sudokus are
9 x 9
. For a Sudoku of a different size, we need to pass in the size. Smallest size for which Sudokus exist, is4
. Largest size we accept is35
. For a Sudoku with a size exceeding 9, we will letters as values. (So, for a12 x 12
Sudoku, we have1 .. 9, 'A', 'B'
as values.)The size directly influences the size of the boxes (the rectangles where each of the numbers appears exactly once). For a size
N
, the size of a box will be those integersp
andq
whereN = p * q
, and which minimizesabs (p - q)
. Common sizes lead to the following box sizes:size (N x N) | box size (width x height) =============+========================== 4 * | 2 x 2 6 | 3 x 2 8 | 4 x 2 9 * | 3 x 3 (Default) 10 | 5 x 2 12 | 4 x 3 15 | 5 x 3 16 * | 4 x 4 24 | 6 x 4 25 * | 5 x 5 30 | 6 x 5 35 | 7 x 5
Sizes which are perfect squares (marked with
*
in the table above) lead to square boxes.A size which is a prime number leads to boxes which are identical to rows -- you would need to configure different boxes.
set_clues (STRING | ARRAYREF)
The set_clues
method is used to pass in the clues (aka givens) of a Suduko. Most Sudokus will have at least one clue, but there are a few variants which allow clueless Sudokus. For a standard 9 x 9
Sudoku, the minimum amount of clues is 17.
The clues are either given as a string, or a two dimensional arrayref.
In the case of a string, rows are separated by newlines, and values in a row by whitespace. The first line of the string corresponds with the first row of the Sudoku, the second line with the second row, etc. In each line, the first value corresponds with the first cell of that row, the second value with the second cell, etc. In case of an arrayref, the array consists of arrays of values. Each array corresponds with a row, and each element of the inner arrays corresponds with a cell.
The values have the following meaning:
'1' .. '9', 'A' .. 'Z'
-
This corresponds to a clue/given in the corresponding cell. For standard Sudokus, we use
'1' .. '9'
. Smaller Sudokus use less digits. For Sudokus greater than9 x 9
, capital letters are used, up to'Z'
for a35 x 35
Sudoku. '.'
,0
,""
,undef
-
These values indicate the Sudoku does not have a clue for the corresponding cell: the cell is blank.
""
andundef
can only be used if the array form is being used. 'e'
-
This indicates the cell should have an even number in its solution. (Note that
'E'
indicates a clue (if the size is at least15 x 15
), and is different from'e'
). 'o'
-
This indicates the cell should have an odd number in its solution. (Note that
'O'
indicates a clue (if the size is at least25 x 25
), and is different from'o'
).
Additional Houses
A house is a region which contains each of the numbers 1 .. 9
(or 1 .. N
for an N x N
sized Sudoku) exactly once. With a standard Sudoku, each row, each column, and each 3 x 3
box is a house.
Some variants have additional houses, next to the rows, columns and boxes. In this section, we describe the methods which can be used to configure the Sukodu to have additional houses.
set_nrc_houses ()
An NRC Sudoku has four additional houses, indicated below with the numbers 1 .. 4
. This variant is only defined for 9 x 9
Sudokus:
. . . . . . . . .
. 1 1 1 . 2 2 2 .
. 1 1 1 . 2 2 2 .
. 1 1 1 . 2 2 2 .
. . . . . . . . .
. 3 3 3 . 4 4 4 .
. 3 3 3 . 4 4 4 .
. 3 3 3 . 4 4 4 .
. . . . . . . . .
Calling the set_nrc_houses ()
sets up those houses.
The NRC Sudoku is named after the Dutch newspaper NRC, which first publishes such a Sudoku and still publishes one daily. It is also known under the names Windoku and Hyper Sudoku.
set_asterisk_house ()
An asterisk Sudoku has an additional house, roughly in the shape of an asterisk, as indicated below. This variant is only defined for 9 x 9
Sudokus:
. . . . . . . . .
. . . . * . . . .
. . * . . . * . .
. . . . . . . . .
. * . . * . . * .
. . . . . . . . .
. . * . . . * . .
. . . . * . . . .
. . . . . . . . .
Calling the set_asterisk_house ()
sets up those houses.
set_girandola_house ()
An girandola Sudoku has an additional house, roughly in the shape of a windmill pinwheel (a childs toy), as indicated below. This variant is only defined for 9 x 9
Sudokus:
* . . . . . . . *
. . . . * . . . .
. . . . . . . . .
. . . . . . . . .
. * . . * . . * .
. . . . . . . . .
. . . . . . . . .
. . . . * . . . .
* . . . . . . . *
Calling the set_girandola_house ()
sets up those houses.
set_center_dot_house ()
A center dot house is an additional house which consists of all the center cell of all the boxes. This is only defined for Sudokus where the boxes have odd sizes. (Sizes 9
, 15
, 25
, and 35
; see the table with sizes above). For a 9 x 9
Sudoku, this looks like:
. . . . . . . . .
. * . . * . . * .
. . . . . . . . .
. . . . . . . . .
. * . . * . . * .
. . . . . . . . .
. . . . . . . . .
. * . . * . . * .
. . . . . . . . .
Calling the set_center_dot_house ()
sets up those houses.
Diagonals
A common constraint used in variant Sudokus is uniqueness of one or more diagonals: all the values on each of the marked diagonals should be unique.
The main diagonal of a Sudoku is the diagonal which runs from the top left to the bottom right. The minor diagonal the diagonal which runs from the top right to the bottom left.
\ . . . . . . . . . . . . . . . . /
. \ . . . . . . . . . . . . . . / .
. . \ . . . . . . . . . . . . / . .
. . . \ . . . . . . . . . . / . . .
. . . . \ . . . . . . . . / . . . .
. . . . . \ . . . . . . / . . . . .
. . . . . . \ . . . . / . . . . . .
. . . . . . . \ . . / . . . . . . .
. . . . . . . . \ / . . . . . . . .
Main Diagonal Minor Diagonal
A super diagonal is a diagonal which parallel and above of the main or minor diagonal. A sub diagonal is a diagonal which runs parallel and below the main or minor diagonal. Super and sub diagonals have an offset, indicating their distance from the main or minor diagonal. The super and sub diagonal directly next to the main and minor diagonals have an offset of 1. The maximum offset for an N x N
Sudoku is N - 1
, although such an offset reduces the diagonal to a single cell.
. \ . . . . . . . . . . . . . . / .
. . \ . . . . . . . . . . . . / . .
\ . . \ . . . . . . . . . . / . . /
. \ . . \ . . . . . . . . / . . / .
. . \ . . \ . . . . . . / . . / . .
. . . \ . . \ . . . . / . . / . . .
. . . . \ . . \ . . / . . / . . . .
. . . . . \ . . \ / . . / . . . . .
. . . . . . \ . . . . / . . . . . .
Super and sub diagonals Super and sub diagonals
off the main diagonal off the minor diagonal
In total, an N x N
Sudoku can have 4 * N - 2
diagonals (34 for a standard 9 x 9
Sudoku).
There will be a method to set uniqness for each possible diagonal.
set_diagonal_main ()
This method sets a uniqness constraint on the main diagonal.
set_diagonal_minor ()
This method sets a uniqness constraint on the minor diagonal.
set_diagonal_main_super_1 () .. set_diagonal_main_super_34 ()
These methods set uniqness constraints on super diagonals parallel to the main diagonal, with the given offset. If the offset equals or exceeds the size of the Sudoku, the diagonal falls completely outside of the Sudoku, and hence, does not add a constraint.
set_diagonal_main_sub () .. set_diagonal_main_sub ()
These methods set uniqness constraints on sub diagonals parallel to the main diagonal, with the given offset. If the offset equals or exceeds the size of the Sudoku, the diagonal falls completely outside of the Sudoku, and hence, does not add a constraint.
set_diagonal_minor_super_1 () .. set_diagonal_minor_super_34 ()
These methods set uniqness constraints on super diagonals parallel to the minor diagonal, with the given offset. If the offset equals or exceeds the size of the Sudoku, the diagonal falls completely outside of the Sudoku, and hence, does not add a constraint.
set_diagonal_minor_sub () .. set_diagonal_minor_sub ()
These methods set uniqness constraints on sub diagonals parallel to the minor diagonal, with the given offset. If the offset equals or exceeds the size of the Sudoku, the diagonal falls completely outside of the Sudoku, and hence, does not add a constraint.
Crosses and other diagonal sets
It is quite common for variants which have constraints on diagonals to do so in a symmetric fashion. To avoid having to call multiple set_diagonal_*
methods, we provide a bunch of wrappers which set uniqness constraints on two or more diagonals.
set_cross ()
A common variant has uniqness constraints for both the main and minor diagonal -- this variant is widely known under the name X-Sudoku. set_cross ()
sets the uniqness constraints for both the main and minor diagonals:
\ . . . . . . . /
. \ . . . . . / .
. . \ . . . / . .
. . . \ . / . . .
. . . . X . . . .
. . . / . \ . . .
. . / . . . \ . .
. / . . . . . \ .
/ . . . . . . . \
Cross constraints
set_cross_1 () .. set_cross_34 ()
Each of the set_cross_N ()
methods enable a uniqness constraint on four diagonals: the super and sub diaganols (relative to both the main and minor diagonals) with offset N
. Note that if N
is equal, or exceeds the size of the Sudoku, all the diagonals lie fully outside the Sudoku, rendering the method useless.
set_diagonal_double ()
This method enables a uniqness constraints on the diagonals parallel, and directly next to the main and minor diagonals. This is method is equivalent to set_cross_1
.
. \ . . . . . / .
\ . \ . . . / . /
. \ . \ . / . / .
. . \ . X . / . .
. . . X . X . . .
. . / . X . \ . .
. / . / . \ . \ .
/ . / . . . \ . \
. / . . . . . \ .
Diagonal Double
set_diagonal_triple ()
This methods enables uniqness constraints on six diagonals: the main and minor diagonals, and the diagonals parallel to them, and directly next to them. Calling this method is equivalent to calling both set_cross ()
and set_diagonal_double ()
.
\ \ . . . . . / /
\ \ \ . . . / / /
. \ \ \ . / / / .
. . \ X X X / . .
. . . X X X . . .
. . / X X X \ . .
. / / / . \ \ \ .
/ / / . . . \ \ \
/ / . . . . . \ \
Diagonal Triple
set_argyle ()
The Argyle Sudoku variant has uniqness constraints on eight diagonals. This is named after a pattern consisting of lozenges, which itself was named after the tartans of the Clan Cambell in Argyll in the Scottish highlands.
Calling set_argyle ()
is equivalent to calling set_cross_1 ()
and set_cross_4 ()
.
. \ . . ^ . . / .
\ . \ / . \ / . /
. \ / \ . / \ / .
. / \ . X . / \ .
< . . X . X . . >
. \ / . X . \ / .
. / \ / . \ / \ .
/ . / \ . / \ . \
. / . . V . . \ .
Argyle Pattern
Global constraints
There are Sudoku variants which enable specific constraints on all the cells in the Sudoku.
set_anti_knight_constraint ()
An anti knight constraint implies that two cells which are a knights move (as in classical Chess) apart must have different values. (A knights move is first two cells in an orthognal direction, then one cell perpendicular). For each cell, this puts a restriction to up to eight different cells. In the diagram below, *
marks all the cells which are a knights move away from the cell marked O
.
. . . . . . . . .
. . . . . . . . .
. . * . * . . . .
. * . . . * . . .
. . . O . . . . .
. * . . . * . . .
. . * . * . . . .
. . . . . . . . .
. . . . . . . . .
Anti Knight Constraint
set_anti_king_constraint ()
Also known as the no touch constraint.
An anti king constraint implies that two cells which are a kings move (as in classical Chess) apart must have different values. (A kings move is one step in any of the eight directions).
For each cell, this puts a restriction to up to eight different cells. Four of them are already restricted because they are one the same row or columns. And at least one kings move will end in the same box. So, this restriction is far less restrictive than the anti knights move restriction.
In the diagram below, *
marks all the cells which are a kings move away from the cell marked O
.
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . * * * . . . .
. . * O * . . . .
. . * * * . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Anti King Constraint
Retricted lines and areas
set_renban (LIST)
A Renban line (or area) consist of a number of cells where all the values should form a consecutive sets of numbers. The numbers do not have to be in order. For example, a Renban area of size four may contain the numbers 5-7-4-6
or 2-3-4-5
, but not 2-3-5-6
.
This method takes a list of cell names as argument, where each name is of the form RxCy
, with 1 <= x, y <= N
, where N
is the size of the Sudoku.
No validation of cell names is performed. Names which aren't of the form RxCy
, or which are outside of the Sudoku have no effect. A Renban area with more cells than the size of the Sudoku leads to an unsolvable Sudoku.
This method can be called more than once, and should be called more than once if a Sudoku has more than one Renban line/area.
BUGS
There are no known bugs.
TODO
Disjoint Groups
Jigsaw
Battenburg
Greater Than
Thermo
Slow Thermo
Rossini
Consecutive Sudoku
Non-consecutive Sudoku
Kropki
Absolute difference = 1
Other differences
Ratio 1:2
Other ratios
XV Sudoku
CL Sudoku
Outsize Sudoku
Young Tableaux
Palindromes
Renban lines
Nabner
German Whisper
Clones
Quadruple
Killer Sudoku
Little Killer Sudoku
Frame Sudoku
Arrow Sudoku
Sandwich
Clock Sudoku
SEE ALSO
DEVELOPMENT
The current sources of this module are found on github, git://github.com/Abigail/Regexp-Sudoku.git.
AUTHOR
Abigail, mailto:cpan@abigail.freedom.nl.
COPYRIGHT and LICENSE
Copyright (C) 2021-2022 by Abigail.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
INSTALLATION
To install this module, run, after unpacking the tar-ball, the following commands:
perl Makefile.PL
make
make test
make install