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   2594 use 5.006002; # For 'our', at least.
  2         11  
571              
572 2     2   9 use strict;
  2         2  
  2         32  
573 2     2   8 use warnings;
  2         3  
  2         54  
574              
575 2     2   16 use Exporter qw{ import };
  2         4  
  2         166  
576              
577             our $VERSION = '0.026_01';
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   12 use Carp;
  2         2  
  2         121  
589 2     2   1081 use Data::Dumper;
  2         11150  
  2         115  
590 2     2   13 use List::Util qw{first max reduce};
  2         4  
  2         180  
591 2     2   828 use POSIX qw{floor};
  2         11468  
  2         9  
592              
593 2     2   2346 use constant SUDOKU_SUCCESS => 0;
  2         3  
  2         91  
594 2     2   8 use constant SUDOKU_NO_SOLUTION => 1;
  2         4  
  2         87  
595 2     2   11 use constant SUDOKU_TOO_HARD => 2;
  2         4  
  2         71  
596 2     2   8 use constant SUDOKU_MULTIPLE_SOLUTIONS => 3;
  2         3  
  2         141  
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   12 use constant HASH_REF => ref {};
  2         2  
  2         17982  
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 485 my ($class, @args) = @_;
633 2 50       8 ref $class and $class = ref $class;
634 2         10 my $self = bless {
635             debug => 0,
636             generation_limit => 30,
637             iteration_limit => 0,
638             output_delimiter => ' ',
639             }, $class;
640 2 50       6 @args and $self->set (@args);
641 2 50       16 $self->{cell} or $self->set (sudoku => 3);
642             $self->{symbol_list}
643 2 50       7 or $self->set (symbols => join ' ', '.', 1 .. $self->{largest_set});
644             defined $self->{columns}
645 2 50       8 or $self->set (columns => @{$self->{symbol_list}} - 1);
  0         0  
646             defined $self->{status_value}
647 2 50       11 or $self->set (status_value => SUDOKU_SUCCESS);
648             defined $self->{max_tuple}
649 2 50       8 or $self->set (max_tuple => 4);
650 2         10 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 46 my ($self, $name, @cells) = @_;
666 21 50       50 $self->{set}{$name} and croak <
667             Error - Set '$name' already exists.
668             eod
669 21         30 foreach my $inx (@cells) {
670 184 50       287 $self->{cell}[$inx] or croak <
671             Error - Cell $inx does not exist.
672             eod
673             }
674 21         30 foreach my $inx (@cells) {
675 184         248 my $cell = $self->{cell}[$inx];
676 184 50       187 @{$cell->{membership}} or --$self->{cells_unused};
  184         296  
677 184         195 foreach my $other (@{$cell->{membership}}) {
  184         269  
678 468         736 my $int = join ',', sort $other, $name;
679 468   100     1388 $self->{intersection}{$int} ||= [];
680 468         539 push @{$self->{intersection}{$int}}, $inx;
  468         789  
681             }
682 184         206 @{$cell->{membership}} = sort $name, @{$cell->{membership}};
  184         430  
  184         288  
683             }
684 21         140 $self->{set}{$name} = {
685             name => $name,
686             membership => [sort @cells],
687             };
688             $self->{largest_set} = max ($self->{largest_set},
689 21         32 scalar @{$self->{set}{$name}{membership}});
  21         54  
690 21         29 delete $self->{backtrack_stack}; # Force setting of new problem.
691 21         52 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 17 my ( $self ) = @_;
713 6 50 33     40 return unless $self->{constraints_used} && defined wantarray;
714 6 50       15 return %{$self->{constraints_used}} if wantarray;
  0         0  
715             my $rslt = join ' ', grep {
716 6         20 $self->{constraints_used}{$_}} qw{F N B T X Y W ?};
  48         85  
