File Coverage

blib/lib/Games/Sudoku/General.pm
Criterion Covered Total %
statement 675 905 74.5
branch 224 428 52.3
condition 63 125 50.4
subroutine 53 59 89.8
pod 13 13 100.0
total 1028 1530 67.1


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Games::Sudoku::General - Solve sudoku-like puzzles.
4              
5             =head1 SYNOPSIS
6              
7             $su = Games::Sudoku::General->new ();
8             print $su->problem(<solution();
9             3 . . . . 8 . 2 .
10             . . . . . 9 . . .
11             . . 2 7 . 5 . . .
12             2 4 . 5 . . 8 . .
13             . 8 5 . 7 4 . . 6
14             . 3 . . . . 9 4 .
15             1 . 4 . . . . 7 2
16             . . 6 9 . . . 5 .
17             . 7 . 6 1 2 . . 9
18             eod
19              
20             =head1 DESCRIPTION
21              
22             This package solves puzzles that involve the allocation of symbols
23             among a number of sets, such that no set contains more than one of
24             any symbol. This class of problem includes the puzzles known as
25             'Sudoku', 'Number Place', and 'Wasabi'.
26              
27             Each Sudoku puzzle is considered to be made up of a number of cells,
28             each of which is a member of one or more sets, and each of which may
29             contain exactly one symbol. The contents of some of the cells are
30             given, and the problem is to deduce the contents of the rest of the
31             cells.
32              
33             Although such puzzles as Sudoku are presented on a square grid, this
34             package does not assume any particular geometry. Instead, the topology
35             of the puzzle is defined by the user in terms of a list of the sets
36             to which each cell belongs. Some topology generators are provided, but
37             the user has the option of hand-specifying an arbitrary topology.
38              
39             Even on the standard 9 x 9 Sudoku topology there are variants in which
40             unspecified cells are constrained in various ways (odd/even, high/low).
41             Such variants are accommodated by defining named sets of allowed
42             symbols, and then giving the set name for each unoccupied cell to which
43             it applies. See the C attribute for more
44             information and an example.
45              
46             This module is able not only to solve a variety of Sudoku-like
47             puzzles, but to 'explain' how it arrived at its solution. The
48             steps() method, called after a solution is generated, lists in order
49             what solution constraints were applied, what cell each constraint
50             is applied to, and what symbol the cell was constrained to.
51              
52             Test script t/sudoku.t demonstrates these features. ActivePerl users
53             will have to download the kit from L or
54             L to get this
55             file.
56              
57             =head2 Exported symbols
58              
59             No symbols are exported by default, but the following things are
60             available for export:
61              
62             Status values exported by the :status tag
63             SUDOKU_SUCCESS
64             This means what you think it does.
65             SUDOKU_NO_SOLUTION
66             This means the method exhausted all possible
67             soltions without finding one
68             SUDOKU_TOO_HARD
69             This means the iteration_limit attribute was
70             set to a positive number and the solution()
71             method hit the limit without finding a solution.
72              
73             The :all tag is provided for convenience, but it exports the same
74             symbols as :status.
75              
76             =head2 Attributes
77              
78             Games::Sudoku::General objects have the following attributes, which may
79             normally be accessed by the get() method, and changed by the set()
80             method.
81              
82             In parentheses after the name of the attribute is the word "boolean",
83             "number" or "string", giving the data type of the attribute. Booleans
84             are interpreted in the Perl sense: undef, 0, and '' are false, and
85             anything else is true. The parentheses may also contain the words
86             "read-only" to denote a read-only attribute or "write-only" to denote
87             a write-only attribute.
88              
89             In general, the write-only attributes exist as a convenience to the
90             user, and provide a shorthand way to set a cluster of attributes at
91             the same time. At the moment all of them are concerned with generating
92             problem topologies, which are a real pain to specify by hand.
93              
94             =over
95              
96             =item allowed_symbols (string)
97              
98             This attribute names and defines sets of allowed symbols which may
99             appear in empty cells. The set definitions are whitespace-delimited
100             and each consists of a string of the form 'name=symbol,symbol...'
101             where the 'name' is the name of the set, and the symbols are a list
102             of the symbols valid in a cell to which that set applies.
103              
104             For example, if you have an odd/even puzzle (i.e. you are given that
105             at least some of the unoccupied cells are even or odd but not both),
106             you might want to
107              
108             $su->set (allowed_symbols => <
109             o=1,3,5,7,9
110             e=2,4,6,8
111             eod
112              
113             and then define the problem like this:
114              
115             $su->problem (<
116             1 o e o e e o e 3
117             o o e o 6 e o o e
118             e e 3 o o 1 o e e
119             e 7 o 1 o e e o e
120             o e 8 e e o 5 o o
121             o e o o e 3 e 4 o
122             e o o 8 o o 6 o e
123             o o o e 1 e e e o
124             6 e e e o o o o 7
125             eod
126              
127             To eliminate an individual allowed symbol set, set it to an empty
128             string (e.g. $su->set (allowed_symbols => 'o=');). To eliminate all
129             symbol sets, set the entire attribute to the empty string.
130              
131             Allowed symbol set names may not conflict with symbol names. If you set
132             the symbol attribute, all allowed symbol sets are deleted, because
133             that seemed to be the most expeditious way to enforce this restriction
134             across a symbol set change.
135              
136             Because symbol set names must be parsed like symbol names when a
137             problem is defined, they also affect the need for whitespace on
138             problem input. See the L documentation for
139             full details.
140              
141             =item autocopy (boolean)
142              
143             If true, this attribute causes the generate() method to implicitly call
144             copy() to copy the generated problem to the clipboard.
145              
146             This attribute is false by default.
147              
148             =item brick (string, write-only)
149              
150             This "virtual" attribute is a convenience, which causes the object to be
151             configured with a topology of rows, columns, and rectangles. The value
152             set must be either a comma-separated list of two numbers (e.g. '3,2')
153             or a reference to a list containing two numbers (e.g. [3, 2]). Either
154             way, the numbers represent the horizontal dimension of the rectangle (in
155             columns) and the vertical dimension of the rectangle (in rows). The
156             overall size of the puzzle square is the product of these. For example,
157              
158             $su->set( brick => [ 3, 2 ] )
159              
160             generates a topology that looks like this
161              
162             +-------+-------+
163             | x x x | x x x |
164             | x x x | x x x |
165             +-------+-------+
166             | x x x | x x x |
167             | x x x | x x x |
168             +-------+-------+
169             | x x x | x x x |
170             | x x x | x x x |
171             +-------+-------+
172              
173             Originally there was a third argument giving the total size of the
174             puzzle. Beginning with version 0.006 this was deprecated, since it
175             appeared to me to be redundant. As of version 0.021, all uses of this
176             argument resulted in a warning. As of version 0.022, use of the third
177             argument will become fatal.
178              
179             Setting this attribute modifies the following "real" attributes:
180              
181             columns is set to the size of the big square;
182             symbols is set to "." and the numbers "1", "2",
183             and so on, up to the size of the big square;
184             topology is set to represent the rows, columns,
185             and small rectangles in the big square, with row
186             sets named "r0", "r1", and so on, column sets
187             named "c0", "c1", and so on, and small
188             rectangle sets named "s0", "s1", and so on for
189             historical reasons.
190              
191             =item columns (number)
192              
193             This attribute defines the number of columns of data to present in a
194             line of output when formatting the topology attribute, or the solution
195             to a puzzle.
196              
197             =item corresponding (number, write-only)
198              
199             This "virtual" attribute is a convenience, which causes the object
200             to be configured for "corresponding-cell" Sudoku. The topology is
201             the same as C ... )>, but in addition corresponding
202             cells in the small squares must have different values. The extra set
203             names are "u0", "u1", and so on.
204              
205             This kind of puzzle is also called "disjoint groups."
206              
207             =item cube (string, write-only)
208              
209             This "virtual" attribute is a convenience, which causes the object to
210             be configured for cubical sudoku. The string is either a number, or
211             'full', or 'half'.
212              
213             * a number sets the topology to a Dion cube of the given order.
214             That is,
215              
216             sudokug> set cube 3
217              
218             generates a 9 x 9 x 9 Dion cube, with the small squares being 3 x 3.
219             The problem is entered in plane, row, and column order, as though you
220             were entering the required number of normal Sudoku puzzles
221             back-to-back.
222              
223             * 'full' generates a topology that includes all faces of the cube. The
224             sets are the faces of the cube, and the rows, columns, and (for lack
225             of a better word) planes of cells that circle the cube.
226              
227             To enter the problem, imagine the cube unfolded to make a Latin cross.
228             Then, enter the problem in order by faces, rows, and columns, top to
229             bottom and left to right. The order of entry is actually by cell
230             number, as given below.
231              
232             +-------------+
233             | 0 1 2 3 |
234             | 4 5 6 7 |
235             | 8 9 10 11 |
236             | 12 13 14 15 |
237             +-------------+-------------+-------------+
238             | 16 17 18 19 | 32 33 34 35 | 48 49 50 51 |
239             | 20 21 22 23 | 36 37 38 39 | 52 53 54 55 |
240             | 24 25 26 27 | 40 41 42 43 | 56 57 58 59 |
241             | 28 29 30 31 | 44 45 46 47 | 60 61 62 63 |
242             +-------------+-------------+-------------+
243             | 64 65 66 67 |
244             | 68 69 70 71 |
245             | 72 73 74 75 |
246             | 76 77 78 79 |
247             +-------------+
248             | 80 81 82 83 |
249             | 84 85 86 87 |
250             | 88 89 90 91 |
251             | 92 93 94 95 |
252             +-------------+
253              
254             The solution will be displayed in order by cell number, with line
255             breaks controlled by the C attribute, just
256             like any other solution presented by this package.
257              
258             I have seen such puzzles presented with the bottom square placed to the
259             right and rotated counterclockwise 90 degrees. You will need to perform
260             the opposite rotation when you enter the problem.
261              
262             * 'half' generates a topology that looks like an isometric view of a
263             cube, with the puzzle on the visible faces. The faces are divided in
264             half, since the set size here is 8, not 16. Imagine the isometric
265             unfolded to make an L-shape. Then, enter the problem in order by faces,
266             rows, and columns, top to bottom and left to right. The order of entry
267             is actually in order by cell number, as given below.
268              
269             +-------------------+
270             | 0 1 2 3 |
271             | |
272             | 4 5 6 7 |
273             +-------------------+
274             | 8 9 10 11 |
275             | |
276             | 12 13 14 15 |
277             +---------+---------+-------------------+
278             | 16 17 | 18 19 | 32 33 34 35 |
279             | | | |
280             | 20 21 | 22 23 | 36 37 38 39 |
281             | | +-------------------+
282             | 24 25 | 26 27 | 40 41 42 43 |
283             | | | |
284             | 28 29 | 30 31 | 44 45 46 47 |
285             +---------+---------+-------------------+
286              
287             The solution will be displayed in order by cell number, with line
288             breaks controlled by the C attribute, just
289             like any other solution presented by this package.
290              
291             For the 'full' and 'half' cube puzzles, the C attribute is
292             set to 4, and the C attribute to the numbers 1
293             to the size of the largest set (16 for the full cube, 8 for the half
294             or isometric cube). I have seen full cube puzzles done with hex digits
295             0 to F; these are handled most easily by setting the
296             C attribute appropriately:
297              
298             $su->set (cube => 'full', symbols => <
299             . 0 1 2 3 4 5 6 7 8 9 A B C D E F
300             eod
301              
302             =item debug (number)
303              
304             This attribute, if not 0, causes debugging information to be displayed.
305             Values other than 0 are not supported, in the sense that the author
306             makes no commitment what will happen when a non-zero value is set, and
307             further reserves the right to change this behavior without notice of
308             any sort, and without documenting the changes.
309              
310             =item generation_limit (number)
311              
312             This attribute governs how hard the generate() method tries to generate
313             a problem. If generate() cannot generate a problem after this number of
314             tries, it gives up.
315              
316             The default is 30.
317              
318             =item iteration_limit (number)
319              
320             This attribute governs how hard the solution() method tries to solve
321             a problem. An iteration is an attempt to use the backtrack constraint.
322             Since what this really counts is the number of times we place a
323             backtrack constraint on the stack, not the number of values generated
324             from that constraint, I suspect 10 to 20 is reasonable for a "normal"
325             sudoku problem.
326              
327             The default is 0, which imposes no limit.
328              
329             =item largest_set (number, read-only)
330              
331             This read-only attribute returns the size of the largest set defined by
332             the current topology.
333              
334             =item latin (number, write-only)
335              
336             This "virtual" attribute is a convenience, which causes the object to
337             be configured to handle a Latin square. The value gives the size of
338             the square. Setting this modifies the following "real" attributes:
339              
340             columns is set to the size of the square;
341             symbols is set to "." and the letters "A", "B",
342             and so on, up to the size of the square;
343             topology is set to represent the rows and columns
344             of a square, with row sets named "r0", "r1",
345             and so on, and the column sets named "c0",
346             "c1", and so on.
347              
348             =item max_tuple (number)
349              
350             This attribute represents the maximum-sized tuple to consider for the
351             tuple constraint. It is possible that one might want to modify this
352             upward for large puzzles, or downward for small ones.
353              
354             The default is 4, meaning that the solution considers doubles, triples,
355             and quads only.
356              
357             =item name (string)
358              
359             This attribute is for information, and is not used by the class.
360              
361             =item null (string, write-only)
362              
363             This "virtual" attribute is a convenience, which causes the object to
364             be configured with the given number of cells, but no topology. The
365             topology must be added later using the add_set method once for each
366             set of cells to be created.
367              
368             The value must be either a comma-separated list of one to three numbers
369             (e.g. '81,9,9') or a reference to a list containing one to three
370             numbers (e.g. [81, 9, 9]). The first (and only required) number gives the
371             number of cells. The second, if supplied, sets the 'columns' attribute,
372             and the third, if supplied, sets the 'rows' attribute. For example,
373              
374             $su->set (null => [36, 6]);
375             $su->add_set (r0 => 0, 1, 2, 3, 4, 5);
376             $su->add_set (r1 => 6, 7, 8, 9, 10, 11);
377             ...
378             $su->add_set (c0 => 0, 6, 12, 18, 24, 30);
379             $su->add_set (c1 => 1, 7, 13, 19, 25, 31);
380             ...
381             $su->add_set (s0 => 0, 1, 2, 6, 7, 8);
382             $su->add_set (s1 => 3, 4, 5, 9, 10, 11);
383             ...
384              
385             Generates the topology equivalent to
386              
387             $su->set (brick => [3, 2])
388              
389             =item output_delimiter (string)
390              
391             This attribute specifies the delimiter to be used between cell values
392             on output. The default is a single space.
393              
394             =item quincunx (text, write-only)
395              
396             This "virtual" attribute is a convenience, which causes the object to be
397             configured as a quincunx (a. k. a. 'Samurai Sudoku' at
398             L). The value must be
399             either a comma-separated list of one to two numbers (e.g. '3,1') or a
400             reference to a list of one to two numbers (e.g. [3, 1]). In either case,
401             the numbers are the order of the quincunx (3 corresponding to the usual
402             'Samurai Sudoku' configuration), and the gap between the arms of the
403             quincunx, in small squares. The gap must be strictly less than the
404             order, and the same parity (odd or even) as the order. If the gap is not
405             specified, it defaults to the smallest possible.
406              
407             To be specific,
408              
409             $su->set(quincunx => 3)
410              
411             is equivalent to
412              
413             $su->set(quincunx => [3, 1])
414              
415             and both specify the 'Samurai Sudoku' configuration.
416              
417             The actual topology is set up as a square of (2 * order + gap) * order
418             cells on a side, with the cells in the gap being unused. The sets used
419             are the same as for sudoku of the same order, but with 'g0' through 'g4'
420             prepended to their names, with g0 being the top left sudoku grid, g1 the
421             top right, g2 the middle, g3 the bottom left, and g4 the bottom right.
422              
423             In the case of the 's' sets, this would result in duplicate sets being
424             generated in the overlap area, so the 's' set from the higher-numbered
425             grid is suppressed. For example, in the 'Samurai Sudoku' configuration,
426             sets g0s8, g1s6, g2s6, and g2s8 contain exactly the same cells as g2s0,
427             g2s2, g3s2, and g4s0 respectively, so the latter are suppressed, and
428             only the former appear in the topology.
429              
430             Problems are specified left-to-right by rows. The cells in the gaps are
431             unused, and are not specified. For example, the May 2, 2008 'Samurai
432             Sudoku' problem could be specified as
433              
434             . . . . . 1 . . . . . . 4 . . . . .
435             . . . . 3 . 6 . . . . 7 . 2 . . . .
436             . . . 7 . . . 5 . . 4 . . . 5 . . .
437              
438             . . 6 9 . . . . 7 6 . . . . 9 1 . .
439             . 5 . . 2 . . 4 . . 2 . . 5 . . 9 .
440             4 . . . . 5 2 . . . . 8 1 . . . . 7
441              
442             . 2 . . . 4 . . . . 8 . . . . 3 . . . 2 .
443             . . 5 . 6 . . . . 4 . 5 . . . . 8 . 4 . .
444             . . . 1 . . . . . . 7 . . . . . . 7 . . .
445              
446             . 4 . . 6 . . 2 .
447             6 . 7 8 . 9 4 . 1
448             . 1 . . 4 . . 3 .
449              
450             . . . 7 . . . . . . 9 . . . . . . 6 . . .
451             . . 8 . 2 . . . . 2 . 8 . . . . 8 . 5 . .
452             . 4 . . . 3 . . . . 5 . . . . 3 . . . 2 .
453              
454             2 . . . . 7 8 . . . . 4 1 . . . . 6
455             . 3 . . 5 . . 4 . . 3 . . 2 . . 4 .
456             . . 4 8 . . . . 7 2 . . . . 3 1 . .
457              
458             . . . 9 . . . 1 . . 5 . . . 8 . . .
459             . . . . 6 . 9 . . . . 7 . 4 . . . .
460             . . . . . 4 . . . . . . 2 . . . . .
461              
462             Setting this attribute causes the rows and columns attributes to be set
463             to (2 * order + gap) * order. The symbols attribute is set to '.' and
464             the numbers 1, 2, ... up to order * order.
465              
466             =item rows (number)
467              
468             This attribute defines the number of lines of output to present before
469             inserting a blank line (for readability) when formatting the topology
470             attribute, or the solution to a puzzle.
471              
472             =item status_text (text, read-only)
473              
474             This attribute is a short piece of text corresponding to the
475             status_value.
476              
477             =item status_value (number)
478              
479             The solution() method sets a status, which can be retrieved via this
480             attribute. The retrieved value is one of
481              
482             SUDOKU_SUCCESS
483             This means what you think it does.
484             SUDOKU_NO_SOLUTION
485             This means the method exhausted all possible
486             soltions without finding one
487             SUDOKU_TOO_HARD
488             This means the iteration_limit attribute was
489             set to a positive number and the solution()
490             method hit the limit without finding a solution.
491              
492             =item sudoku (number, write-only)
493              
494             This attribute is a convenience, which causes the object to be
495             configured to handle a standard Sudoku square. The value gives the size
496             of the small squares into which the big square is divided. The big
497             square's side is the square of the value.
498              
499             For example, the customary Sudoku topology is set by
500              
501             $su->set (sudoku => 3);
502              
503             This attribute is implemented in terms of C ... )>,
504             and modifies the same "real" attributes. See the C attribute for
505             the details.
506              
507             =item sudokux (number, write-only)
508              
509             This attribute is a convenience. It is similar to the 'sudoku'
510             attribute, but the topology includes both main diagonals (set names
511             'd0' and 'd1') in addition to the standard sets. See the
512             C attribute for the details, since that's ultimately how this
513             attribute is implemented.
514              
515             =item symbols (string)
516              
517             This attribute defines the symbols to be used in the puzzle. Any
518             printing characters may be used except ",". Multi-character symbols
519             are supported. The value of the attribute is a whitespace-delimited
520             list of the symbols, though the whitespace is optional if all symbols
521             (and symbol constraints if any) are a single character. See the
522             L documentation for full details.
523              
524             The first symbol in the list is the one that represents an empty cell.
525             Except for this, the order of the symbols is immaterial.
526              
527             The symbols defined here are used only for input or output. It is
528             perfectly legitimate to set symbols, call the problem() method, and
529             then change the symbols. The solution() method will return solutions
530             in the new symbol set. I have no idea why you would want to do this.
531              
532             =item topology (string)
533              
534             This attribute defines the topology of the puzzle, in terms of what
535             sets each cell belongs to. Each cell is defined in terms of a
536             comma-delimited list of the names of the sets it belongs to, and
537             the string is a whitespace-delimited list of cell definitions. For
538             example, a three-by-three grid with diagonals can be defined as
539             follows in terms of sets r1, r2, and r3 for the rows, c1, c2, and
540             c3 for the columns, and d1 and d2 for the diagonals:
541              
542             r1,c1,d1 r1,c2 r1,c3,d2
543             r2,c1 r2,c2,d1,d2 r2,c3
544             r3,c1,d2 r3,c2 r3,c3,d1
545              
546             The parser treats line breaks as whitespace. That is to say, the
547             above definition would be the same if it were all on one line.
548              
549             You do not need to define the sets themselves anywhere. The
550             package defines each set as it encounters it in the topology
551             definition.
552              
553             For certain topologies (e.g. the London Times Quincunx) it may be
554             convenient to include in the definition cells that are not part of the
555             puzzle. Such unused cells are defined by specifying just a comma,
556             without any set names.
557              
558             Setting the topology invalidates any currently-set-up problem.
559              
560             =back
561              
562             =head2 Methods
563              
564             This package provides the following public methods:
565              
566             =cut
567              
568             package Games::Sudoku::General;
569              
570 2     2   3864 use 5.006002; # For 'our', at least.
  2         16  
571              
572 2     2   13 use strict;
  2         4  
  2         62  
573 2     2   11 use warnings;
  2         5  
  2         105  
574              
575 2     2   12 use Exporter qw{ import };
  2         3  
  2         241  
576              
577             our $VERSION = '0.026';
578             our @EXPORT_OK = qw{
579             SUDOKU_SUCCESS
580             SUDOKU_NO_SOLUTION
581             SUDOKU_TOO_HARD
582             SUDOKU_MULTIPLE_SOLUTIONS
583             };
584             our %EXPORT_TAGS = (
585             all => \@EXPORT_OK,
586             status => \@EXPORT_OK,
587             );
588 2     2   14 use Carp;
  2         4  
  2         193  
589 2     2   1387 use Data::Dumper;
  2         15943  
  2         219  
590 2     2   22 use List::Util qw{first max reduce};
  2         7  
  2         276  
591 2     2   1199 use POSIX qw{floor};
  2         17137  
  2         22  
592              
593 2     2   3367 use constant SUDOKU_SUCCESS => 0;
  2         5  
  2         177  
594 2     2   12 use constant SUDOKU_NO_SOLUTION => 1;
  2         4  
  2         109  
595 2     2   15 use constant SUDOKU_TOO_HARD => 2;
  2         3  
  2         90  
596 2     2   10 use constant SUDOKU_MULTIPLE_SOLUTIONS => 3;
  2         6  
  2         184  
597              
598             my @status_values = (
599             'Success',
600             'No solution found',
601             'No solution found before exceeding iteration limit',
602             'Multiple solutions found',
603             );
604              
605 2     2   15 use constant HASH_REF => ref {};
  2         5  
  2         23313  
606              
607             =head2 new
608              
609             $su = Games::Sudoku::General->new ()
610              
611             This method instantiates a new Games::Sudoku::General object. Any
612             arguments are passed to the set() method. If, after processing
613             the arguments, the object does not have a topology,
614              
615             $self->set (sudoku => 3)
616              
617             is called. If there is no symbols setting (which could happen
618             if the user passed an explicit topology),
619              
620             $self->set (symbols => join ' ', '.',
621             1 .. $self->get ('largest_set'))
622              
623             is called. If, after all this, there is still no columns setting,
624             the number of columns is set to the number of symbols, excluding
625             the "empty cell" symbol.
626              
627             The newly-instantiated object is returned.
628              
629             =cut
630              
631             sub new {
632 2     2 1 741 my ($class, @args) = @_;
633 2 50       12 ref $class and $class = ref $class;
634 2         16 my $self = bless {
635             debug => 0,
636             generation_limit => 30,
637             iteration_limit => 0,
638             output_delimiter => ' ',
639             }, $class;
640 2 50       8 @args and $self->set (@args);
641 2 50       25 $self->{cell} or $self->set (sudoku => 3);
642             $self->{symbol_list}
643 2 50       11 or $self->set (symbols => join ' ', '.', 1 .. $self->{largest_set});
644             defined $self->{columns}
645 2 50       13 or $self->set (columns => @{$self->{symbol_list}} - 1);
  0         0  
646             defined $self->{status_value}
647 2 50       19 or $self->set (status_value => SUDOKU_SUCCESS);
648             defined $self->{max_tuple}
649 2 50       17 or $self->set (max_tuple => 4);
650 2         20 return $self;
651             }
652              
653             =head2 add_set
654              
655             $su->add_set ($name => $cell ...)
656              
657             This method adds to the current topology a new set with the given name,
658             and consisting of the given cells. The set name must not already
659             exist, but the cells must already exist. In other words, you can't
660             modify an existing set with this method, nor can you add new cells.
661              
662             =cut
663              
664             sub add_set {
665 21     21 1 65 my ($self, $name, @cells) = @_;
666 21 50       54 $self->{set}{$name} and croak <
667             Error - Set '$name' already exists.
668             eod
669 21         37 foreach my $inx (@cells) {
670 184 50       350 $self->{cell}[$inx] or croak <
671             Error - Cell $inx does not exist.
672             eod
673             }
674 21         35 foreach my $inx (@cells) {
675 184         282 my $cell = $self->{cell}[$inx];
676 184 50       237 @{$cell->{membership}} or --$self->{cells_unused};
  184         359  
677 184         250 foreach my $other (@{$cell->{membership}}) {
  184         300  
678 468         898 my $int = join ',', sort $other, $name;
679 468   100     1838 $self->{intersection}{$int} ||= [];
680 468         602 push @{$self->{intersection}{$int}}, $inx;
  468         1284  
681             }
682 184         256 @{$cell->{membership}} = sort $name, @{$cell->{membership}};
  184         486  
  184         334  
683             }
684 21         161 $self->{set}{$name} = {
685             name => $name,
686             membership => [sort @cells],
687             };
688             $self->{largest_set} = max ($self->{largest_set},
689 21         34 scalar @{$self->{set}{$name}{membership}});
  21         58  
690 21         40 delete $self->{backtrack_stack}; # Force setting of new problem.
691 21         65 return $self;
692             }
693              
694             =head2 constraints_used
695              
696             %constraints_used = $su->constraints_used;
697              
698             This method returns a hash containing the constraints used in the most
699             recent call to solution(), and the number of times each was used. The
700             constraint codes are the same as for the steps() method. If called in
701             scalar context it returns a string representing the constraints used
702             at least once, in canonical order (i.e. in the order documented in the
703             steps() method).
704              
705             B As of version 0.002, the string returned by the scalar has
706             spaces delimiting the constraint names. They were not delimited in
707             version 0.001
708              
709             =cut
710              
711             sub constraints_used {
712 6     6 1 25 my ( $self ) = @_;
713 6 50 33     45 return unless $self->{constraints_used} && defined wantarray;
714 6 50       22 return %{$self->{constraints_used}} if wantarray;
  0         0  
715             my $rslt = join ' ', grep {
716 6         23 $self->{constraints_used}{$_}} qw{F N B T X Y W ?};
  48         104  
717 6         36 return $rslt;
718             }
719              
720             =head2 copy
721              
722             $su->copy ()
723              
724             This method copies the current problem to the clipboard. If solution()
725             has been called, the current solution goes on the clipboard.
726              
727             See L for what is needed for this
728             to work.
729              
730             =cut
731              
732             { # Local symbol block.
733             my $copier;
734             sub copy {
735 1     1 1 3 my ( $self ) = @_;
736 1 50 33     6 ( $copier ||= eval {
737 1         804 require Clipboard;
738 1         8 Clipboard->import();
739             sub {
740 1     1   10 Clipboard->copy( join '', @_ );
741 1         2 return;
742 1         11 };
743             }
744             ) or croak 'copy() unavailable; can not load Clipboard';
745 1         7 $copier->( $self->_unload() );
746 1         4 return $self;
747             }
748             }
749              
750             =head2 drop_set
751              
752             $su->drop_set( $name )
753              
754             This method removes from the current topology the set with the given
755             name. The set must exist, or an exception is raised.
756              
757             =cut
758              
759             sub drop_set {
760 1     1 1 5 my ($self, $name) = @_;
761 1 50       6 $self->{set}{$name} or croak <
762             Error - Set '$name' not defined.
763             eod
764 1         3 foreach my $inx (@{$self->{set}{$name}{membership}}) {
  1         6  
765 4         6 my $cell = $self->{cell}[$inx];
766 4         8 my @mbr;
767 4         7 foreach my $other (@{$cell->{membership}}) {
  4         11  
768 12 100       25 if ($other ne $name) {
769 8         15 push @mbr, $other;
770 8         20 my $int = join ',', sort $other, $name;
771 8         19 delete $self->{intersection}{$int};
772             }
773             }
774 4 50       11 if (@mbr) {
775 4         9 @{$cell->{membership}} = sort @mbr;
  4         13  
776             } else {
777 0         0 @{$cell->{membership}} = ();
  0         0  
778 0         0 $self->{cells_unused}++;
779             }
780             }
781 1         5 delete $self->{set}{$name};
782 1         2 $self->{largest_set} = 0;
783 1         17 foreach (keys %{$self->{set}}) {
  1         7  
784             $self->{largest_set} = max ($self->{largest_set},
785 8         12 scalar @{$self->{set}{$_}{membership}});
  8         21  
786             }
787 1         5 delete $self->{backtrack_stack}; # Force setting of new problem.
788 1         3 return $self;
789             }
790              
791             =head2 generate
792              
793             $problem = $su->generate( $min, $max, $const );
794              
795             This method generates a problem and returns it.
796              
797             The $min argument is the minimum number of givens in the puzzle. You
798             may (and probably will) get more. The default is the number of cells
799             in the puzzle divided by the number of sets a cell belongs to.
800              
801             The value of this argument is critical to getting a puzzle: too large
802             and you generate puzzles with no solution; too small and you spend all
803             your time backtracking. There is no science behind the default, just an
804             attempt to make a rational heuristic based on the number of degrees of
805             freedom and the observation that about a third of the cells are given
806             in a typical Sudoku puzzle. My experience with the default is:
807              
808             topology comment
809             brick 3,2 default is OK
810             corresponding 3 default is OK
811             cube 3 default is too large
812             cube half default is OK
813             cube full default is OK
814             quincunx 3 default is too large
815             sudoku 3 default is OK
816             sudoku 4 default is OK
817             sudokux 3 default is OK
818              
819             Typically when I take the defaults I get a puzzle in anywhere from
820             a few seconds (most of the listed topologies) to a couple minutes
821             (sudoku 4) on an 800 Mhz G4. But I have never successfully generated
822             a Dion cube (cube 3). C
823              
824             The $max argument is the maximum number of givens in the puzzle. You
825             may get less. The default is 1.5 times the minimum.
826              
827             The $const argument specifies the constraints to be used in the
828             generated puzzle. This may be specified either as a string or as a hash
829             reference. If specified as a string, it is a whitespace-delimited list,
830             with each constraint name possibly followed by an equals sign and a
831             number to specify that that constraint can be used only a certain
832             number of times. For example, 'F N ?=1' specifies a puzzle to be
833             solved by use of any number of applications of the F and N constraints,
834             and at most one guessed cell. If specified as a hash reference, the
835             keys are the constraint names, and the values are the usage counts,
836             with undef meaning no limit. The hash reference corresponding to
837             'F N ?=1' is {F => undef, N => undef, '?' => 1}. The default for this
838             argument is to allow all known constraints except '?'.
839              
840             In practice, the generator usually generates puzzles solvable using
841             only the F constraint, or the F and N constraints.
842              
843             The algorithm used is to generate a puzzle with the minimum number of
844             cells selected at random, and then solve it. If a solution does not
845             exist, we try again until we have tried
846             C times, then we return undef.
847             B
848              
849             If we get a solution, we remove allowed constraints. If we run into
850             a constraint that is not allowed, we either stop (if we're below the
851             maximum number of givens) or turn it into a given value (if we're
852             above the maximum). We stop unconditionally if we get down to the
853             minimum number of givens. As a side effect, the generated puzzle is
854             set up as a problem.
855              
856             Note that if you allow guesses you may get puzzles with more than
857             one solution.
858              
859             =cut
860              
861             sub generate {
862 0     0 1 0 my ( $self, $min, $max, $const ) = @_;
863 0         0 my $size = @{$self->{cell}} - $self->{cells_unused};
  0         0  
864 0   0     0 $min ||= do {
865             floor( $size * $size /
866 0         0 ( $self->{largest_set} * keys %{ $self->{set} } ) );
  0         0  
867             };
868 0   0     0 $max ||= floor( $min * 1.5 );
869 0   0     0 $const ||= 'F N B T';
870 0 0 0     0 croak <<"EOD" if ref $const && HASH_REF ne ref $const;
871             Error - The constraints argument must be a string or a hash reference,
872 0         0 not a @{[ref $const]} reference.
873             EOD
874 0 0       0 $const = {map {my @ret; $_ and do {
  0 0       0  
  0         0  
875 0         0 @ret = split '=', $_, 2; push @ret, undef while @ret < 2}; @ret}
  0         0  
  0         0  
876             split '\s+', $const}
877             unless HASH_REF eq ref $const;
878 0 0       0 $self->{debug} and do {
879 0         0 local $Data::Dumper::Terse = 1;
880 0         0 print <
881 0         0 Debug generate ($min, $max, @{[Dumper $const]})
882             eod
883             };
884 0         0 my $syms = @{$self->{symbol_list}} - 1;
  0         0  
885 0 0       0 croak < $size;
886             Error - You specified a minimum of $min given values, but the puzzle
887             only contains $size cells.
888             eod
889 0         0 my $tries = $self->{generation_limit};
890 0         0 $size = @{$self->{cell}}; # Note equivocation on $size.
  0         0  
891 0         0 local $Data::Dumper::Terse = 1;
892             my @universe = $self->{cells_unused} ?
893 0         0 grep {@{$self->{cell}[$_]{membership}}} (0 .. @{$self->{cell}} - 1) :
  0         0  
  0         0  
894 0 0       0 (0 .. @{$self->{cell}} - 1);
  0         0  
895 0         0 while (--$tries >= 0) {
896 0         0 $self->problem (); # We rely on this specifying an empty problem.
897             ## my @ix = (0 .. $size - 1);
898 0         0 my @ix = @universe;
899 0         0 my $gen = 0;
900 0         0 while ($gen++ < $min) {
901 0         0 my ($inx) = splice @ix, floor (rand scalar @ix), 1;
902 0         0 my $cell = $self->{cell}[$inx];
903             ## @{$cell->{membership}} or redo; # Ignore unused cells.
904 0 0       0 my @pos = grep {!$cell->{possible}{$_}} 1 .. $syms or next;
  0         0  
905 0         0 my $val = $pos[floor (rand scalar @pos)];
906 0 0       0 defined $val or confess <{possible});
907             Programming error - generate() selected an undefined value for cell $inx.
908             Possible values hash is:
909             eod
910             $self->_try ($cell, $val)
911 0 0       0 and confess <{possible});
912             Programming error - generate() tried to assign $val to cell $inx,
913             but it was rejected. Possible values hash is:
914             eod
915             }
916 0 0       0 $self->solution () or next;
917 0         0 $self->_constraint_remove ($min, $max, $const);
918 0         0 my $prob = $self->_unload ('', SUDOKU_SUCCESS);
919 0         0 $self->problem ($prob);
920 0 0       0 $self->copy ($prob) if $self->{autocopy};
921 0         0 return $prob;
922             }
923 0         0 return;
924             }
925              
926             my %accessor = (
927             allowed_symbols => \&_get_allowed_symbols,
928             autocopy => \&_get_value,
929             columns => \&_get_value,
930             debug => \&_get_value,
931             generation_limit => \&_get_value,
932             ## ignore_unused => \&_get_value,
933             iteration_limit => \&_get_value,
934             largest_set => \&_get_value,
935             name => \&_get_value,
936             output_delimiter => \&_get_value,
937             rows => \&_get_value,
938             status_text => \&_get_value,
939             status_value => \&_get_value,
940             symbols => \&_get_symbols,
941             topology => \&_get_topology,
942             );
943              
944             =head2 get
945              
946             $value = $su->get( $name );
947              
948             This method returns the value of the named attribute. An exception
949             is thrown if the given name does not correspond to an attribute that
950             can be read. That is, the given name must appear on the list of
951             attributes above, and not be marked "write-only".
952              
953             If called in list context, you can pass multiple attribute names,
954             and get back a list of their values. If called in scalar context,
955             attribute names after the first are ignored.
956              
957             =cut
958              
959             sub get {
960 21     21 1 77 my ($self, @args) = @_;
961 21         37 my @rslt;
962 21 50       69 wantarray or @args = ($args[0]);
963 21         57 foreach my $name (@args) {
964 21 50       64 exists $accessor{$name} or croak <
965             Error - Attribute $name does not exist, or is write-only.
966             eod
967 21         83 push @rslt, $accessor{$name}->($self, $name);
968             }
969 21 50       142 return wantarray ? @rslt : $rslt[0];
970             }
971              
972             sub _get_allowed_symbols {
973 2     2   5 my ( $self ) = @_;
974 2         4 my $rslt = '';
975 2         4 my $syms = @{$self->{symbol_list}};
  2         6  
976 2         5 foreach (sort keys %{$self->{allowed_symbols}}) {
  2         14  
977 6         12 my @symlst;
978 6         14 for (my $val = 1; $val < $syms; $val++) {
979             push @symlst, $self->{symbol_list}[$val]
980 54 100       130 if $self->{allowed_symbols}{$_}[$val];
981             }
982 6         9 $rslt .= "$_=@{[join ',', @symlst]}\n";
  6         25  
983             }
984 2         7 return $rslt;
985             }
986              
987             sub _get_symbols {
988 5     5   17 my ( $self ) = @_;
989 5         12 return join ' ', @{$self->{symbol_list}};
  5         31  
990             }
991              
992             sub _get_topology {
993 8     8   61 my ( $self ) = @_;
994 8         28 my $rslt = '';
995 8         20 my $col = $self->{columns};
996 8   33     32 my $row = $self->{rows} ||= floor (@{$self->{cell}} / $col);
  0         0  
997 8 50       21 foreach (map {join (',', @{$_->{membership}}) || ','} @{$self->{cell}}) {
  583         800  
  583         1437  
  8         32  
998 583         767 $rslt .= $_;
999 583 100       854 if (--$col > 0) {
1000 522         735 $rslt .= ' '
1001             } else {
1002 61         99 $rslt .= "\n";
1003 61         85 $col = $self->{columns};
1004 61 100       130 if (--$row <= 0) {
1005 8         14 $rslt .= "\n";
1006 8         25 $row = $self->{rows};
1007             }
1008             }
1009             }
1010 8         65 0 while chomp $rslt;
1011 8         19 $rslt .= "\n";
1012 8         61 return $rslt;
1013             }
1014              
1015 6     6   27 sub _get_value {return $_[0]->{$_[1]}}
1016              
1017             =head2 paste
1018              
1019             $su->paste()
1020              
1021             This method pastes a problem from the clipboard.
1022              
1023             See L for what is needed for this
1024             to work.
1025              
1026             =cut
1027              
1028             { # Begin local symbol block
1029              
1030             my $paster;
1031             sub paste {
1032 1     1 1 4 my ( $self ) = @_;
1033 1 50 33     7 ( $paster ||= eval {
1034 1         13 require Clipboard;
1035 1         9 Clipboard->import();
1036             return sub {
1037 1     1   6 return Clipboard->paste();
1038 1         8 };
1039             }
1040             ) or croak 'paste() unavailable; can not load Clipboard';
1041              
1042 1         5 $self->problem( $paster->() );
1043 1         8 $self->_unload();
1044 1         8 return $self;
1045             }
1046              
1047             } # End local symbol block
1048              
1049             =head2 problem
1050              
1051             $su->problem( $string );
1052              
1053             This method specifies the problem to be solved, and sets the object
1054             up to solve the problem.
1055              
1056             The problem is specified by a whitespace-delimited list of the symbols
1057             contained by each cell. You can format the puzzle definition into a
1058             square grid (e.g. the SYNOPSIS section), but to the parser a line
1059             break is no different than spaces. If you pass an empty string, an
1060             empty problem will be set up - that is, one in which all cells are
1061             empty.
1062              
1063             An exception will be thrown if:
1064              
1065             * The puzzle definition uses an unknown symbol;
1066             * The puzzle definition has a different number
1067             of cells from the topology definition;
1068             * There exists a set with more members than the
1069             number of symbols, excluding the "empty"
1070             symbol.
1071              
1072             The whitespace delimiter is optional, provided that all symbol names
1073             are exactly one character long, B that you have not defined any
1074             symbol constraint names more than one character long since the last
1075             time you set the symbol names.
1076              
1077             =cut
1078              
1079             sub problem {
1080 19     19 1 63 my ( $self, $val ) = @_;
1081 19   50     67 $val ||= '';
1082             $val =~ m/\S/ or
1083             $val = "$self->{symbol_list}[0] " x
1084 19 50       123 (scalar @{$self->{cell}} - $self->{cells_unused});
  0         0  
1085 19 100       353 $val =~ s/\s+//g unless $self->{biggest_spec} > 1;
1086 19         65 $val =~ s/^\s+//;
1087 19         101 $val =~ s/\s+$//;
1088 19 50       65 $self->{debug} and print <
1089             Debug problem - Called with $val
1090             eod
1091              
1092 19         54 local $Data::Dumper::Terse = 1;
1093 19 50       38 $self->{largest_set} >= @{$self->{symbol_list}} and croak <
  19         73  
1094             Error - The largest set has $self->{largest_set} cells, but there are only @{[
1095 0         0 @{$self->{symbol_list}} - 1]} symbols.
  0         0  
1096             Either the set definition is in error or the list of symbols is
1097             incomplete.
1098             eod
1099              
1100 19         29 my $syms = @{$self->{symbol_list}};
  19         45  
1101 19         35 foreach (@{$self->{cell}}) {
  19         53  
1102 1651         2983 $_->{content} = $_->{chosen} = 0;
1103 1651         3116 $_->{possible} = {map {$_ => 0} (1 .. $syms - 1)};
  17167         32424  
1104             }
1105 19         41 foreach (values %{$self->{set}}) {
  19         114  
1106 511         678 $_->{free} = @{$_->{membership}};
  511         858  
1107 511         1060 $_->{content} = [$_->{free}];
1108             }
1109 19         37 $self->{cells_unassigned} = scalar @{$self->{cell}} - $self->{cells_unused};
  19         65  
1110              
1111 19         38 my $hash = $self->{symbol_hash};
1112 19         50 my $inx = 0;
1113 19         32 my $max = @{$self->{cell}};
  19         43  
1114 19 100       689 foreach (split (($self->{biggest_spec} > 1 ? '\s+' : ''), $val)) {
1115 1651 50       2844 $inx >= $max and croak <
1116             Error - Too many cell specifications. The topology allows only $max.
1117             eod
1118 1651 50       2799 next unless defined $_;
1119             # was $self->{ignore_unused}
1120 0         0 ($self->{cells_unused} && !@{$self->{cell}[$inx]{membership}})
1121 1651 50 33     3269 and do {$inx++; redo};
  0         0  
  0         0  
1122 1651 100       3030 $self->{allowed_symbols}{$_} and do {
1123 195 50       354 $self->{debug} > 1 and print <
1124             Debug problem - Cell $inx allows symbol set $_
1125             eod
1126 195         270 my $cell = $self->{cell}[$inx];
1127 195 50       253 @{$cell->{membership}} or croak <
  195         383  
1128             Error - Cell $inx is unused, and must be specified as empty.
1129             eod
1130 195         380 for (my $val = 1; $val < $syms; $val++) {
1131 1692 100       3475 next if $self->{allowed_symbols}{$_}[$val];
1132 749         1453 $cell->{possible}{$val} = 1;
1133             }
1134             };
1135 1651 100       3188 defined $hash->{$_} or $_ = $self->{symbol_list}[0];
1136 1651         3524 (@{$self->{cell}[$inx]{membership}} ||
1137 1651 50 33     2119 $_ eq $self->{symbol_list}[0])
1138             or croak <
1139             Error - Cell $inx is unused, and must be specified as empty.
1140             eod
1141 1651 50       3036 $self->{debug} > 1 and print <
1142             Debug problem - Cell $inx specifies symbol $_
1143             eod
1144 1651 50       3108 $self->_try ($inx, $hash->{$_}) and croak <
1145             Error - Symbol '$_' appears more than once in a set.
1146             The problem loaded thus far is:
1147 0         0 @{[$self->_unload (' ')]}
1148             eod
1149 1651 100       3344 $self->{cell}[$inx]{chosen} = $hash->{$_} ? 1 : 0;
1150             } continue {
1151 1651         2487 $inx++;
1152             }
1153              
1154 19 50       197 unless ($inx == $max) {
1155             # was $self->{ignore_unused}
1156 0 0       0 $self->{cells_unused} and do {
1157 0         0 $inx -= $self->{cells_unused};
1158 0         0 $max -= $self->{cells_unused};
1159             };
1160 0         0 croak <
1161             Error - Not enough cell specifications. you gave $inx but the topology
1162             defined $max.
1163             eod
1164             }
1165              
1166 19         86 $self->{constraints_used} = {};
1167              
1168 19 50       53 $self->{debug} and print <
1169             Debug problem - problem loaded.
1170             eod
1171              
1172 19         293 $self->{backtrack_stack} = [];
1173 19         49 $self->{cell_order} = [];
1174 19         36 delete $self->{no_more_solutions};
1175              
1176 19 50       54 $self->{debug} > 1 and print " object = ", Dumper ($self);
1177              
1178 19         84 return $self;
1179             }
1180              
1181             my %mutator = (
1182             allowed_symbols => \&_set_allowed_symbols,
1183             autocopy => \&_set_value,
1184             brick => \&_set_brick,
1185             columns => \&_set_number,
1186             debug => \&_set_number,
1187             corresponding => \&_set_corresponding,
1188             cube => \&_set_cube,
1189             generation_limit => \&_set_number,
1190             ## ignore_unused => \&_set_value,
1191             iteration_limit => \&_set_number,
1192             latin => \&_set_latin,
1193             max_tuple => \&_set_number,
1194             name => \&_set_value,
1195             null => \&_set_null,
1196             output_delimiter => \&_set_value,
1197             quincunx => \&_set_quincunx,
1198             rows => \&_set_number,
1199             status_value => \&_set_status_value,
1200             sudoku => \&_set_sudoku,
1201             sudokux => \&_set_sudokux,
1202             symbols => \&_set_symbols,
1203             topology => \&_set_topology,
1204             );
1205              
1206             =head2 set
1207              
1208             $su->set( $name => $value );
1209              
1210             This method sets the value of the named attribute. An exception
1211             is thrown if the given name does not correspond to an attribute that
1212             can be written. That is, the given name must appear on the list of
1213             attributes above, and not be marked "read-only". An exception is
1214             also thrown if the value is invalid, e.g. a non-numeric value for
1215             an attribute marked "number".
1216              
1217             You can pass multiple name-value pairs. If an exception is thrown,
1218             all settings before the exception will be made, and all settings
1219             after the exception will not be made.
1220              
1221             The object itself is returned.
1222              
1223             =cut
1224              
1225             sub set {
1226 62     62 1 210 my ( $self, @args ) = @_;
1227 62         169 while ( @args ) {
1228 90         270 my ( $name, $val ) = splice @args, 0, 2;
1229 90 50       262 exists $mutator{$name} or croak <
1230             Error - Attribute $name does not exist, or is read-only.
1231             eod
1232 90         302 $mutator{$name}->($self, $name, $val );
1233             }
1234 62         134 return $self;
1235             }
1236              
1237             sub _set_allowed_symbols {
1238             ## my ( $self, $name, $value ) = @_;
1239 4     4   12 my ( $self, undef, $value ) = @_; # Name unused
1240 4 50       12 defined $value or $value = '';
1241 4         10 my $maxlen = 0;
1242 4 50       15 $self->{debug} and print <
1243             Debug allowed_symbols being set to '$value'
1244             eod
1245 4 50       13 if ($value) {
1246 4         36 foreach (split '\s+', $value) {
1247 22         59 my ($name, $value) = split '=', $_, 2;
1248 22 50       49 croak <{symbol_hash}{$name};
1249             Error - You can not use '$name' as a symbol constraint name, because
1250             it is a valid symbol name.
1251             eod
1252 22 100       44 $value or do {delete $self->{allowed_symbols}{$name}; next};
  2         6  
  2         3  
1253 20         47 $maxlen = max ($maxlen, length ($name));
1254 20 50       40 $self->{debug} > 1 and print <
1255             Debug allowed_symbols - $_
1256 0         0 set name '$name' has length @{[length ($name)]}. Maxlen now $maxlen.
1257             eod
1258 20         46 my $const = $self->{allowed_symbols}{$name} = [];
1259 20         51 foreach (split ',', $value) {
1260 93 50       179 $self->{debug} > 1 and print <
1261             Debug allowed_symbols - Adding symbol '$_' to set '$name'.
1262             eod
1263 93 50       166 $self->{symbol_hash}{$_} or croak <
1264             Error - '$_' is not a valid symbol.
1265             eod
1266 93         179 $const->[$self->{symbol_hash}{$_}] = 1;
1267             }
1268             }
1269             } else {
1270 0         0 $self->{allowed_symbols} = {};
1271             }
1272 4 100       29 $self->{biggest_spec} = $maxlen if $maxlen > $self->{biggest_spec};
1273 4         14 return;
1274             }
1275              
1276             sub _set_brick {
1277 6     6   21 my ( $self, undef, $value ) = @_; # $name unused
1278 6 100       32 my ($horiz, $vert, $size) = ref $value ? @$value : split ',', $value;
1279 6 50       22 defined $size
1280             and $self->_deprecation_notice( 'brick_third_argument' );
1281 6   33     105 $size ||= $horiz * $vert;
1282 6 50 33     58 ($size % $horiz || $size % $vert) and croak <
1283             Error - The puzzle size $size must be a multiple of both the horizontal
1284             brick size $horiz and the vertical brick size $vert.
1285             eod
1286 6         52 my $rowmul = floor ($size / $horiz);
1287 6         16 my $syms = '.';
1288 6         22 my $topo = '';
1289 6         31 for (my $row = 0; $row < $size; $row++) {
1290 58         93 $syms .= " @{[$row + 1]}";
  58         149  
1291 58         139 for (my $col = 0; $col < $size; $col++) {
1292 616         2181 $topo .= sprintf ' r%d,c%d,s%d', $row, $col,
1293             floor ($row / $vert) * $rowmul + floor ($col / $horiz);
1294             }
1295             }
1296 6         24 substr ($topo, 0, 1, '');
1297 6         30 $self->set (columns => $size, rows => $size, symbols => $syms,
1298             topology => $topo);
1299 6         26 return;
1300             }
1301              
1302             sub _set_corresponding {
1303             ## my ( $self, $name, $order ) = @_;
1304 1     1   4 my ( $self, undef, $order ) = @_; # Name unused
1305 1         4 my $size = $order * $order;
1306 1         5 $self->set (sudoku => $order);
1307 1         3 my $order_minus_1 = $order - 1;
1308 1         4 my $offset = $size * $order;
1309 1         5 for (my $inx = 0; $inx < $size; $inx++) {
1310 9         58 my $base = floor ($inx / $order) * $size + $inx % $order;
1311             $self->add_set ("u$inx", map {
1312 9         26 my $g = $_ * $offset + $base;
  27         38  
1313 27         44 (map {$_ * $order + $g} 0 .. $order_minus_1)} 0 .. $order_minus_1);
  81         148  
1314             }
1315 1         11 return;
1316             }
1317              
1318             my %cube = (
1319             full => <
1320             c0,r0,s0 c1,r0,s0 c2,r0,s0 c3,r0,s0
1321             c0,r1,s0 c1,r1,s0 c2,r1,s0 c3,r1,s0
1322             c0,r2,s0 c1,r2,s0 c2,r2,s0 c3,r2,s0
1323             c0,r3,s0 c1,r3,s0 c2,r3,s0 c3,r3,s0
1324             p0,r0,s1 p0,r1,s1 p0,r2,s1 p0,r3,s1
1325             p1,r0,s1 p1,r1,s1 p1,r2,s1 p1,r3,s1
1326             p2,r0,s1 p2,r1,s1 p2,r2,s1 p2,r3,s1
1327             p3,r0,s1 p3,r1,s1 p3,r2,s1 p3,r3,s1
1328             c0,p0,s2 c1,p0,s2 c2,p0,s2 c3,p0,s2
1329             c0,p1,s2 c1,p1,s2 c2,p1,s2 c3,p1,s2
1330             c0,p2,s2 c1,p2,s2 c2,p2,s2 c3,p2,s2
1331             c0,p3,s2 c1,p3,s2 c2,p3,s2 c3,p3,s2
1332             p0,r3,s3 p0,r2,s3 p0,r1,s3 p0,r0,s3
1333             p1,r3,s3 p1,r2,s3 p1,r1,s3 p1,r0,s3
1334             p2,r3,s3 p2,r2,s3 p2,r1,s3 p2,r0,s3
1335             p3,r3,s3 p3,r2,s3 p3,r1,s3 p3,r0,s3
1336             c0,r3,s4 c1,r3,s4 c2,r3,s4 c3,r3,s4
1337             c0,r2,s4 c1,r2,s4 c2,r2,s4 c3,r2,s4
1338             c0,r1,s4 c1,r1,s4 c2,r1,s4 c3,r1,s4
1339             c0,r0,s4 c1,r0,s4 c2,r0,s4 c3,r0,s4
1340             c0,p3,s5 c1,p3,s5 c2,p3,s5 c3,p3,s5
1341             c0,p2,s5 c1,p2,s5 c2,p2,s5 c3,p2,s5
1342             c0,p1,s5 c1,p1,s5 c2,p1,s5 c3,p1,s5
1343             c0,p0,s5 c1,p0,s5 c2,p0,s5 c3,p0,s5
1344             eod
1345             half => <
1346             r0,c0,s0 r0,c1,s0 r0,c2,s0 r0,c3,s0
1347             r1,c0,s0 r1,c1,s0 r1,c2,s0 r1,c3,s0
1348             r2,c0,s1 r2,c1,s1 r2,c2,s1 r2,c3,s1
1349             r3,c0,s1 r3,c1,s1 r3,c2,s1 r3,c3,s1
1350             p0,c0,s2 p0,c1,s2 p0,c2,s3 p0,c3,s3
1351             p1,c0,s2 p1,c1,s2 p1,c2,s3 p1,c3,s3
1352             p2,c0,s2 p2,c1,s2 p2,c2,s3 p2,c3,s3
1353             p3,c0,s2 p3,c1,s2 p3,c2,s3 p3,c3,s3
1354             p0,r3,s4 p0,r2,s4 p0,r1,s4 p0,r0,s4
1355             p1,r3,s4 p1,r2,s4 p1,r1,s4 p1,r0,s4
1356             p2,r3,s5 p2,r2,s5 p2,r1,s5 p2,r0,s5
1357             p3,r3,s5 p3,r2,s5 p3,r1,s5 p3,r0,s5
1358             eod
1359             );
1360              
1361             sub _set_cube {
1362             ## my ( $self, $name, $type ) = @_;
1363 2     2   7 my ( $self, undef, $type ) = @_; # Name unused
1364 2 50       15 if ($type =~ m/\D/) {
1365 2 50       8 $cube{$type} or croak <
1366             Error - Cube type '$type' is not defined. Legal values are numeric (for
1367 0         0 Dion cube), or one of @{[join ', ', map {"'$_'"} sort keys %cube]}
  0         0  
1368             eod
1369 2         7 $self->set (topology => $cube{$type}, columns => 4, rows => 4);
1370             } else {
1371 0         0 my $size = $type * $type;
1372 0         0 my $topo = '';
1373 0         0 for (my $x = 0; $x < $size; $x++) {
1374 0         0 for (my $y = 0; $y < $size; $y++) {
1375 0         0 for (my $z = 0; $z < $size; $z++) {
1376 0         0 $topo .= join (',',
1377             _cube_set_names ($type, x => $x, $y, $z),
1378             _cube_set_names ($type, y => $y, $z, $x),
1379             _cube_set_names ($type, z => $z, $x, $y)) . ' ';
1380             }
1381             }
1382             }
1383 0         0 $self->set (topology => $topo, columns => $size, rows => $size);
1384             }
1385 2         19 $self->set (symbols => join ' ', '.', 1 .. $self->{largest_set});
1386 2         6 return;
1387             }
1388              
1389             sub _cube_set_names {
1390 0     0   0 my ( $order, $name, $x, $y, $z ) = @_;
1391 0         0 my $tplt = sprintf '%s%d%%s%%d', $name, $x;
1392 0         0 return map {sprintf $tplt, @$_} [r => $y], [c => $z],
  0         0  
1393             [s => floor ($y / $order) * $order + floor ($z / $order)]
1394             }
1395              
1396             sub _set_latin {
1397             ## my ( $self, $name, $size ) = @_;
1398 2     2   5 my ( $self, undef, $size ) = @_; # Name unused
1399 2         4 my $syms = '.';
1400 2         4 my $topo = '';
1401 2         4 my $letter = 'A';
1402 2         8 for (my $row = 0; $row < $size; $row++) {
1403 13         15 $syms .= " @{[$letter++]}";
  13         33  
1404 13         34 for (my $col = 0; $col < $size; $col++) {
1405 97         220 $topo .= sprintf ' r%d,c%d', $row, $col;
1406             }
1407             }
1408 2         5 substr ($topo, 0, 1, '');
1409 2         8 $self->set (columns => $size, rows => $size, symbols => $syms,
1410             topology => $topo);
1411 2         7 return;
1412             }
1413              
1414             sub _set_null {
1415             ## my ( $self, $name, $value ) = @_;
1416 0     0   0 my ( $self, undef, $value ) = @_; # Name unused
1417 0 0       0 my ($size, $columns, $rows) = ref $value ? @$value : split ',', $value;
1418 0         0 $self->{cell} = []; # The cells themselves.
1419 0         0 $self->{set} = {}; # The sets themselves.
1420 0         0 $self->{largest_set} = 0;
1421 0         0 $self->{intersection} = {};
1422 0         0 $self->{cells_unused} = $size;
1423 0         0 foreach my $cell_inx (0 .. $size - 1) {
1424 0         0 my $cell = {membership => [], index => $cell_inx};
1425 0         0 push @{$self->{cell}}, $cell;
  0         0  
1426             }
1427 0         0 delete $self->{backtrack_stack}; # Force setting of new problem.
1428 0 0       0 defined $columns and $self->set (columns => $columns);
1429 0 0       0 defined $rows and $self->set (rows => $rows);
1430 0         0 return;
1431             }
1432              
1433             sub _set_number {
1434 23     23   60 my ( $self, $name, $value ) = @_;
1435 23 50       52 _looks_like_number ($value) or croak <
1436             Error - Attribute $name must be numeric.
1437             eod
1438 23         59 $self->{$name} = $value;
1439 23         57 return;
1440             }
1441              
1442             sub _set_quincunx {
1443             ## my ( $self, $name, $value ) = @_;
1444 0     0   0 my ( $self, undef, $value ) = @_; # Name unused
1445 0 0       0 my ($order, $gap) = ref $value ? @$value : split ',', $value;
1446 0 0       0 $order =~ m/\D/ and croak <
1447             Error - The quincunx order must be an integer.
1448             eod
1449 0 0       0 if (defined $gap) {
1450 0 0       0 $gap =~ m/\D/ and croak <
1451             Error - The quincunx gap must be an integer.
1452             eod
1453 0 0       0 $gap > $order - 2 and croak <
1454             Error - The quincunx gap must not be greater than the order ($order) - 2.
1455             eod
1456 0 0       0 $gap % 2 == $order % 2 or croak <
1457             Error - The gap must be the same parity (odd or even) as the order.
1458             eod
1459             } else {
1460 0         0 $gap = $order % 2;
1461             }
1462 0         0 my $cols = ($order * 2 + $gap) * $order;
1463 0         0 $self->set(null => [$cols * $cols, $cols, $cols]);
1464 0         0 my $osq = $order * $order;
1465 0         0 $self->set(symbols => join (' ', '.', 1 .. $osq));
1466 0         0 my @squares = do { # Squares in terms of index of top left corner
1467 0         0 my $offset = ($order + $gap) * $order;
1468 0         0 my $inset = ($order - ($order - $gap) / 2) * $order;
1469             (
1470 0         0 0, # Top left square
1471             $offset, # Top right square
1472             $inset * $cols + $inset, # Middle square
1473             $offset * $cols, # Bottom left square
1474             $offset * ($cols + 1), # Bottom right square
1475             )
1476             };
1477 0         0 my $limit = $osq - 1;
1478 0         0 my @colinx = map {$_ * $cols} 0 .. $limit;
  0         0  
1479 0         0 my @sqinx = map {$_ .. $_ + $order - 1} map {$_ * $cols} 0 .. $order - 1;
  0         0  
  0         0  
1480 0         0 my @sqloc = map {$_ * $order} @sqinx;
  0         0  
1481 0         0 my @sqgened; # 's' sets generated, by origin cell.
1482             # Crete the row, column, and square sets. These have the same names
1483             # as those created by the corresponding 'sudoku' topology, but with
1484             # 'g0' .. 'g4' prepended, representing the five individual
1485             # 'standard' sudoku grids. For topology 'quincunx 3', the top left
1486             # cell is in sets g0c0,g0r0,g0s0, the top right in g1c8,g1r0,g1s2,
1487             # and so on. Because some of the 's' sets are duplicates, the
1488             # higher-numbered ones are supressed. In topology 'quincunx 3', set
1489             # g0s8 is the same as g2s0, so the latter is supressed.
1490 0         0 foreach my $grid (0 .. $#squares) {
1491 0         0 my $sqr = $squares[$grid];
1492 0         0 foreach my $inx (0 .. $limit) {
1493 0         0 my $offset = $inx * $cols;
1494 0         0 my $o1 = $offset + $sqr;
1495 0         0 $self->add_set("g${grid}r$inx" => $o1 .. $o1 + $limit);
1496 0         0 $self->add_set("g${grid}c$inx" => map {$_ + $inx + $sqr}
  0         0  
1497             @colinx);
1498 0         0 $o1 = $sqloc[$inx] + $sqr;
1499             $sqgened[$o1]++
1500 0 0       0 or $self->add_set("g${grid}s$inx" => map {$_ + $o1}
  0         0  
1501             @sqinx);
1502             }
1503             }
1504 0         0 return;
1505             }
1506              
1507             sub _set_status_value {
1508 21     21   73 my ( $self, $name, $value ) = @_;
1509 21 50       89 _looks_like_number ($value) or croak <
1510             Error - Attribute $name must be numeric.
1511             eod
1512 21 50 33     128 ($value < 0 || $value >= @status_values) and croak <
1513             Error - Attribute $name must be greater than or equal to 0 and
1514 0         0 less than @{[scalar @status_values]}
1515             eod
1516 21         68 $self->{status_value} = $value;
1517 21         57 $self->{status_text} = $status_values[$value];
1518 21         64 return;
1519             }
1520              
1521             sub _set_sudoku {
1522             ## my ( $self, $name, $order ) = @_;
1523 5     5   18 my ( $self, undef, $order ) = @_; # Name unused
1524 5         27 $self->set( brick => [ $order, $order ] );
1525 5         20 return;
1526             }
1527              
1528             sub _set_sudokux {
1529             ## my ( $self, $name, $order ) = @_;
1530 1     1   3 my ( $self, undef, $order ) = @_; # Name unused
1531 1         6 $self->set (sudoku => $order);
1532 1         3 my $size = $order * $order;
1533 1         3 my $size_minus_1 = $size - 1;
1534 1         2 my $size_plus_1 = $size + 1;
1535 1         4 $self->add_set (d0 => map {$_ * $size_plus_1} 0 .. $size_minus_1);
  9         25  
1536 1         4 $self->add_set (d1 => map {$_ * $size_minus_1} 1 .. $size);
  9         17  
1537 1         4 return;
1538             }
1539              
1540             sub _set_symbols {
1541             ## my ( $self, $name, $value ) = @_;
1542 13     13   35 my ( $self, undef, $value ) = @_; # Name unused
1543 13         157 my @lst = split '\s+', $value;
1544 13         33 my %hsh;
1545 13         23 my $inx = 0;
1546 13         24 my $maxlen = 0;
1547 13         36 foreach (@lst) {
1548 142 50       254 defined $_ or next;
1549 142 50       276 m/,/ and croak <
1550             Error - Symbols may not contain commas.
1551             eod
1552 142 50       289 exists $hsh{$_} and croak <
1553             Error - Symbol '$_' specified more than once.
1554             eod
1555 142         277 $hsh{$_} = $inx++;
1556 142         339 $maxlen = max ($maxlen, length ($_));
1557             }
1558 13         62 $self->{symbol_list} = \@lst;
1559 13         61 $self->{symbol_hash} = \%hsh;
1560 13         36 $self->{symbol_number} = scalar @lst;
1561 13         35 $self->{biggest_spec} = $self->{biggest_symbol} = $maxlen;
1562 13         40 $self->{allowed_symbols} = {};
1563 13         42 return;
1564             }
1565              
1566             sub _set_topology {
1567             ## my ( $self, $name, @args ) = @_;
1568 11     11   32 my ( $self, undef, @args ) = @_; # Name unused
1569 11         1130 $self->{cell} = []; # The cells themselves.
1570 11         411 $self->{set} = {}; # The sets themselves.
1571 11         25 $self->{largest_set} = 0;
1572 11         553 $self->{intersection} = {};
1573 11         20 $self->{cells_unused} = 0;
1574 11         27 my $cell_inx = 0;
1575 11         32 foreach my $cell_def (map {split '\s+', $_} @args) {
  11         426  
1576 938         2548 my $cell = {membership => [], index => $cell_inx};
1577 938         1379 push @{$self->{cell}}, $cell;
  938         1550  
1578 938         2193 foreach my $name (sort grep {$_ ne ''} split ',', $cell_def) {
  2717         5763  
1579 2717         3600 foreach my $other (@{$cell->{membership}}) {
  2717         4523  
1580 2620         4329 my $int = "$other,$name";
1581 2620   100     8854 $self->{intersection}{$int} ||= [];
1582 2620         3396 push @{$self->{intersection}{$int}}, $cell_inx;
  2620         5244  
1583             }
1584 2717         3602 push @{$cell->{membership}}, $name;
  2717         4848  
1585 2717   100     6491 my $set = $self->{set}{$name} ||=
1586             {name => $name, membership => []};
1587 2717         3527 push @{$set->{membership}}, $cell_inx;
  2717         4598  
1588             $self->{largest_set} = max ($self->{largest_set},
1589 2717         3783 scalar @{$set->{membership}});
  2717         6258  
1590             }
1591 938 50       1464 @{$cell->{membership}} or $self->{cells_unused}++;
  938         1736  
1592 938         1502 $cell_inx++;
1593             }
1594 11         497 delete $self->{backtrack_stack}; # Force setting of new problem.
1595 11         52 return;
1596             }
1597              
1598 1     1   5 sub _set_value {$_[0]->{$_[1]} = $_[2]; return;}
  1         5  