717 6         26 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     4 ( $copier ||= eval {
737 1         538 require Clipboard;
738 1         7 Clipboard->import();
739             sub {
740 1     1   6 Clipboard->copy( join '', @_ );
741 1         1 return;
742 1         9 };
743             }
744             ) or croak 'copy() unavailable; can not load Clipboard';
745 1         4 $copier->( $self->_unload() );
746 1         3 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 3 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         4  
765 4         7 my $cell = $self->{cell}[$inx];
766 4         6 my @mbr;
767 4         6 foreach my $other (@{$cell->{membership}}) {
  4         6  
768 12 100       22 if ($other ne $name) {
769 8         14 push @mbr, $other;
770 8         15 my $int = join ',', sort $other, $name;
771 8         17 delete $self->{intersection}{$int};
772             }
773             }
774 4 50       6 if (@mbr) {
775 4         7 @{$cell->{membership}} = sort @mbr;
  4         10  
776             } else {
777 0         0 @{$cell->{membership}} = ();
  0         0  
778 0         0 $self->{cells_unused}++;
779             }
780             }
781 1         3 delete $self->{set}{$name};
782 1         3 $self->{largest_set} = 0;
783 1         2 foreach (keys %{$self->{set}}) {
  1         6  
784             $self->{largest_set} = max ($self->{largest_set},
785 8         11 scalar @{$self->{set}{$_}{membership}});
  8         17  
786             }
787 1         2 delete $self->{backtrack_stack}; # Force setting of new problem.
788 1         2 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 64 my ($self, @args) = @_;
961 21         29 my @rslt;
962 21 50       74 wantarray or @args = ($args[0]);
963 21         40 foreach my $name (@args) {
964 21 50       58 exists $accessor{$name} or croak <
965             Error - Attribute $name does not exist, or is write-only.
966             eod
967 21         67 push @rslt, $accessor{$name}->($self, $name);
968             }
969 21 50       120 return wantarray ? @rslt : $rslt[0];
970             }
971              
972             sub _get_allowed_symbols {
973 2     2   5 my ( $self ) = @_;
974 2         5 my $rslt = '';
975 2         4 my $syms = @{$self->{symbol_list}};
  2         6  
976 2         4 foreach (sort keys %{$self->{allowed_symbols}}) {
  2         13  
977 6         11 my @symlst;
978 6         12 for (my $val = 1; $val < $syms; $val++) {
979             push @symlst, $self->{symbol_list}[$val]
980 54 100       111 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   11 my ( $self ) = @_;
989 5         10 return join ' ', @{$self->{symbol_list}};
  5         30  
990             }
991              
992             sub _get_topology {
993 8     8   41 my ( $self ) = @_;
994 8         34 my $rslt = '';
995 8         19 my $col = $self->{columns};
996 8   33     25 my $row = $self->{rows} ||= floor (@{$self->{cell}} / $col);
  0         0  
997 8 50       14 foreach (map {join (',', @{$_->{membership}}) || ','} @{$self->{cell}}) {
  583         708  
  583         1352  
  8         21  
998 583         661 $rslt .= $_;
999 583 100       733 if (--$col > 0) {
1000 522         623 $rslt .= ' '
1001             } else {
1002 61         72 $rslt .= "\n";
1003 61         77 $col = $self->{columns};
1004 61 100       108 if (--$row <= 0) {
1005 8         14 $rslt .= "\n";
1006 8         15 $row = $self->{rows};
1007             }
1008             }
1009             }
1010 8         59 0 while chomp $rslt;
1011 8         13 $rslt .= "\n";
1012 8         37 return $rslt;
1013             }
1014              
1015 6     6   20 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 2 my ( $self ) = @_;
1033 1 50 33     5 ( $paster ||= eval {
1034 1         8 require Clipboard;
1035 1         5 Clipboard->import();
1036             return sub {
1037 1     1   3 return Clipboard->paste();
1038 1         7 };
1039             }
1040             ) or croak 'paste() unavailable; can not load Clipboard';
1041              
1042 1         4 $self->problem( $paster->() );
1043 1         5 $self->_unload();
1044 1         6 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 64 my ( $self, $val ) = @_;
1081 19   50     94 $val ||= '';
1082             $val =~ m/\S/ or
1083             $val = "$self->{symbol_list}[0] " x
1084 19 50       106 (scalar @{$self->{cell}} - $self->{cells_unused});
  0         0  
1085 19 100       347 $val =~ s/\s+//g unless $self->{biggest_spec} > 1;
1086 19         59 $val =~ s/^\s+//;
1087 19         83 $val =~ s/\s+$//;
1088 19 50       57 $self->{debug} and print <
1089             Debug problem - Called with $val
1090             eod
1091              
1092 19         57 local $Data::Dumper::Terse = 1;
1093 19 50       39 $self->{largest_set} >= @{$self->{symbol_list}} and croak <
  19         56  
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         34 my $syms = @{$self->{symbol_list}};
  19         34  
1101 19         29 foreach (@{$self->{cell}}) {
  19         52  
1102 1651         2583 $_->{content} = $_->{chosen} = 0;
1103 1651         2241 $_->{possible} = {map {$_ => 0} (1 .. $syms - 1)};
  17167         26536  
1104             }
1105 19         39 foreach (values %{$self->{set}}) {
  19         105  
1106 511         565 $_->{free} = @{$_->{membership}};
  511         782  
1107 511         963 $_->{content} = [$_->{free}];
1108             }
1109 19         67 $self->{cells_unassigned} = scalar @{$self->{cell}} - $self->{cells_unused};
  19         51  
1110              
1111 19         41 my $hash = $self->{symbol_hash};
1112 19         41 my $inx = 0;
1113 19         36 my $max = @{$self->{cell}};
  19         34  
1114 19 100       615 foreach (split (($self->{biggest_spec} > 1 ? '\s+' : ''), $val)) {
1115 1651 50       2404 $inx >= $max and croak <
1116             Error - Too many cell specifications. The topology allows only $max.
1117             eod
1118 1651 50       2273 next unless defined $_;
1119             # was $self->{ignore_unused}
1120 0         0 ($self->{cells_unused} && !@{$self->{cell}[$inx]{membership}})
1121 1651 50 33     2611 and do {$inx++; redo};
  0         0  
  0         0  
1122 1651 100       2540 $self->{allowed_symbols}{$_} and do {
1123 195 50       318 $self->{debug} > 1 and print <
1124             Debug problem - Cell $inx allows symbol set $_
1125             eod
1126 195         223 my $cell = $self->{cell}[$inx];
1127 195 50       213 @{$cell->{membership}} or croak <
  195         335  
1128             Error - Cell $inx is unused, and must be specified as empty.
1129             eod
1130 195         316 for (my $val = 1; $val < $syms; $val++) {
1131 1692 100       2887 next if $self->{allowed_symbols}{$_}[$val];
1132 749         1241 $cell->{possible}{$val} = 1;
1133             }
1134             };
1135 1651 100       2550 defined $hash->{$_} or $_ = $self->{symbol_list}[0];
1136 1651         2955 (@{$self->{cell}[$inx]{membership}} ||
1137 1651 50 33     1684 $_ 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       2517 $self->{debug} > 1 and print <
1142             Debug problem - Cell $inx specifies symbol $_
1143             eod
1144 1651 50       2497 $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       2778 $self->{cell}[$inx]{chosen} = $hash->{$_} ? 1 : 0;
1150             } continue {
1151 1651         2339 $inx++;
1152             }
1153              
1154 19 50       237 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         98 $self->{constraints_used} = {};
1167              
1168 19 50       47 $self->{debug} and print <
1169             Debug problem - problem loaded.
1170             eod
1171              
1172 19         329 $self->{backtrack_stack} = [];
1173 19         38 $self->{cell_order} = [];
1174 19         40 delete $self->{no_more_solutions};
1175              
1176 19 50       54 $self->{debug} > 1 and print " object = ", Dumper ($self);
1177              
1178 19         103 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 177 my ( $self, @args ) = @_;
1227 62         143 while ( @args ) {
1228 90         226 my ( $name, $val ) = splice @args, 0, 2;
1229 90 50       252 exists $mutator{$name} or croak <
1230             Error - Attribute $name does not exist, or is read-only.
1231             eod
1232 90         289 $mutator{$name}->($self, $name, $val );
1233             }
1234 62         123 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       10 defined $value or $value = '';
1241 4         9 my $maxlen = 0;
1242 4 50       16 $self->{debug} and print <
1243             Debug allowed_symbols being set to '$value'
1244             eod
1245 4 50       12 if ($value) {
1246 4         31 foreach (split '\s+', $value) {
1247 22         48 my ($name, $value) = split '=', $_, 2;
1248 22 50       45 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       39 $value or do {delete $self->{allowed_symbols}{$name}; next};
  2         8  
  2         3  
1253 20         37 $maxlen = max ($maxlen, length ($name));
1254 20 50       41 $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         42 my $const = $self->{allowed_symbols}{$name} = [];
1259 20         45 foreach (split ',', $value) {
1260 93 50       132 $self->{debug} > 1 and print <
1261             Debug allowed_symbols - Adding symbol '$_' to set '$name'.
1262             eod
1263 93 50       144 $self->{symbol_hash}{$_} or croak <
1264             Error - '$_' is not a valid symbol.
1265             eod
1266 93         154 $const->[$self->{symbol_hash}{$_}] = 1;
1267             }
1268             }
1269             } else {
1270 0         0 $self->{allowed_symbols} = {};
1271             }
1272 4 100       15 $self->{biggest_spec} = $maxlen if $maxlen > $self->{biggest_spec};
1273 4         11 return;
1274             }
1275              
1276             sub _set_brick {
1277 6     6   14 my ( $self, undef, $value ) = @_; # $name unused
1278 6 100       28 my ($horiz, $vert, $size) = ref $value ? @$value : split ',', $value;
1279 6 50       16 defined $size
1280             and $self->_deprecation_notice( 'brick_third_argument' );
1281 6   33     44 $size ||= $horiz * $vert;
1282 6 50 33     33 ($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         53 my $rowmul = floor ($size / $horiz);
1287 6         15 my $syms = '.';
1288 6         11 my $topo = '';
1289 6         19 for (my $row = 0; $row < $size; $row++) {
1290 58         75 $syms .= " @{[$row + 1]}";
  58         121  
1291 58         119 for (my $col = 0; $col < $size; $col++) {
1292 616         1748 $topo .= sprintf ' r%d,c%d,s%d', $row, $col,
1293             floor ($row / $vert) * $rowmul + floor ($col / $horiz);
1294             }
1295             }
1296 6         15 substr ($topo, 0, 1, '');
1297 6         25 $self->set (columns => $size, rows => $size, symbols => $syms,
1298             topology => $topo);
1299 6         25 return;
1300             }
1301              
1302             sub _set_corresponding {
1303             ## my ( $self, $name, $order ) = @_;
1304 1     1   3 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         3 my $offset = $size * $order;
1309 1         5 for (my $inx = 0; $inx < $size; $inx++) {
1310 9         25 my $base = floor ($inx / $order) * $size + $inx % $order;
1311             $self->add_set ("u$inx", map {
1312 9         22 my $g = $_ * $offset + $base;
  27         33  
1313 27         35 (map {$_ * $order + $g} 0 .. $order_minus_1)} 0 .. $order_minus_1);
  81         115  
1314             }
1315 1         4 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       12 if ($type =~ m/\D/) {
1365 2 50       7 $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         24 $self->set (symbols => join ' ', '.', 1 .. $self->{largest_set});
1386 2         8 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         7 for (my $row = 0; $row < $size; $row++) {
1403 13         17 $syms .= " @{[$letter++]}";
  13         29  
1404 13         28 for (my $col = 0; $col < $size; $col++) {
1405 97         173 $topo .= sprintf ' r%d,c%d', $row, $col;
1406             }
1407             }
1408 2         4 substr ($topo, 0, 1, '');
1409 2         8 $self->set (columns => $size, rows => $size, symbols => $syms,
1410             topology => $topo);
1411 2         8 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   49 my ( $self, $name, $value ) = @_;
1435 23 50       50 _looks_like_number ($value) or croak <
1436             Error - Attribute $name must be numeric.
1437             eod
1438 23         48 $self->{$name} = $value;
1439 23         58 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   62 my ( $self, $name, $value ) = @_;
1509 21 50       83 _looks_like_number ($value) or croak <
1510             Error - Attribute $name must be numeric.
1511             eod
1512 21 50 33     122 ($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         61 $self->{status_value} = $value;
1517 21         59 $self->{status_text} = $status_values[$value];
1518 21         54 return;
1519             }
1520              
1521             sub _set_sudoku {
1522             ## my ( $self, $name, $order ) = @_;
1523 5     5   13 my ( $self, undef, $order ) = @_; # Name unused
1524 5         31 $self->set( brick => [ $order, $order ] );
1525 5         17 return;
1526             }
1527              
1528             sub _set_sudokux {
1529             ## my ( $self, $name, $order ) = @_;
1530 1     1   2 my ( $self, undef, $order ) = @_; # Name unused
1531 1         4 $self->set (sudoku => $order);
1532 1         4 my $size = $order * $order;
1533 1         3 my $size_minus_1 = $size - 1;
1534 1         3 my $size_plus_1 = $size + 1;
1535 1         5 $self->add_set (d0 => map {$_ * $size_plus_1} 0 .. $size_minus_1);
  9         16  
1536 1         4 $self->add_set (d1 => map {$_ * $size_minus_1} 1 .. $size);
  9         14  
1537 1         5 return;
1538             }
1539              
1540             sub _set_symbols {
1541             ## my ( $self, $name, $value ) = @_;
1542 13     13   26 my ( $self, undef, $value ) = @_; # Name unused
1543 13         136 my @lst = split '\s+', $value;
1544 13         23 my %hsh;
1545 13         23 my $inx = 0;
1546 13         20 my $maxlen = 0;
1547 13         27 foreach (@lst) {
1548 142 50       211 defined $_ or next;
1549 142 50       222 m/,/ and croak <
1550             Error - Symbols may not contain commas.
1551             eod
1552 142 50       221 exists $hsh{$_} and croak <
1553             Error - Symbol '$_' specified more than once.
1554             eod
1555 142         237 $hsh{$_} = $inx++;
1556 142         242 $maxlen = max ($maxlen, length ($_));
1557             }
1558 13         56 $self->{symbol_list} = \@lst;
1559 13         45 $self->{symbol_hash} = \%hsh;
1560 13         34 $self->{symbol_number} = scalar @lst;
1561 13         35 $self->{biggest_spec} = $self->{biggest_symbol} = $maxlen;
1562 13         42 $self->{allowed_symbols} = {};
1563 13         37 return;
1564             }
1565              
1566             sub _set_topology {
1567             ## my ( $self, $name, @args ) = @_;
1568 11     11   31 my ( $self, undef, @args ) = @_; # Name unused
1569 11         1359 $self->{cell} = []; # The cells themselves.
1570 11         475 $self->{set} = {}; # The sets themselves.
1571 11         17 $self->{largest_set} = 0;
1572 11         545 $self->{intersection} = {};
1573 11         17 $self->{cells_unused} = 0;
1574 11         18 my $cell_inx = 0;
1575 11         31 foreach my $cell_def (map {split '\s+', $_} @args) {
  11         342  
1576 938         1743 my $cell = {membership => [], index => $cell_inx};
1577 938         1144 push @{$self->{cell}}, $cell;
  938         1317  
1578 938         1792 foreach my $name (sort grep {$_ ne ''} split ',', $cell_def) {
  2717         4807  
1579 2717         2981 foreach my $other (@{$cell->{membership}}) {
  2717         3576  
1580 2620         3582 my $int = "$other,$name";
1581 2620   100     7047 $self->{intersection}{$int} ||= [];
1582 2620         2942 push @{$self->{intersection}{$int}}, $cell_inx;
  2620         4428  
1583             }
1584 2717         2924 push @{$cell->{membership}}, $name;
  2717         3939  
1585 2717   100     5084 my $set = $self->{set}{$name} ||=
1586             {name => $name, membership => []};
1587 2717         2882 push @{$set->{membership}}, $cell_inx;
  2717         3727  
1588             $self->{largest_set} = max ($self->{largest_set},
1589 2717         3150 scalar @{$set->{membership}});
  2717         5156  
1590             }
1591 938 50       1204 @{$cell->{membership}} or $self->{cells_unused}++;
  938         1494  
1592 938         1238 $cell_inx++;
1593             }
1594 11         539 delete $self->{backtrack_stack}; # Force setting of new problem.
1595 11         58 return;
1596             }
1597              
1598 1     1   4 sub _set_value {$_[0]->{$_[1]} = $_[2]; return;}
  1         3  
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 54 my ( $self ) = @_;
1620              
1621 19 50       59 $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       60 $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         79 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 3 my ( $self ) = @_;
1684 0         0 return wantarray ? (@{$self->{backtrack_stack}}) :
1685             defined wantarray ?
1686 1 50       5 $self->_format_constraint (@{$self->{backtrack_stack}}) :
  1 50       6  
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 5 my ( $self ) = @_;
1702 2         7 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   36 my ( $self ) = @_;
1723 19   50     59 my $stack = $self->{backtrack_stack} ||= []; # May hit this
1724             # when initializing.
1725 19   50     95 my $used = $self->{constraints_used} ||= {};
1726 19         44 my $iterations;
1727             $iterations = $self->{iteration_limit}
1728 19 50       60 if $self->{iteration_limit} > 0;
1729              
1730             $self->{no_more_solutions} and
1731 19 50       98 return $self->_unload (undef, SUDOKU_NO_SOLUTION);
1732              
1733 19 100       32 @{$self->{backtrack_stack}} and do {
  19         54  
1734 1 50       5 $self->_constraint_remove and
1735             return $self->_unload (undef, SUDOKU_NO_SOLUTION);
1736             };
1737              
1738 18 50       48 $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         28 my $number_of_cells = @{$self->{cell}};
  18         40  
1744              
1745             constraint_loop:
1746             { # Begin outer constraint loop.
1747              
1748 18         32 foreach my $constraint (qw{F N B T ?}) {
  361         767  
1749 693 50       899 confess <{cell}} != $number_of_cells;
  693         1485  
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 693   33     2623 my $method = $constraint_method{$constraint} ||
1755             "_constraint_$constraint";
1756 693 50       2431 my $rslt = $self->$method () or next;
1757 693 100       1629 @$rslt or next;
1758 361         706 foreach my $constr (@$rslt) {
1759 1151 50       1954 if (ref $constr) {
1760 1151         1692 push @$stack, $constr;
1761 1151         1927 $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 361 100       833 return $self->_unload ('', SUDOKU_SUCCESS);
1770 343         926 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 361     361   699 my ( $self ) = @_;
1791 361         491 my @stack;
1792 361         537 my $done = 1;
1793              
1794 361         643 while ($done) {
1795 555         749 $done = 0;
1796 555         817 my $inx = 0; # Cell index.
1797 555         719 foreach my $cell (@{$self->{cell}}) {
  555         1131  
1798 66560 100       99732 next if $cell->{content}; # Skip already-assigned cells.
1799 30695 50       32217 next unless @{$cell->{membership}}; # Skip unused cells.
  30695         48491  
1800 30695         33740 my $pos = 0;
1801 30695 100       32071 foreach (values %{$cell->{possible}}) {$_ or $pos++};
  30695         56932  
  387283         550617  
1802 30695 100       43328 if ($pos > 1) { # > 1 possibility. Can't apply.
    50          
1803             } elsif ($pos == 1) { # Exactly 1 possibility. Apply.
1804 857         957 my $val;
1805 857         926 foreach (keys %{$cell->{possible}}) {
  857         2623  
1806 4823 100       7483 next if $cell->{possible}{$_};
1807 857         1059 $val = $_;
1808 857         991 last;
1809             }
1810 857 50       1890 $self->_try ($cell, $val) and confess <
1811             Programming error - Passed 'F' constraint but _try failed.
1812             eod
1813 857         1953 my $constraint = [F => [$inx, $val]];
1814             $self->{debug} and
1815 857 50       1498 print '# ', $self->_format_constraint ($constraint);
1816 857         996 $done++;
1817 857         1296 push @stack, $constraint;
1818 857 100       1518 $self->{cells_unassigned} or do {$done = 0; last};
  18         27  
  18         54  
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 66542         82108 $inx++;
1833             }
1834             }
1835 361         1193 return \@stack;
1836             }
1837              
1838             # N constraint - the only cell which supplies a necessary value.
1839              
1840             sub _constraint_N {
1841 294     294   694 my ( $self ) = @_;
1842 294         487 while (my ($name, $set) = each %{$self->{set}}) {
  4019         10242  
1843 3987         4509 my @suppliers;
1844 3987         4345 foreach my $inx (@{$set->{membership}}) {
  3987         7025  
1845 51255         65973 my $cell = $self->{cell}[$inx];
1846 51255 100       82920 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 25529         28104 while (my ($val, $count) = each %{$cell->{possible}}) {
  372222         673154  
1850 346693 100       495639 next if $count;
1851 101572   100     185602 $suppliers[$val] ||= [];
1852 101572         108083 push @{$suppliers[$val]}, $inx;
  101572         163979  
1853             }
1854             }
1855 3987         5504 my $limit = @suppliers;
1856 3987         7144 for (my $val = 1; $val < $limit; $val++) {
1857 43313 100 100     69500 next unless $suppliers[$val] && @{$suppliers[$val]} == 1;
  24880         61848  
1858 262         433 my $inx = $suppliers[$val][0];
1859 262 0       1036 $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 262         981 my $constraint = [N => [$inx, $val]];
1868             $self->{debug} and
1869 262 50       729 print '# ', $self->_format_constraint ($constraint);
1870 262         392 keys %{$self->{set}}; # Reset iterator.
  262         534  
1871 262         1223 return [$constraint];
1872             }
1873             }
1874 32         132 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 32     32   100 my ( $self ) = @_;
1888 32         56 my $done = 0;
1889 32         57 while (my ($int, $cells) = each %{$self->{intersection}}) {
  4054         9479  
1890 4048 100       6940 next unless @$cells > 1;
1891 1414         1850 my @int_supplies; # Values supplied by the intersection
1892             my %int_cells; # Cells in the intersection
1893 1414         2227 foreach my $inx (@$cells) {
1894 5318 100       10165 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 2942         5320 $int_cells{$inx} = 1;
1898 2942         3344 while (my ($val, $imposs) = each %{
1899 46700         89864 $self->{cell}[$inx]{possible}}) {
1900 43758 100       68138 $int_supplies[$val] = 1 unless $imposs;
1901             }
1902             }
1903 1414         1753 my %ext_supplies; # Intersection values also supplied outside.
1904             my %ext_cells; # Cells not in the intersection.
1905 1414         3197 my @set_names = split ',', $int;
1906 1414         1926 foreach my $set (@set_names) {
1907 2828         4595 $ext_supplies{$set} = [];
1908 2828         3834 $ext_cells{$set} = [];
1909 2828         3175 foreach my $inx (@{$self->{set}{$set}{membership}}) {
  2828         5780  
1910 40556 100       62755 next if $int_cells{$inx}; # Skip cells in intersection.
1911 34672 100       59741 next if $self->{cell}[$inx]{content};
1912 16733         17625 push @{$ext_cells{$set}}, $inx;
  16733         26758  
1913 16733         19381 while (my ($val, $imposs) = each %{
1914 271843         527284 $self->{cell}[$inx]{possible}}) {
1915 255110 100 100     447804 $ext_supplies{$set}[$val] = 1
1916             if !$imposs && $int_supplies[$val];
1917             }
1918             }
1919             }
1920 1414         3187 for (my $val = 1; $val < @int_supplies; $val++) {
1921 15963 100       26412 next unless $int_supplies[$val];
1922 6896         8366 my @occurs_in = grep {$ext_supplies{$_}[$val]} @set_names;
  13792         21877  
1923 6896 100 100     25798 next unless @occurs_in && @occurs_in < @set_names;
1924 26         58 my %cells_claimed;
1925 26         52 foreach my $set (@occurs_in) {
1926 26         47 foreach my $inx (@{$ext_cells{$set}}) {
  26         55  
1927 141 100       292 next if $self->{cell}[$inx]{possible}{$val};
1928 68         144 $cells_claimed{$inx} = 1;
1929 68         85 $self->{cell}[$inx]{possible}{$val} = 1;
1930 68         88 $done++;
1931             }
1932             }
1933 26 50       71 next unless $done;
1934 26         216 my $constraint = [B => [[sort keys %cells_claimed], $val]];
1935             $self->{debug} and
1936 26 50       105 print '# ', $self->_format_constraint ($constraint);
1937 26         39 keys %{$self->{intersection}}; # Reset iterator.
  26         57  
1938 26         231 return [$constraint];
1939             }
1940             }
1941 6         32 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 6     6   13 my ( $self ) = @_;
1967 6         22 my @tuple; # Tuple indices
1968             my %vacant; # Empty cells by set. $vacant{$set} = [$cell ...]
1969 6         0 my %contributors; # Number of cells which can contrib value, by set.
1970 6         13 my $syms = @{$self->{symbol_list}};
  6         16  
1971              
1972 6         13 while (my ($name, $set) = each %{$self->{set}}) {
  212         565  
1973 2526         4325 my @open = grep {!$_->{content}}
1974 206 100       242 map {$self->{cell}[$_]} @{$set->{membership}}
  2526         3591  
  206         359  
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 187         347 foreach my $cell (@open) {
1979 1212         1843 for (my $val = 1; $val < $syms; $val++) {
1980 16599 100       29226 $cell->{possible}{$val} and next;
1981 4457   100     6344 $contributors{$name} ||= [];
1982 4457         6725 $contributors{$name}[$val]++;
1983             }
1984             }
1985 187 100       229 @{$contributors{$name}} = map {$_ || 0} @{$contributors{$name}};
  187         334  
  2291         3840  
  187         283  
1986 187         314 $vacant{$name} = \@open;
1987 187   100     434 $tuple[scalar @open] ||= [map {[$_]} 0 .. $#open];
  256         492  
1988             }
1989              
1990 6         28 for (my $order = 2; $order <= $self->{max_tuple}; $order++) {
1991 6         21 for (my $inx = 1; $inx < @tuple; $inx++) {
1992 52 100       117 next unless $tuple[$inx];
1993 40         52 my $max = $inx - 1;
1994 216         270 $tuple[$inx] = [map {my @tpl = @$_;
1995 216         294 map {[@tpl, $_]} $tpl[-1] + 1 .. $max}
  912         1566  
1996 40         51 grep {$_->[-1] < $max} @{$tuple[$inx]}];
  256         378  
  40         64  
1997 40 50       99 $tuple[$inx] = undef unless @{$tuple[$inx]};
  40         108  
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 6         53 foreach my $name (keys %vacant) {
2012 38         91 my $open = $vacant{$name};
2013 38 50       104 next unless $tuple[@$open];
2014 38         70 my $contributed = $contributors{$name};
2015 38         48 foreach my $tuple (@{$tuple[@$open]}) {
  38         87  
2016 1228         1370 my @tcontr; # number of times each value
2017             # contributed by the tuple.
2018 1228         1774 foreach my $inx (@$tuple) {
2019 2456         2926 my $cell = $open->[$inx];
2020 2456         3683 for (my $val = 1; $val < $syms; $val++) {
2021 38274 100       66563 next if $cell->{possible}{$val};
2022 10775         15887 $tcontr[$val]++;
2023             }
2024             }
2025 1228 100       1692 @tcontr = map {$_ || 0} @tcontr;
  19014         32150  
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 1228         1564 my $discrete = grep {$_} @tcontr;
  19014         20913  
2040 1228         1446 my $constraint;
2041             my @tuple_member;
2042 1228 100       2150 if ($discrete == $order) {
    50          
2043 7         19 for (my $val = 1; $val < @tcontr; $val++) {
2044 53 100 100     132 next unless $tcontr[$val] &&
2045             $contributed->[$val] > $tcontr[$val];
2046              
2047             # At this point we know we have an "effective" naked tuple.
2048              
2049 4   100     13 $constraint ||= ['T', 'naked', $order];
2050 4 100       10 @tuple_member or map {$tuple_member[$_] = 1} @$tuple;
  4         9  
2051 4         6 my @ccl;
2052 4         9 for (my $inx = 0; $inx < @$open; $inx++) {
2053             next if $tuple_member[$inx] ||
2054 18 100 100     51 $open->[$inx]{possible}{$val};
2055 6         10 $open->[$inx]{possible}{$val} = 1;
2056 6         7 --$contributed->[$val];
2057 6         13 push @ccl, $open->[$inx]{index};
2058             }
2059 4 50       26 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 1221         1304 my $within = 0; # Number of values occuring only
2070             # within tuple.
2071 1221         1967 for (my $val = 1; $val < @tcontr; $val++) {
2072 17733 100 100     37733 $within++ if $tcontr[$val] &&
2073             $contributed->[$val] == $tcontr[$val];
2074             }
2075 1221 100       2660 next unless $within >= $order;
2076 4         17 $constraint = ['T', 'hidden', $order];
2077 4         9 map {$tuple_member[$_] = 1} @$tuple;
  8         21  
2078 4         16 for (my $val = 1; $val < @tcontr; $val++) {
2079 47 100 100     118 next unless $tcontr[$val] &&
2080             $contributed->[$val] > $tcontr[$val];
2081 11         18 my @ccl;
2082 11         23 for (my $inx = 0; $inx < @$open; $inx++) {
2083             next unless $tuple_member[$inx]
2084 78 100 100     178 && !$open->[$inx]{possible}{$val}
2085             ;
2086 13         31 $open->[$inx]{possible}{$val} = 1;
2087 13         18 --$contributed->[$val];
2088 13         18 --$tcontr[$val];
2089 13         31 push @ccl, $open->[$inx]{index};
2090             }
2091              
2092 11 50       58 push @$constraint, [\@ccl, $val] if @ccl;
2093             }
2094             }
2095              
2096 11 100       37 next unless $constraint;
2097             $self->{debug} and
2098 6 50       19 print '# ', $self->_format_constraint ($constraint);
2099 6         292 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   3 my ( $self, $min, $max, $removal_ok ) = @_;
2163 1 50       4 $min and $min = @{$self->{cell}} - $min;
  0         0  
2164 1 50       3 $max and $max = @{$self->{cell}} - $max;
  0         0  
2165 1 50       3 $self->{no_more_solutions} and return SUDOKU_NO_SOLUTION;
2166 1 50       3 my $stack = $self->{backtrack_stack} or return SUDOKU_NO_SOLUTION;
2167 1   50     3 my $used = $self->{constraints_used} ||= {};
2168 1         3 my $inx = @$stack;
2169 1         2 my $syms = @{$self->{symbol_list}};
  1         2  
2170 1 50 33     5 ($self->{debug} && $inx) and print <
2171             # Debug - Backtracking
2172             eod
2173 1         2 my $old = $inx;
2174 1         4 while (--$inx >= 0) {
2175 45 50 33     70 ($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         69 my $constraint = $stack->[$inx][0];
2182 45 50       63 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     69 ($max && $self->{cells_unassigned} <= $max &&
      33        
2201             $constraint eq '?')
2202             and next;
2203             }
2204 45         53 --$used->{$constraint};
2205 45 50 66     79 if ($constraint eq 'F' || $constraint eq 'N') {
    0 0        
    0          
2206 45         51 foreach my $ref (reverse @{$stack->[$inx]}) {
  45         62  
2207 90 100       170 $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         98 pop @$stack;
2248             }
2249 1 50       7 $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         3 $self->{no_more_solutions} = 1;
2254 1         10 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   5 my ($self, @args) = @_;
2296 1         2 my @steps;
2297 1         2 foreach (@args) {
2298 52         57 my @stuff;
2299 52         66 foreach (@$_) {
2300 104 50       176 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       244 $self->{symbol_list}[$_->[1]],
    50          
    100          
2307             ) . ']' :
2308             $_;
2309             }
2310 52         114 push @steps, join (' ', @stuff) . "\n";
2311             }
2312 1         12 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   98 ( local $_ ) = @_;
2323 44 50 33     192 return 0 if !defined ($_) || ref ($_);
2324 44 50       420 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   4273 my ( $self, $cell, $new ) = @_;
2341 2815 100       4928 $cell = $self->{cell}[$cell] unless ref $cell;
2342 2815 50       4233 defined $new
2343             or _fatal (
2344             "_try called for cell $cell->{index} with new value undefined");
2345 2815 50       4964 defined (my $old = $cell->{content}) or _fatal (
2346             "_try called with old cell $cell->{index} value undefined");
2347 2815         3707 my $rslt = eval {
2348 2815 100       4599 return 0 if $old == $new;
2349 1644 100       2595 if ($new) {
2350 1599         1877 foreach my $set (@{$cell->{membership}}) {
  1599         2787  
2351 4833 50       10830 return 1 if $self->{set}{$set}{content}[$new];
2352             }
2353             }
2354 1644         2345 $cell->{content} = $new;
2355 1644 100       2575 $old and $self->{cells_unassigned}++;
2356 1644 100       2980 $new and --$self->{cells_unassigned};
2357 1644         1891 foreach my $name (@{$cell->{membership}}) {
  1644         2423  
2358 4968         6277 my $set = $self->{set}{$name};
2359 4968         5988 --$set->{content}[$old];
2360 4968 100       7011 $old and do {
2361 135         143 $set->{free}++;
2362 135         142 foreach (@{$set->{membership}}) {
  135         181  
2363 1215         1655 --$self->{cell}[$_]{possible}{$old};
2364             }
2365             };
2366 4968         6709 $set->{content}[$new]++;
2367 4968 100       7212 $new and do {
2368 4833         5528 --$set->{free};
2369 4833         5421 foreach (@{$set->{membership}}) {
  4833         7264  
2370 50421         73306 $self->{cell}[$_]{possible}{$new}++;
2371             }
2372             };
2373             }
2374 1644         2273 return 0;
2375             };
2376 2815 50       4204 $@ and _fatal ("Eval failed in _try", $@);
2377 2815         4689 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   64 my ($self, $prefix, @args) = @_;
2390 23 100       65 defined $prefix or $prefix = '';
2391 23 100       80 @args and do {
2392 19         94 $self->set (status_value => $args[0]);
2393 19 100       107 $args[0] and return;
2394             };
2395 22         41 my $rslt = '';
2396 22         54 my $col = $self->{columns};
2397 22   33     65 my $row = $self->{rows} ||= floor (@{$self->{cell}} / $col);
  0         0  
2398 22         80 my $fmt = "%$self->{biggest_symbol}s";
2399 22         43 foreach (@{$self->{cell}}) {
  22         60  
2400 1894 100       2674 $col == $self->{columns} and $rslt .= $prefix;
2401             # was $self->{ignore_unused}
2402             $rslt .= ($self->{cells_unused} && !@{$_->{membership}}) ?
2403             sprintf ($fmt, ' ') :
2404 1894 50 33     4622 sprintf ($fmt, $self->{symbol_list}[$_->{content} || 0]);
      100        
2405 1894 100       2516 if (--$col > 0) {
2406             $rslt .= $self->{output_delimiter}
2407 1674         2165 } else {
2408             # was $self->{ignore_unused}
2409 220 50       322 $self->{cells_unused} and $rslt =~ s/\s+$//m;
2410 220         252 $rslt .= "\n";
2411 220         283 $col = $self->{columns};
2412 220 100       361 if (--$row <= 0) {
2413 29         53 $rslt .= "\n";
2414 29         50 $row = $self->{rows};
2415             }
2416             }
2417             }
2418 22         89 0 while chomp $rslt;
2419 22         35 $rslt .= "\n";
2420 22         362 return $rslt;
2421             }
2422              
2423             1;
2424              
2425             __END__