1599              
1600             =head2 solution
1601              
1602             $string = $su->solution();
1603              
1604             This method returns the next solution to the problem, or undef if there
1605             are no further solutions. The solution is a blank-delimited list of the
1606             symbols each cell contains, with line breaks as specified by the
1607             'columns' attribute. If the problem() method has not been called,
1608             an exception is thrown.
1609              
1610             Status values set:
1611              
1612             SUDOKU_SUCCESS
1613             SUDOKU_NO_SOLUTION
1614             SUDOKU_TOO_HARD
1615              
1616             =cut
1617              
1618             sub solution {
1619 19     19 1 58 my ( $self ) = @_;
1620              
1621 19 50       61 $self->{backtrack_stack} or croak <
1622             Error - You cannot call the solution() method unless you have specified
1623             the problem via the problem() method.
1624             eod
1625              
1626 19 50       61 $self->{debug} and print <
1627             Debug solution - entering method. Stack depth = @{[
1628 0         0 scalar @{$self->{backtrack_stack}}]}
  0         0  
1629             eod
1630              
1631 19         64 return $self->_constrain ();
1632             }
1633              
1634             =head2 steps
1635              
1636             $string = $su->steps();
1637              
1638             =for comment help syntax-highlighting editor "
1639              
1640             This method returns the steps taken to solve the problem. If no
1641             solution was found, it returns the steps taken to determine this. If
1642             called in list context, you get an actual copy of the list. The first
1643             element is the name of the constraint applied:
1644              
1645             F = forced: only one value works in this cell;
1646             N = numeration or necessary: this is the only cell
1647             that can supply the given value;
1648             B = box claim: if a candidate number appears in only
1649             one row or column of a given box, it can be
1650             eliminated as a candidate in that row or column
1651             but outside that box;
1652             T = tuple, which is a generalization of the concept
1653             pair, triple, and so on. These come in two
1654             varieties for a given size of the tuple N:
1655             naked: N cells contain among them N values, so
1656             no cells outside the tuple can supply those
1657             values.
1658             hidden: N cells contain N values which do not
1659             occur outside those cells, so any other values
1660             in the tuple are supressed.
1661             ? = no constraint: generated in backtrack mode.
1662              
1663             See C and
1664             L for fuller
1665             definitions of the constraints and how they are applied. The
1666             L section addresses why the former
1667             URL is not an actual POD link.
1668              
1669             The second value is the cell number, as defined by the topology
1670             setting. For the 'sudoku' and 'latin' settings, the cells are
1671             numbered from zero, row-by-row. If you did your own topology, the
1672             first cell you defined is 0, the second is 1, and so on.
1673              
1674             The third value is the value assigned to the cell. If returned in
1675             list context, it is the number assigned to the cell's symbol. If
1676             in scalar context, it is the symbol itself.
1677              
1678             =for comment help syntax-highlighting editor "
1679              
1680             =cut
1681              
1682             sub steps {
1683 1     1 1 4 my ( $self ) = @_;
1684 0         0 return wantarray ? (@{$self->{backtrack_stack}}) :
1685             defined wantarray ?
1686 1 50       6 $self->_format_constraint (@{$self->{backtrack_stack}}) :
  1 50       7  
1687             undef;
1688             }
1689              
1690             =head2 unload
1691              
1692             $string = $su->unload();
1693              
1694             This method returns either the current puzzle or the current solution,
1695             depending on whether the solution() method has been called since the
1696             puzzle was loaded.
1697              
1698             =cut
1699              
1700             sub unload {
1701 2     2 1 8 my ( $self ) = @_;
1702 2         8 return $self->_unload ()
1703             }
1704              
1705             ########################################################################
1706              
1707             # Private methods and subroutines.
1708              
1709             # $status_value = $su->_constrain ();
1710              
1711             # This method applies all possible constraints to the current
1712             # problem, placing them on the backtrack stack. The backtrack
1713             # algorithm needs to remove these when backtracking. The return
1714             # is false if we ran out of constraints, or true if we found
1715             # a constraint that could not be satisfied.
1716              
1717             my %constraint_method = (
1718             '?' => '_constraint_backtrack',
1719             );
1720              
1721             sub _constrain {
1722 19     19   42 my ( $self ) = @_;
1723 19   50     66 my $stack = $self->{backtrack_stack} ||= []; # May hit this
1724             # when initializing.
1725 19   50     57 my $used = $self->{constraints_used} ||= {};
1726 19         30 my $iterations;
1727             $iterations = $self->{iteration_limit}
1728 19 50       55 if $self->{iteration_limit} > 0;
1729              
1730             $self->{no_more_solutions} and
1731 19 50       47 return $self->_unload (undef, SUDOKU_NO_SOLUTION);
1732              
1733 19 100       36 @{$self->{backtrack_stack}} and do {
  19         56  
1734 1 50       6 $self->_constraint_remove and
1735             return $self->_unload (undef, SUDOKU_NO_SOLUTION);
1736             };
1737              
1738 18 50       52 $self->{cells_unassigned} or do {
1739 0         0 $self->{no_more_solutions} = 1;
1740 0         0 return $self->_unload ('', SUDOKU_SUCCESS);
1741             };
1742              
1743 18         30 my $number_of_cells = @{$self->{cell}};
  18         38  
1744              
1745             constraint_loop:
1746             { # Begin outer constraint loop.
1747              
1748 18         34 foreach my $constraint (qw{F N B T ?}) {
  370         822  
1749 716 50       981 confess <{cell}} != $number_of_cells;
  716         1865  
1750             Programming error - Before trying $constraint constraint.
1751             We started with $number_of_cells cells, but now have @{[
1752 0         0 scalar @{$self->{cell}}]}.
  0         0  
1753             eod
1754 716   33     3176 my $method = $constraint_method{$constraint} ||
1755             "_constraint_$constraint";
1756 716 50       2632 my $rslt = $self->$method () or next;
1757 716 100       1725 @$rslt or next;
1758 370         728 foreach my $constr (@$rslt) {
1759 1155 50       2204 if (ref $constr) {
1760 1155         2046 push @$stack, $constr;
1761 1155         2286 $used->{$constr->[0]}++
1762             } else {
1763 0 0       0 my $rslt = $self->_constraint_remove or
1764             redo constraint_loop;
1765 0         0 return $self->_unload ('', $rslt);
1766             }
1767             }
1768             $self->{cells_unassigned} or
1769 370 100       991 return $self->_unload ('', SUDOKU_SUCCESS);
1770 352         887 redo constraint_loop;
1771             }
1772              
1773             } # end outer constraint loop.
1774              
1775 0         0 $self->set (status_value => SUDOKU_TOO_HARD);
1776 0         0 return;
1777             }
1778              
1779             # Constraint executors:
1780             # These all return a reference to the constraints to be stacked,
1781             # provided progress was made. Otherwise they return 0. At the
1782             # point a contradiction is found, they push 'backtrack' on the
1783             # end of the list to be returned, and return immediately.
1784              
1785             # F constraint - only one value possible. Unlike the other
1786             # constraints, we keep iterating this one until we make no
1787             # progress.
1788              
1789             sub _constraint_F {
1790 370     370   716 my ( $self ) = @_;
1791 370         619 my @stack;
1792 370         593 my $done = 1;
1793              
1794 370         749 while ($done) {
1795 571         1006 $done = 0;
1796 571         869 my $inx = 0; # Cell index.
1797 571         835 foreach my $cell (@{$self->{cell}}) {
  571         1079  
1798 69447 100       127662 next if $cell->{content}; # Skip already-assigned cells.
1799 31870 50       41659 next unless @{$cell->{membership}}; # Skip unused cells.
  31870         58192  
1800 31870         43583 my $pos = 0;
1801 31870 100       40061 foreach (values %{$cell->{possible}}) {$_ or $pos++};
  31870         66018  
  404123         682577  
1802 31870 100       55541 if ($pos > 1) { # > 1 possibility. Can't apply.
    50          
1803             } elsif ($pos == 1) { # Exactly 1 possibility. Apply.
1804 853         1250 my $val;
1805 853         1135 foreach (keys %{$cell->{possible}}) {
  853         3052  
1806 4841 100       8964 next if $cell->{possible}{$_};
1807 853         1247 $val = $_;
1808 853         1197 last;
1809             }
1810 853 50       2132 $self->_try ($cell, $val) and confess <
1811             Programming error - Passed 'F' constraint but _try failed.
1812             eod
1813 853         2310 my $constraint = [F => [$inx, $val]];
1814             $self->{debug} and
1815 853 50       1798 print '# ', $self->_format_constraint ($constraint);
1816 853         1138 $done++;
1817 853         1658 push @stack, $constraint;
1818 853 100       1957 $self->{cells_unassigned} or do {$done = 0; last};
  18         27  
  18         51  
1819             } else { # No possibilities. Backtrack.
1820 0 0       0 $self->{debug} and print <
1821             Debug - Cell $inx has no possible values. Backtracking.
1822             eod
1823 0 0       0 $self->{debug} > 1 and do {
1824 0         0 local $Data::Dumper::Terse = 1;
1825 0         0 print Dumper $cell;
1826             };
1827 0         0 push @stack, 'backtrack';
1828 0         0 $done = 0;
1829 0         0 last;
1830             }
1831             } continue {
1832 69429         98869 $inx++;
1833             }
1834             }
1835 370         1300 return \@stack;
1836             }
1837              
1838             # N constraint - the only cell which supplies a necessary value.
1839              
1840             sub _constraint_N {
1841 302     302   635 my ( $self ) = @_;
1842 302         487 while (my ($name, $set) = each %{$self->{set}}) {
  4090         11805  
1843 4054         5530 my @suppliers;
1844 4054         5579 foreach my $inx (@{$set->{membership}}) {
  4054         7817  
1845 52219         78866 my $cell = $self->{cell}[$inx];
1846 52219 100       98186 next if $cell->{content};
1847             # No need to check @{$cell->{membership}}, since the cell is
1848             # known to be a member of set $name.
1849 26229         35547 while (my ($val, $count) = each %{$cell->{possible}}) {
  381128         857127  
1850 354899 100       638476 next if $count;
1851 102896   100     227776 $suppliers[$val] ||= [];
1852 102896         131526 push @{$suppliers[$val]}, $inx;
  102896         197196  
1853             }
1854             }
1855 4054         6367 my $limit = @suppliers;
1856 4054         8887 for (my $val = 1; $val < $limit; $val++) {
1857 43623 100 100     85998 next unless $suppliers[$val] && @{$suppliers[$val]} == 1;
  25495         80157  
1858 266         538 my $inx = $suppliers[$val][0];
1859 266 0       1039 $self->_try ($inx, $val) and confess <{debug} ? <
    50          
1860             Programming error - Cell $inx passed 'N' constraint but try of
1861             $self->{symbol_list}[$val] failed.
1862             eod
1863 0         0 @{[$self->_unload
1864             ]} set: $name
1865 0         0 cell: @{[Dumper ($self->{cell}[$inx])]}
1866             eod
1867 266         826 my $constraint = [N => [$inx, $val]];
1868             $self->{debug} and
1869 266 50       690 print '# ', $self->_format_constraint ($constraint);
1870 266         405 keys %{$self->{set}}; # Reset iterator.
  266         513  
1871 266         1391 return [$constraint];
1872             }
1873             }
1874 36         154 return [];
1875             }
1876              
1877             # B constraint - "box claim". Given two sets whose intersection
1878             # contains more than one cell, if all cells which can contribute
1879             # a given value to one set are in the intersection, no cell in
1880             # the second set can contribute that value. Note that this
1881             # constraint does NOT actually assign a value to a cell, it just
1882             # eliminates possible values. The name is because on the
1883             # "standard" sudoku layout one of the sets is always a box; the
1884             # other can be a row or a column.
1885              
1886             sub _constraint_B {
1887 36     36   89 my ( $self ) = @_;
1888 36         64 my $done = 0;
1889 36         78 while (my ($int, $cells) = each %{$self->{intersection}}) {
  6197         17650  
1890 6189 100       13063 next unless @$cells > 1;
1891 2089         3056 my @int_supplies; # Values supplied by the intersection
1892             my %int_cells; # Cells in the intersection
1893 2089         3748 foreach my $inx (@$cells) {
1894 7901 100       17488 next if $self->{cell}[$inx]{content};
1895             # No need to check @{$cell->{membership}}, since the cell is
1896             # known to be a member of at least two sets.
1897 4254         8859 $int_cells{$inx} = 1;
1898 4254         5805 while (my ($val, $imposs) = each %{
1899 67836         163807 $self->{cell}[$inx]{possible}}) {
1900 63582 100       124656 $int_supplies[$val] = 1 unless $imposs;
1901             }
1902             }
1903 2089         3260 my %ext_supplies; # Intersection values also supplied outside.
1904             my %ext_cells; # Cells not in the intersection.
1905 2089         5489 my @set_names = split ',', $int;
1906 2089         3422 foreach my $set (@set_names) {
1907 4178         7990 $ext_supplies{$set} = [];
1908 4178         6794 $ext_cells{$set} = [];
1909 4178         5542 foreach my $inx (@{$self->{set}{$set}{membership}}) {
  4178         9658  
1910 60482 100       110574 next if $int_cells{$inx}; # Skip cells in intersection.
1911 51974 100       104309 next if $self->{cell}[$inx]{content};
1912 24557         31347 push @{$ext_cells{$set}}, $inx;
  24557         48741  
1913 24557         33678 while (my ($val, $imposs) = each %{
1914 399468         969198 $self->{cell}[$inx]{possible}}) {
1915 374911 100 100     835179 $ext_supplies{$set}[$val] = 1
1916             if !$imposs && $int_supplies[$val];
1917             }
1918             }
1919             }
1920 2089         5590 for (my $val = 1; $val < @int_supplies; $val++) {
1921 23332 100       47548 next unless $int_supplies[$val];
1922 9989         15166 my @occurs_in = grep {$ext_supplies{$_}[$val]} @set_names;
  19978         37551  
1923 9989 100 100     44845 next unless @occurs_in && @occurs_in < @set_names;
1924 28         55 my %cells_claimed;
1925 28         83 foreach my $set (@occurs_in) {
1926 28         46 foreach my $inx (@{$ext_cells{$set}}) {
  28         60  
1927 151 100       345 next if $self->{cell}[$inx]{possible}{$val};
1928 72         159 $cells_claimed{$inx} = 1;
1929 72         116 $self->{cell}[$inx]{possible}{$val} = 1;
1930 72         114 $done++;
1931             }
1932             }
1933 28 50       74 next unless $done;
1934 28         311 my $constraint = [B => [[sort keys %cells_claimed], $val]];
1935             $self->{debug} and
1936 28 50       137 print '# ', $self->_format_constraint ($constraint);
1937 28         59 keys %{$self->{intersection}}; # Reset iterator.
  28         65  
1938 28         248 return [$constraint];
1939             }
1940             }
1941 8         41 return []
1942             }
1943              
1944             # T constraint - "tuple" (double, triple, quad). These come in
1945             # two flavors, "naked" and "hidden". Considering only pairs for
1946             # the moment:
1947             # A "naked pair" is two cells in the same set which contain the same
1948             # pair of possibilities, and only those possibilities. These
1949             # possibilities are then excluded from other cells in the set.
1950             # A "hidden pair" is when there is a pair of values which can only
1951             # be contributed to the set by one or the other of a pair of
1952             # cells. These cells then must supply these values, and any other
1953             # values supplied by cells in the pair can be eliminated.
1954             # For higher groups (triples, quads ...) the rules generalize, except
1955             # that all of the candidate values need not be present in all of
1956             # the cells under consideration; it is only necessary that none
1957             # of the candidate values appears outside the cells under
1958             # consideration.
1959             #
1960             # Glenn Fowler of AT&T (http://www.research.att.com/~gsf/sudoku/)
1961             # lumps all these together. But he refers to Angus Johnson
1962             # (http://www.angusj.com/sudoku/hints.php) for the details, and
1963             # Angus separates naked and hidden tuples.
1964              
1965             sub _constraint_T {
1966 8     8   20 my ( $self ) = @_;
1967 8         24 my @tuple; # Tuple indices
1968             my %vacant; # Empty cells by set. $vacant{$set} = [$cell ...]
1969 8         0 my %contributors; # Number of cells which can contrib value, by set.
1970 8         17 my $syms = @{$self->{symbol_list}};
  8         24  
1971              
1972 8         22 while (my ($name, $set) = each %{$self->{set}}) {
  310         974  
1973 4062         7486 my @open = grep {!$_->{content}}
1974 302 100       413 map {$self->{cell}[$_]} @{$set->{membership}}
  4062         6125  
  302         600  
1975             or next;
1976             # No need to check @{$_->{membership}} in the grep, since cell
1977             # $_ is known to be a member of set $name.
1978 281         601 foreach my $cell (@open) {
1979 2025         3692 for (my $val = 1; $val < $syms; $val++) {
1980 29607 100       63038 $cell->{possible}{$val} and next;
1981 7685   100     13461 $contributors{$name} ||= [];
1982 7685         13903 $contributors{$name}[$val]++;
1983             }
1984             }
1985 281 100       394 @{$contributors{$name}} = map {$_ || 0} @{$contributors{$name}};
  281         599  
  3814         8225  
  281         513  
1986 281         578 $vacant{$name} = \@open;
1987 281   100     800 $tuple[scalar @open] ||= [map {[$_]} 0 .. $#open];
  424         915  
1988             }
1989              
1990 8         54 for (my $order = 2; $order <= $self->{max_tuple}; $order++) {
1991 8         33 for (my $inx = 1; $inx < @tuple; $inx++) {
1992 79 100       193 next unless $tuple[$inx];
1993 60         98 my $max = $inx - 1;
1994 364         561 $tuple[$inx] = [map {my @tpl = @$_;
1995 364         585 map {[@tpl, $_]} $tpl[-1] + 1 .. $max}
  1645         3268  
1996 60         87 grep {$_->[-1] < $max} @{$tuple[$inx]}];
  424         728  
  60         117  
1997 60 50       181 $tuple[$inx] = undef unless @{$tuple[$inx]};
  60         198  
1998             }
1999              
2000             # Okay, I have generated the blasted tuples. Now I need to take
2001             # the union of all values provided by the tuple of cells. If the
2002             # number of values in this union is equal to the current order, I
2003             # have potentially found a naked tuple, and if this lets me
2004             # eliminate any values outside the tuple I can apply the
2005             # constraint. If the number of values inside the union is greater
2006             # than the current order, I need to consider whether any tuple of
2007             # supplied values is not represented outside the cell tuple; if
2008             # so, I have a hidden tuple and can eliminate the superfluous
2009             # values.
2010              
2011 8         97 foreach my $name (keys %vacant) {
2012 87         157 my $open = $vacant{$name};
2013 87 50       187 next unless $tuple[@$open];
2014 87         127 my $contributed = $contributors{$name};
2015 87         119 foreach my $tuple (@{$tuple[@$open]}) {
  87         153  
2016 1332         1746 my @tcontr; # number of times each value
2017             # contributed by the tuple.
2018 1332         2093 foreach my $inx (@$tuple) {
2019 2664         3753 my $cell = $open->[$inx];
2020 2664         4818 for (my $val = 1; $val < $syms; $val++) {
2021 37794 100       79990 next if $cell->{possible}{$val};
2022 10581         18897 $tcontr[$val]++;
2023             }
2024             }
2025 1332 100       2018 @tcontr = map {$_ || 0} @tcontr;
  18634         39850  
2026              
2027             # At this point, @tcontr contains how many cells in the tuple
2028             # contribute each value. Calculate the number of discrete values
2029             # the tuple can contribute.
2030              
2031             # If the number of discrete values contributed by the tuple is
2032             # equal to the current order, we have a naked tuple. We have an
2033             # "effective" naked tuple if at least one of the values
2034             # contributed by the tuple occurs outside the tuple. We can
2035             # determine this by subtracting the values in @tcontr from the
2036             # corresponding values in @$contributed; if we get a positive
2037             # result for any cell, we have an "effective" naked tuple.
2038              
2039 1332         2028 my $discrete = grep {$_} @tcontr;
  18634         24485  
2040 1332         1861 my $constraint;
2041             my @tuple_member;
2042 1332 100       2755 if ($discrete == $order) {
    50          
2043 22         51 for (my $val = 1; $val < @tcontr; $val++) {
2044 162 100 100     459 next unless $tcontr[$val] &&
2045             $contributed->[$val] > $tcontr[$val];
2046              
2047             # At this point we know we have an "effective" naked tuple.
2048              
2049 5   100     23 $constraint ||= ['T', 'naked', $order];
2050 5 100       13 @tuple_member or map {$tuple_member[$_] = 1} @$tuple;
  6         14  
2051 5         8 my @ccl;
2052 5         14 for (my $inx = 0; $inx < @$open; $inx++) {
2053             next if $tuple_member[$inx] ||
2054 23 100 100     73 $open->[$inx]{possible}{$val};
2055 7         13 $open->[$inx]{possible}{$val} = 1;
2056 7         14 --$contributed->[$val];
2057 7         19 push @ccl, $open->[$inx]{index};
2058             }
2059 5 50       62 push @$constraint, [\@ccl, $val] if @ccl;
2060             }
2061              
2062             # If the number of discrete values is greater than the current
2063             # order, we may have a hidden tuple. The test for an "effective"
2064             # hidden tuple involves massaging @tcontr against @$contributed in
2065             # some way to find a tuple of values within the tuple of cells
2066             # which do not occur outside it.
2067              
2068             } elsif ($discrete > $order) {
2069 1310         1752 my $within = 0; # Number of values occuring only
2070             # within tuple.
2071 1310         2458 for (my $val = 1; $val < @tcontr; $val++) {
2072 17140 100 100     45952 $within++ if $tcontr[$val] &&
2073             $contributed->[$val] == $tcontr[$val];
2074             }
2075 1310 100       3334 next unless $within >= $order;
2076 5         19 $constraint = ['T', 'hidden', $order];
2077 5         10 map {$tuple_member[$_] = 1} @$tuple;
  10         30  
2078 5         23 for (my $val = 1; $val < @tcontr; $val++) {
2079 54 100 100     169 next unless $tcontr[$val] &&
2080             $contributed->[$val] > $tcontr[$val];
2081 14         24 my @ccl;
2082 14         43 for (my $inx = 0; $inx < @$open; $inx++) {
2083             next unless $tuple_member[$inx]
2084 97 100 100     260 && !$open->[$inx]{possible}{$val}
2085             ;
2086 16         32 $open->[$inx]{possible}{$val} = 1;
2087 16         27 --$contributed->[$val];
2088 16         28 --$tcontr[$val];
2089 16         50 push @ccl, $open->[$inx]{index};
2090             }
2091              
2092 14 50       97 push @$constraint, [\@ccl, $val] if @ccl;
2093             }
2094             }
2095              
2096 27 100       91 next unless $constraint;
2097             $self->{debug} and
2098 8 50       35 print '# ', $self->_format_constraint ($constraint);
2099 8         446 return [$constraint];
2100             } # Next tuple
2101             } # Next set containing vacant cells
2102             } # Next order
2103              
2104 0         0 return [];
2105             }
2106              
2107             # ? constraint - initiate backtracking.
2108              
2109             sub _constraint_backtrack {
2110 0     0   0 my ( $self ) = @_;
2111             ## --$iterations >= 0 or return $self->_unload ('', SUDOKU_TOO_HARD)
2112             ## if defined $iterations;
2113 0         0 my @try;
2114 0         0 my $syms = @{$self->{symbol_list}};
  0         0  
2115 0         0 foreach my $cell (@{$self->{cell}}) {
  0         0  
2116 0 0       0 next if $cell->{content};
2117 0 0       0 next unless @{$cell->{membership}};
  0         0  
2118 0         0 my $possible = 0;
2119 0         0 for (my $val = 1; $val < $syms; $val++) {
2120 0 0       0 $possible++ unless $cell->{possible}{$val};
2121             }
2122 0 0       0 $possible or return ['backtrack'];
2123 0         0 push @try, [$cell, $possible];
2124             }
2125 0         0 @try = map {$_->[0]} sort {
2126 0 0       0 $a->[1] <=> $b->[1] || $a->[0]{index} <=> $b->[0]{index}} @try;
  0         0  
2127 0         0 my $cell = $try[0];
2128 0         0 for (my $val = 1; $val < $syms; $val++) {
2129 0 0       0 next if $cell->{possible}{$val};
2130 0 0       0 $self->_try ($cell, $val) and confess <
2131             Programming error - Value $val illegal in cell $cell->{index} for ? constraint, but
2132             \$self->{possible}{$val} = $self->{possible}{$val}
2133             eod
2134 0         0 my $constraint = ['?' => [$cell->{index}, $val]];
2135             $self->{debug}
2136 0 0       0 and print '# ', $self->_format_constraint ($constraint);
2137 0         0 return [$constraint];
2138             }
2139 0         0 return [];
2140             }
2141              
2142             # $status_value = $su->_constraint_remove ();
2143              
2144             # This method removes the topmost constraints from the backtrack
2145             # stack. It continues until the next item is a backtrack item or
2146             # the stack is empty. It returns true (SUDOKU_NO_SOLUTION,
2147             # actually) if the stack is emptied, or false (SUDOKU_SUCCESS,
2148             # actually) if it stops because it found a backtrack item.
2149              
2150             # The following arguments may be passed, for use in preparing
2151             # a generated problem:
2152             # - minimum number of cells to leave occupied (no lower limit
2153             # if this is undefined);
2154             # - maximum number of cells to leave occupied (no upper limit
2155             # if this is undefined);
2156             # - a reference to a hash of constraints that it is legal to
2157             # remove. The hash value is the number of times it is
2158             # legal to remove that constraint, or undef if it can
2159             # be removed any number of times.
2160              
2161             sub _constraint_remove {
2162 1     1   4 my ( $self, $min, $max, $removal_ok ) = @_;
2163 1 50       5 $min and $min = @{$self->{cell}} - $min;
  0         0  
2164 1 50       3 $max and $max = @{$self->{cell}} - $max;
  0         0  
2165 1 50       4 $self->{no_more_solutions} and return SUDOKU_NO_SOLUTION;
2166 1 50       5 my $stack = $self->{backtrack_stack} or return SUDOKU_NO_SOLUTION;
2167 1   50     4 my $used = $self->{constraints_used} ||= {};
2168 1         3 my $inx = @$stack;
2169 1         2 my $syms = @{$self->{symbol_list}};
  1         3  
2170 1 50 33     6 ($self->{debug} && $inx) and print <
2171             # Debug - Backtracking
2172             eod
2173 1         3 my $old = $inx;
2174 1         5 while (--$inx >= 0) {
2175 45 50 33     80 ($min && $self->{cells_unassigned} >= $min) and do {
2176 0 0       0 $self->{debug} and print <
2177             Debug - Hit minimum occupied cells - returning.
2178             eod
2179 0         0 return SUDOKU_SUCCESS;
2180             };
2181 45         70 my $constraint = $stack->[$inx][0];
2182 45 50       75 if ($removal_ok) {
2183             ($max && $self->{cells_unassigned} <= $max &&
2184             ## !$removal_ok->{$constraint} and next;
2185 0 0 0     0 !exists $removal_ok->{$constraint}) and next;
      0        
2186              
2187 0 0 0     0 if (!exists $removal_ok->{$constraint}) {
    0          
2188 0 0       0 $self->{debug} and print <
2189             Debug - Encountered constraint $constraint - returning.
2190             eod
2191 0         0 return SUDOKU_SUCCESS;
2192             } elsif (defined $removal_ok->{$constraint} &&
2193             --$removal_ok->{$constraint}) {
2194 0 0       0 $self->{debug} and print <
2195             Debug - Reached usage limit on $constraint - returning.
2196             eod
2197 0         0 return SUDOKU_SUCCESS;
2198             }
2199             } else {
2200 45 0 33     84 ($max && $self->{cells_unassigned} <= $max &&
      33        
2201             $constraint eq '?')
2202             and next;
2203             }
2204 45         66 --$used->{$constraint};
2205 45 50 66     116 if ($constraint eq 'F' || $constraint eq 'N') {
    0 0        
    0          
2206 45         57 foreach my $ref (reverse @{$stack->[$inx]}) {
  45         74  
2207 90 100       191 $self->_try ($ref->[0], 0) if ref $ref;
2208             }
2209             } elsif ($constraint eq 'B' || $constraint eq 'T') {
2210 0         0 foreach my $ref (reverse @{$stack->[$inx]}) {
  0         0  
2211 0 0       0 next unless ref $ref;
2212 0         0 my $val = $ref->[1];
2213 0         0 foreach my $inx (@{$ref->[0]}) {
  0         0  
2214 0         0 $self->{cell}[$inx]{possible}{$val} = 0;
2215             }
2216             }
2217             } elsif ($constraint eq '?') {
2218 0         0 my $start = $stack->[$inx][1][1] + 1;
2219 0         0 my $cell = $self->{cell}[$stack->[$inx][1][0]];
2220 0         0 $self->_try ($cell, 0);
2221 0 0       0 next if $removal_ok;
2222 0         0 for (my $val = $start; $val < $syms; $val++) {
2223 0 0       0 next if $cell->{possible}{$val};
2224 0 0       0 $self->_try ($cell, $val) and confess <
2225             Programming error - Try of $val in cell $cell->{index} failed, but
2226             \$cell->{possible}[$inx] = $cell->{possible}[$inx]
2227             eod
2228 0         0 $used->{$constraint}++;
2229 0         0 $stack->[$inx][1][0] = $cell->{index};
2230 0         0 $stack->[$inx][1][1] = $val;
2231 0 0       0 $self->{debug} and do {
2232 0         0 my $x = $self->_format_constraint ($stack->[$inx]);
2233 0         0 chomp $x;
2234 0         0 print <
2235 0         0 # Debug - Backtrack complete. @{[$old - @$stack]} constraints removed.
2236 0         0 # Resuming puzzle at stack depth @{[$inx + 1]} with
2237             # $self->{cells_unassigned} unassigned cells, guessing
2238             # $x
2239             eod
2240             };
2241 0         0 return SUDOKU_SUCCESS;
2242             }
2243 0         0 } else {confess <
2244             Programming Error - No code provided to remove constraint '$constraint' from stack.
2245             eod
2246             }
2247 45         113 pop @$stack;
2248             }
2249 1 50       6 $self->{debug} and print <
2250 0         0 # Debug - Backtrack complete. @{[$old - @$stack]} constraints removed.
2251             # No more solutions to the puzzle exist.
2252             eod
2253 1         2 $self->{no_more_solutions} = 1;
2254 1         7 return SUDOKU_NO_SOLUTION;
2255             }
2256              
2257             # $self->_deprecation_notice( $name );
2258             #
2259             # This method centralizes deprecation. Deprecation is driven of
2260             # the %deprecate hash. Level values are:
2261             # false - no warning
2262             # 1 - warn on first use
2263             # 2 - warn on each use
2264             # 3 - die on each use.
2265              
2266             {
2267              
2268             my %deprecate = (
2269             brick_third_argument => {
2270             message => 'Specifying 3 values for set( brick => ... ) is no longer allowed',
2271             level => 3,
2272             },
2273             );
2274              
2275             sub _deprecation_notice {
2276 0     0   0 my ( undef, $name ) = @_; # Invocant unused
2277 0 0       0 my $info = $deprecate{$name}
2278             or return;
2279             $info->{level}
2280 0 0       0 or return;
2281             $info->{level} >= 3
2282 0 0       0 and croak $info->{message};
2283             warnings::enabled( 'deprecated' )
2284 0 0       0 and carp $info->{message};
2285             $info->{level} == 1
2286 0 0       0 and $info->{level} = 0;
2287 0         0 return;
2288             }
2289              
2290             }
2291              
2292             # _format_constraint formats the given constraint for output.
2293              
2294             sub _format_constraint {
2295 1     1   6 my ($self, @args) = @_;
2296 1         2 my @steps;
2297 1         3 foreach (@args) {
2298 52         72 my @stuff;
2299 52         88 foreach (@$_) {
2300 104 50       173 last unless $_;
2301             push @stuff, ref $_ ?
2302             '[' . join (' ',
2303 0         0 ref $_->[0] ? '[' . join (', ', @{$_->[0]}) . ']' : $_->[0],
2304             ref $_->[1] ? '[' . join (', ',
2305 0         0 map {$self->{symbol_list}[$_]} @{$_->[1]}) . ']' :
  0         0  
2306 104 50       314 $self->{symbol_list}[$_->[1]],
    50          
    100          
2307             ) . ']' :
2308             $_;
2309             }
2310 52         184 push @steps, join (' ', @stuff) . "\n";
2311             }
2312 1         15 return join '', @steps;
2313             }
2314              
2315             # _looks_like_number is cribbed heavily from
2316             # Scalar::Util::looks_like_number by Graham Barr. This version
2317             # only accepts integers, but it is really here because
2318             # ActivePerl's Scalar::Util is too ancient to export
2319             # looks_like_number.
2320              
2321             sub _looks_like_number {
2322 44     44   119 ( local $_ ) = @_;
2323 44 50 33     228 return 0 if !defined ($_) || ref ($_);
2324 44 50       505 return 1 if m/^[+-]?\d+$/;
2325 0         0 return 0;
2326             }
2327              
2328             # _set_* subroutines are found right after the set() method.
2329              
2330             # $su->_try ($cell, $value)
2331              
2332             # This method inserts the given value in the given cell,
2333             # replacing the previous value if any, and doing all the
2334             # bookkeeping. If the given value is legal (meaning, if
2335             # it is zero or if it is unique in all sets the cell
2336             # belongs to), it returns 0. If not, it returns 1, but
2337             # does not undo the trial.
2338              
2339             sub _try {
2340 2815     2815   4943 my ( $self, $cell, $new ) = @_;
2341 2815 100       5716 $cell = $self->{cell}[$cell] unless ref $cell;
2342 2815 50       4913 defined $new
2343             or _fatal (
2344             "_try called for cell $cell->{index} with new value undefined");
2345 2815 50       5268 defined (my $old = $cell->{content}) or _fatal (
2346             "_try called with old cell $cell->{index} value undefined");
2347 2815         4122 my $rslt = eval {
2348 2815 100       5626 return 0 if $old == $new;
2349 1644 100       2980 if ($new) {
2350 1599         2159 foreach my $set (@{$cell->{membership}}) {
  1599         3037  
2351 4833 50       12070 return 1 if $self->{set}{$set}{content}[$new];
2352             }
2353             }
2354 1644         2660 $cell->{content} = $new;
2355 1644 100       2947 $old and $self->{cells_unassigned}++;
2356 1644 100       3089 $new and --$self->{cells_unassigned};
2357 1644         2215 foreach my $name (@{$cell->{membership}}) {
  1644         2810  
2358 4968         8161 my $set = $self->{set}{$name};
2359 4968         7210 --$set->{content}[$old];
2360 4968 100       8411 $old and do {
2361 135         178 $set->{free}++;
2362 135         170 foreach (@{$set->{membership}}) {
  135         209  
2363 1215         1909 --$self->{cell}[$_]{possible}{$old};
2364             }
2365             };
2366 4968         7907 $set->{content}[$new]++;
2367 4968 100       8638 $new and do {
2368 4833         6617 --$set->{free};
2369 4833         6667 foreach (@{$set->{membership}}) {
  4833         8808  
2370 50421         84546 $self->{cell}[$_]{possible}{$new}++;
2371             }
2372             };
2373             }
2374 1644         2743 return 0;
2375             };
2376 2815 50       5032 $@ and _fatal ("Eval failed in _try", $@);
2377 2815         5663 return $rslt;
2378             }
2379              
2380             # $string = $self->_unload (prefix, status_value)
2381              
2382             # This method unloads the current cell contents into a string.
2383             # The prefix is prefixed to the string, and defaults to ''.
2384             # If status_value is specified, it is set. If status_value is
2385             # specified and it is a failure status, undef is returned, and
2386             # the current cell contents are ignored.
2387              
2388             sub _unload {
2389 23     23   86 my ($self, $prefix, @args) = @_;
2390 23 100       86 defined $prefix or $prefix = '';
2391 23 100       72 @args and do {
2392 19         92 $self->set (status_value => $args[0]);
2393 19 100       60 $args[0] and return;
2394             };
2395 22         47 my $rslt = '';
2396 22         70 my $col = $self->{columns};
2397 22   33     83 my $row = $self->{rows} ||= floor (@{$self->{cell}} / $col);
  0         0  
2398 22         80 my $fmt = "%$self->{biggest_symbol}s";
2399 22         45 foreach (@{$self->{cell}}) {
  22         67  
2400 1894 100       3276 $col == $self->{columns} and $rslt .= $prefix;
2401             # was $self->{ignore_unused}
2402             $rslt .= ($self->{cells_unused} && !@{$_->{membership}}) ?
2403             sprintf ($fmt, ' ') :
2404 1894 50 33     5786 sprintf ($fmt, $self->{symbol_list}[$_->{content} || 0]);
      100        
2405 1894 100       3067 if (--$col > 0) {
2406             $rslt .= $self->{output_delimiter}
2407 1674         2608 } else {
2408             # was $self->{ignore_unused}
2409 220 50       412 $self->{cells_unused} and $rslt =~ s/\s+$//m;
2410 220         328 $rslt .= "\n";
2411 220         322 $col = $self->{columns};
2412 220 100       444 if (--$row <= 0) {
2413 29         65 $rslt .= "\n";
2414 29         69 $row = $self->{rows};
2415             }
2416             }
2417             }
2418 22         136 0 while chomp $rslt;
2419 22         42 $rslt .= "\n";
2420 22         485 return $rslt;
2421             }
2422              
2423             1;
2424              
2425             __END__