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   2801 use 5.006002; # For 'our', at least.
  2         11  
571              
572 2     2   8 use strict;
  2         3  
  2         35  
573 2     2   8 use warnings;
  2         3  
  2         64  
574              
575 2     2   17 use Exporter qw{ import };
  2         3  
  2         181  
576              
577             our $VERSION = '0.027';
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         3  
  2         140  
589 2     2   1047 use Data::Dumper;
  2         11997  
  2         143  
590 2     2   13 use List::Util qw{first max reduce};
  2         4  
  2         200  
591 2     2   841 use POSIX qw{floor};
  2         12271  
  2         9  
592              
593 2     2   2564 use constant SUDOKU_SUCCESS => 0;
  2         4  
  2         112  
594 2     2   10 use constant SUDOKU_NO_SOLUTION => 1;
  2         2  
  2         93  
595 2     2   10 use constant SUDOKU_TOO_HARD => 2;
  2         4  
  2         71  
596 2     2   9 use constant SUDOKU_MULTIPLE_SOLUTIONS => 3;
  2         2  
  2         148  
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   11 use constant HASH_REF => ref {};
  2         3  
  2         18582  
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 550 my ($class, @args) = @_;
633 2 50       9 ref $class and $class = ref $class;
634 2         11 my $self = bless {
635             debug => 0,
636             generation_limit => 30,
637             iteration_limit => 0,
638             output_delimiter => ' ',
639             }, $class;
640 2 50       7 @args and $self->set (@args);
641 2 50       18 $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       17 or $self->set (columns => @{$self->{symbol_list}} - 1);
  0         0  
646             defined $self->{status_value}
647 2 50       13 or $self->set (status_value => SUDOKU_SUCCESS);
648             defined $self->{max_tuple}
649 2 50       8 or $self->set (max_tuple => 4);
650 2         11 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 45 my ($self, $name, @cells) = @_;
666 21 50       43 $self->{set}{$name} and croak <
667             Error - Set '$name' already exists.
668             eod
669 21         38 foreach my $inx (@cells) {
670 184 50       282 $self->{cell}[$inx] or croak <
671             Error - Cell $inx does not exist.
672             eod
673             }
674 21         27 foreach my $inx (@cells) {
675 184         236 my $cell = $self->{cell}[$inx];
676 184 50       192 @{$cell->{membership}} or --$self->{cells_unused};
  184         275  
677 184         208 foreach my $other (@{$cell->{membership}}) {
  184         262  
678 468         740 my $int = join ',', sort $other, $name;
679 468   100     1301 $self->{intersection}{$int} ||= [];
680 468         512 push @{$self->{intersection}{$int}}, $inx;
  468         802  
681             }
682 184         208 @{$cell->{membership}} = sort $name, @{$cell->{membership}};
  184         446  
  184         273  
683             }
684 21         129 $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         52  
690 21         27 delete $self->{backtrack_stack}; # Force setting of new problem.
691 21         51 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 16 my ( $self ) = @_;
713 6 50 33     33 return unless $self->{constraints_used} && defined wantarray;
714 6 50       14 return %{$self->{constraints_used}} if wantarray;
  0         0  
715             my $rslt = join ' ', grep {
716 6         16 $self->{constraints_used}{$_}} qw{F N B T X Y W ?};
  48         80  
717 6         24 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         373 require Clipboard;
738 1         6 Clipboard->import();
739             sub {
740 1     1   6 Clipboard->copy( join '', @_ );
741 1         2 return;
742 1         8 };
743             }
744             ) or croak 'copy() unavailable; can not load Clipboard';
745 1         4 $copier->( $self->_unload() );
746 1         2 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 4 my ($self, $name) = @_;
761 1 50       4 $self->{set}{$name} or croak <
762             Error - Set '$name' not defined.
763             eod
764 1         3 foreach my $inx (@{$self->{set}{$name}{membership}}) {
  1         5  
765 4         8 my $cell = $self->{cell}[$inx];
766 4         6 my @mbr;
767 4         5 foreach my $other (@{$cell->{membership}}) {
  4         8  
768 12 100       20 if ($other ne $name) {
769 8         11 push @mbr, $other;
770 8         16 my $int = join ',', sort $other, $name;
771 8         15 delete $self->{intersection}{$int};
772             }
773             }
774 4 50       9 if (@mbr) {
775 4         7 @{$cell->{membership}} = sort @mbr;
  4         11  
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         2 $self->{largest_set} = 0;
783 1         3 foreach (keys %{$self->{set}}) {
  1         5  
784             $self->{largest_set} = max ($self->{largest_set},
785 8         10 scalar @{$self->{set}{$_}{membership}});
  8         19  
786             }
787 1         3 delete $self->{backtrack_stack}; # Force setting of new problem.
788 1         3 return $self;
789             }
790              
791             =head2 generate
792              
793             $problem = $su->generate( $min, $max, $const );
794              
795             This method generates a problem and returns it.
796              
797             The $min argument is the minimum number of givens in the puzzle. You
798             may (and probably will) get more. The default is the number of cells
799             in the puzzle divided by the number of sets a cell belongs to.
800              
801             The value of this argument is critical to getting a puzzle: too large
802             and you generate puzzles with no solution; too small and you spend all
803             your time backtracking. There is no science behind the default, just an
804             attempt to make a rational heuristic based on the number of degrees of
805             freedom and the observation that about a third of the cells are given
806             in a typical Sudoku puzzle. My experience with the default is:
807              
808             topology comment
809             brick 3,2 default is OK
810             corresponding 3 default is OK
811             cube 3 default is too large
812             cube half default is OK
813             cube full default is OK
814             quincunx 3 default is too large
815             sudoku 3 default is OK
816             sudoku 4 default is OK
817             sudokux 3 default is OK
818              
819             Typically when I take the defaults I get a puzzle in anywhere from
820             a few seconds (most of the listed topologies) to a couple minutes
821             (sudoku 4) on an 800 Mhz G4. But I have never successfully generated
822             a Dion cube (cube 3). C
823              
824             The $max argument is the maximum number of givens in the puzzle. You
825             may get less. The default is 1.5 times the minimum.
826              
827             The $const argument specifies the constraints to be used in the
828             generated puzzle. This may be specified either as a string or as a hash
829             reference. If specified as a string, it is a whitespace-delimited list,
830             with each constraint name possibly followed by an equals sign and a
831             number to specify that that constraint can be used only a certain
832             number of times. For example, 'F N ?=1' specifies a puzzle to be
833             solved by use of any number of applications of the F and N constraints,
834             and at most one guessed cell. If specified as a hash reference, the
835             keys are the constraint names, and the values are the usage counts,
836             with undef meaning no limit. The hash reference corresponding to
837             'F N ?=1' is {F => undef, N => undef, '?' => 1}. The default for this
838             argument is to allow all known constraints except '?'.
839              
840             In practice, the generator usually generates puzzles solvable using
841             only the F constraint, or the F and N constraints.
842              
843             The algorithm used is to generate a puzzle with the minimum number of
844             cells selected at random, and then solve it. If a solution does not
845             exist, we try again until we have tried
846             C times, then we return undef.
847             B
848              
849             If we get a solution, we remove allowed constraints. If we run into
850             a constraint that is not allowed, we either stop (if we're below the
851             maximum number of givens) or turn it into a given value (if we're
852             above the maximum). We stop unconditionally if we get down to the
853             minimum number of givens. As a side effect, the generated puzzle is
854             set up as a problem.
855              
856             Note that if you allow guesses you may get puzzles with more than
857             one solution.
858              
859             =cut
860              
861             sub generate {
862 0     0 1 0 my ( $self, $min, $max, $const ) = @_;
863 0         0 my $size = @{$self->{cell}} - $self->{cells_unused};
  0         0  
864 0   0     0 $min ||= do {
865             floor( $size * $size /
866 0         0 ( $self->{largest_set} * keys %{ $self->{set} } ) );
  0         0  
867             };
868 0   0     0 $max ||= floor( $min * 1.5 );
869 0   0     0 $const ||= 'F N B T';
870 0 0 0     0 croak <<"EOD" if ref $const && HASH_REF ne ref $const;
871             Error - The constraints argument must be a string or a hash reference,
872 0         0 not a @{[ref $const]} reference.
873             EOD
874 0 0       0 $const = {map {my @ret; $_ and do {
  0 0       0  
  0         0  
875 0         0 @ret = split '=', $_, 2; push @ret, undef while @ret < 2}; @ret}
  0         0  
  0         0  
876             split '\s+', $const}
877             unless HASH_REF eq ref $const;
878 0 0       0 $self->{debug} and do {
879 0         0 local $Data::Dumper::Terse = 1;
880 0         0 print <
881 0         0 Debug generate ($min, $max, @{[Dumper $const]})
882             eod
883             };
884 0         0 my $syms = @{$self->{symbol_list}} - 1;
  0         0  
885 0 0       0 croak < $size;
886             Error - You specified a minimum of $min given values, but the puzzle
887             only contains $size cells.
888             eod
889 0         0 my $tries = $self->{generation_limit};
890 0         0 $size = @{$self->{cell}}; # Note equivocation on $size.
  0         0  
891 0         0 local $Data::Dumper::Terse = 1;
892             my @universe = $self->{cells_unused} ?
893 0         0 grep {@{$self->{cell}[$_]{membership}}} (0 .. @{$self->{cell}} - 1) :
  0         0  
  0         0  
894 0 0       0 (0 .. @{$self->{cell}} - 1);
  0         0  
895 0         0 while (--$tries >= 0) {
896 0         0 $self->problem (); # We rely on this specifying an empty problem.
897             ## my @ix = (0 .. $size - 1);
898 0         0 my @ix = @universe;
899 0         0 my $gen = 0;
900 0         0 while ($gen++ < $min) {
901 0         0 my ($inx) = splice @ix, floor (rand scalar @ix), 1;
902 0         0 my $cell = $self->{cell}[$inx];
903             ## @{$cell->{membership}} or redo; # Ignore unused cells.
904 0 0       0 my @pos = grep {!$cell->{possible}{$_}} 1 .. $syms or next;
  0         0  
905 0         0 my $val = $pos[floor (rand scalar @pos)];
906 0 0       0 defined $val or confess <{possible});
907             Programming error - generate() selected an undefined value for cell $inx.
908             Possible values hash is:
909             eod
910             $self->_try ($cell, $val)
911 0 0       0 and confess <{possible});
912             Programming error - generate() tried to assign $val to cell $inx,
913             but it was rejected. Possible values hash is:
914             eod
915             }
916 0 0       0 $self->solution () or next;
917 0         0 $self->_constraint_remove ($min, $max, $const);
918 0         0 my $prob = $self->_unload ('', SUDOKU_SUCCESS);
919 0         0 $self->problem ($prob);
920 0 0       0 $self->copy ($prob) if $self->{autocopy};
921 0         0 return $prob;
922             }
923 0         0 return;
924             }
925              
926             my %accessor = (
927             allowed_symbols => \&_get_allowed_symbols,
928             autocopy => \&_get_value,
929             columns => \&_get_value,
930             debug => \&_get_value,
931             generation_limit => \&_get_value,
932             ## ignore_unused => \&_get_value,
933             iteration_limit => \&_get_value,
934             largest_set => \&_get_value,
935             name => \&_get_value,
936             output_delimiter => \&_get_value,
937             rows => \&_get_value,
938             status_text => \&_get_value,
939             status_value => \&_get_value,
940             symbols => \&_get_symbols,
941             topology => \&_get_topology,
942             );
943              
944             =head2 get
945              
946             $value = $su->get( $name );
947              
948             This method returns the value of the named attribute. An exception
949             is thrown if the given name does not correspond to an attribute that
950             can be read. That is, the given name must appear on the list of
951             attributes above, and not be marked "write-only".
952              
953             If called in list context, you can pass multiple attribute names,
954             and get back a list of their values. If called in scalar context,
955             attribute names after the first are ignored.
956              
957             =cut
958              
959             sub get {
960 21     21 1 70 my ($self, @args) = @_;
961 21         37 my @rslt;
962 21 50       76 wantarray or @args = ($args[0]);
963 21         40 foreach my $name (@args) {
964 21 50       48 exists $accessor{$name} or croak <
965             Error - Attribute $name does not exist, or is write-only.
966             eod
967 21         63 push @rslt, $accessor{$name}->($self, $name);
968             }
969 21 50       107 return wantarray ? @rslt : $rslt[0];
970             }
971              
972             sub _get_allowed_symbols {
973 2     2   6 my ( $self ) = @_;
974 2         4 my $rslt = '';
975 2         3 my $syms = @{$self->{symbol_list}};
  2         5  
976 2         4 foreach (sort keys %{$self->{allowed_symbols}}) {
  2         15  
977 6         7 my @symlst;
978 6         13 for (my $val = 1; $val < $syms; $val++) {
979             push @symlst, $self->{symbol_list}[$val]
980 54 100       123 if $self->{allowed_symbols}{$_}[$val];
981             }
982 6         12 $rslt .= "$_=@{[join ',', @symlst]}\n";
  6         21  
983             }
984 2         11 return $rslt;
985             }
986              
987             sub _get_symbols {
988 5     5   11 my ( $self ) = @_;
989 5         10 return join ' ', @{$self->{symbol_list}};
  5         28  
990             }
991              
992             sub _get_topology {
993 8     8   40 my ( $self ) = @_;
994 8         22 my $rslt = '';
995 8         19 my $col = $self->{columns};
996 8   33     24 my $row = $self->{rows} ||= floor (@{$self->{cell}} / $col);
  0         0  
997 8 50       16 foreach (map {join (',', @{$_->{membership}}) || ','} @{$self->{cell}}) {
  583         656  
  583         1126  
  8         21  
998 583         643 $rslt .= $_;
999 583 100       707 if (--$col > 0) {
1000 522         616 $rslt .= ' '
1001             } else {
1002 61         72 $rslt .= "\n";
1003 61         78 $col = $self->{columns};
1004 61 100       115 if (--$row <= 0) {
1005 8         14 $rslt .= "\n";
1006 8         14 $row = $self->{rows};
1007             }
1008             }
1009             }
1010 8         54 0 while chomp $rslt;
1011 8         16 $rslt .= "\n";
1012 8         43 return $rslt;
1013             }
1014              
1015 6     6   19 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 3 my ( $self ) = @_;
1033 1 50 33     5 ( $paster ||= eval {
1034 1         5 require Clipboard;
1035 1         4 Clipboard->import();
1036             return sub {
1037 1     1   3 return Clipboard->paste();
1038 1         6 };
1039             }
1040             ) or croak 'paste() unavailable; can not load Clipboard';
1041              
1042 1         4 $self->problem( $paster->() );
1043 1         3 $self->_unload();
1044 1         3 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 73 my ( $self, $val ) = @_;
1081 19   50     48 $val ||= '';
1082             $val =~ m/\S/ or
1083             $val = "$self->{symbol_list}[0] " x
1084 19 50       96 (scalar @{$self->{cell}} - $self->{cells_unused});
  0         0  
1085 19 100       294 $val =~ s/\s+//g unless $self->{biggest_spec} > 1;
1086 19         58 $val =~ s/^\s+//;
1087 19         77 $val =~ s/\s+$//;
1088 19 50       69 $self->{debug} and print <
1089             Debug problem - Called with $val
1090             eod
1091              
1092 19         41 local $Data::Dumper::Terse = 1;
1093 19 50       31 $self->{largest_set} >= @{$self->{symbol_list}} and croak <
  19         53  
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         26 my $syms = @{$self->{symbol_list}};
  19         31  
1101 19         27 foreach (@{$self->{cell}}) {
  19         42  
1102 1651         2400 $_->{content} = $_->{chosen} = 0;
1103 1651         2226 $_->{possible} = {map {$_ => 0} (1 .. $syms - 1)};
  17167         26053  
1104             }
1105 19         44 foreach (values %{$self->{set}}) {
  19         77  
1106 511         536 $_->{free} = @{$_->{membership}};
  511         639  
1107 511         842 $_->{content} = [$_->{free}];
1108             }
1109 19         29 $self->{cells_unassigned} = scalar @{$self->{cell}} - $self->{cells_unused};
  19         40  
1110              
1111 19         31 my $hash = $self->{symbol_hash};
1112 19         34 my $inx = 0;
1113 19         30 my $max = @{$self->{cell}};
  19         38  
1114 19 100       485 foreach (split (($self->{biggest_spec} > 1 ? '\s+' : ''), $val)) {
1115 1651 50       2316 $inx >= $max and croak <
1116             Error - Too many cell specifications. The topology allows only $max.
1117             eod
1118 1651 50       2272 next unless defined $_;
1119             # was $self->{ignore_unused}
1120 0         0 ($self->{cells_unused} && !@{$self->{cell}[$inx]{membership}})
1121 1651 50 33     2466 and do {$inx++; redo};
  0         0  
  0         0  
1122 1651 100       2407 $self->{allowed_symbols}{$_} and do {
1123 195 50       320 $self->{debug} > 1 and print <
1124             Debug problem - Cell $inx allows symbol set $_
1125             eod
1126 195         228 my $cell = $self->{cell}[$inx];
1127 195 50       200 @{$cell->{membership}} or croak <
  195         324  
1128             Error - Cell $inx is unused, and must be specified as empty.
1129             eod
1130 195         322 for (my $val = 1; $val < $syms; $val++) {
1131 1692 100       2740 next if $self->{allowed_symbols}{$_}[$val];
1132 749         1210 $cell->{possible}{$val} = 1;
1133             }
1134             };
1135 1651 100       2425 defined $hash->{$_} or $_ = $self->{symbol_list}[0];
1136 1651         2826 (@{$self->{cell}[$inx]{membership}} ||
1137 1651 50 33     1682 $_ 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       2440 $self->{debug} > 1 and print <
1142             Debug problem - Cell $inx specifies symbol $_
1143             eod
1144 1651 50       2438 $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       2745 $self->{cell}[$inx]{chosen} = $hash->{$_} ? 1 : 0;
1150             } continue {
1151 1651         2127 $inx++;
1152             }
1153              
1154 19 50       138 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         62 $self->{constraints_used} = {};
1167              
1168 19 50       42 $self->{debug} and print <
1169             Debug problem - problem loaded.
1170             eod
1171              
1172 19         149 $self->{backtrack_stack} = [];
1173 19         43 $self->{cell_order} = [];
1174 19         29 delete $self->{no_more_solutions};
1175              
1176 19 50       38 $self->{debug} > 1 and print " object = ", Dumper ($self);
1177              
1178 19         62 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 183 my ( $self, @args ) = @_;
1227 62         128 while ( @args ) {
1228 90         204 my ( $name, $val ) = splice @args, 0, 2;
1229 90 50       220 exists $mutator{$name} or croak <
1230             Error - Attribute $name does not exist, or is read-only.
1231             eod
1232 90         215 $mutator{$name}->($self, $name, $val );
1233             }
1234 62         101 return $self;
1235             }
1236              
1237             sub _set_allowed_symbols {
1238             ## my ( $self, $name, $value ) = @_;
1239 4     4   11 my ( $self, undef, $value ) = @_; # Name unused
1240 4 50       11 defined $value or $value = '';
1241 4         9 my $maxlen = 0;
1242 4 50       13 $self->{debug} and print <
1243             Debug allowed_symbols being set to '$value'
1244             eod
1245 4 50       10 if ($value) {
1246 4         32 foreach (split '\s+', $value) {
1247 22         48 my ($name, $value) = split '=', $_, 2;
1248 22 50       46 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       37 $value or do {delete $self->{allowed_symbols}{$name}; next};
  2         14  
  2         4  
1253 20         39 $maxlen = max ($maxlen, length ($name));
1254 20 50       36 $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         53 my $const = $self->{allowed_symbols}{$name} = [];
1259 20         45 foreach (split ',', $value) {
1260 93 50       146 $self->{debug} > 1 and print <
1261             Debug allowed_symbols - Adding symbol '$_' to set '$name'.
1262             eod
1263 93 50       134 $self->{symbol_hash}{$_} or croak <
1264             Error - '$_' is not a valid symbol.
1265             eod
1266 93         157 $const->[$self->{symbol_hash}{$_}] = 1;
1267             }
1268             }
1269             } else {
1270 0         0 $self->{allowed_symbols} = {};
1271             }
1272 4 100       16 $self->{biggest_spec} = $maxlen if $maxlen > $self->{biggest_spec};
1273 4         13 return;
1274             }
1275              
1276             sub _set_brick {
1277 6     6   20 my ( $self, undef, $value ) = @_; # $name unused
1278 6 100       24 my ($horiz, $vert, $size) = ref $value ? @$value : split ',', $value;
1279 6 50       21 defined $size
1280             and $self->_deprecation_notice( 'brick_third_argument' );
1281 6   33     50 $size ||= $horiz * $vert;
1282 6 50 33     41 ($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         66 my $rowmul = floor ($size / $horiz);
1287 6         17 my $syms = '.';
1288 6         12 my $topo = '';
1289 6         36 for (my $row = 0; $row < $size; $row++) {
1290 58         76 $syms .= " @{[$row + 1]}";
  58         124  
1291 58         111 for (my $col = 0; $col < $size; $col++) {
1292 616         1789 $topo .= sprintf ' r%d,c%d,s%d', $row, $col,
1293             floor ($row / $vert) * $rowmul + floor ($col / $horiz);
1294             }
1295             }
1296 6         18 substr ($topo, 0, 1, '');
1297 6         23 $self->set (columns => $size, rows => $size, symbols => $syms,
1298             topology => $topo);
1299 6         18 return;
1300             }
1301              
1302             sub _set_corresponding {
1303             ## my ( $self, $name, $order ) = @_;
1304 1     1   4 my ( $self, undef, $order ) = @_; # Name unused
1305 1         4 my $size = $order * $order;
1306 1         5 $self->set (sudoku => $order);
1307 1         3 my $order_minus_1 = $order - 1;
1308 1         3 my $offset = $size * $order;
1309 1         6 for (my $inx = 0; $inx < $size; $inx++) {
1310 9         27 my $base = floor ($inx / $order) * $size + $inx % $order;
1311             $self->add_set ("u$inx", map {
1312 9         19 my $g = $_ * $offset + $base;
  27         32  
1313 27         30 (map {$_ * $order + $g} 0 .. $order_minus_1)} 0 .. $order_minus_1);
  81         120  
1314             }
1315 1         3 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   19 my ( $self, undef, $type ) = @_; # Name unused
1364 2 50       13 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         18 $self->set (symbols => join ' ', '.', 1 .. $self->{largest_set});
1386 2         5 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   6 my ( $self, undef, $size ) = @_; # Name unused
1399 2         3 my $syms = '.';
1400 2         4 my $topo = '';
1401 2         4 my $letter = 'A';
1402 2         8 for (my $row = 0; $row < $size; $row++) {
1403 13         17 $syms .= " @{[$letter++]}";
  13         28  
1404 13         24 for (my $col = 0; $col < $size; $col++) {
1405 97         176 $topo .= sprintf ' r%d,c%d', $row, $col;
1406             }
1407             }
1408 2         5 substr ($topo, 0, 1, '');
1409 2         7 $self->set (columns => $size, rows => $size, symbols => $syms,
1410             topology => $topo);
1411 2         5 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   43 my ( $self, $name, $value ) = @_;
1435 23 50       53 _looks_like_number ($value) or croak <
1436             Error - Attribute $name must be numeric.
1437             eod
1438 23         56 $self->{$name} = $value;
1439 23         55 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   56 my ( $self, $name, $value ) = @_;
1509 21 50       60 _looks_like_number ($value) or croak <
1510             Error - Attribute $name must be numeric.
1511             eod
1512 21 50 33     126 ($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         49 $self->{status_value} = $value;
1517 21         52 $self->{status_text} = $status_values[$value];
1518 21         51 return;
1519             }
1520              
1521             sub _set_sudoku {
1522             ## my ( $self, $name, $order ) = @_;
1523 5     5   16 my ( $self, undef, $order ) = @_; # Name unused
1524 5         25 $self->set( brick => [ $order, $order ] );
1525 5         11 return;
1526             }
1527              
1528             sub _set_sudokux {
1529             ## my ( $self, $name, $order ) = @_;
1530 1     1   3 my ( $self, undef, $order ) = @_; # Name unused
1531 1         5 $self->set (sudoku => $order);
1532 1         3 my $size = $order * $order;
1533 1         3 my $size_minus_1 = $size - 1;
1534 1         3 my $size_plus_1 = $size + 1;
1535 1         4 $self->add_set (d0 => map {$_ * $size_plus_1} 0 .. $size_minus_1);
  9         17  
1536 1         4 $self->add_set (d1 => map {$_ * $size_minus_1} 1 .. $size);
  9         15  
1537 1         3 return;
1538             }
1539              
1540             sub _set_symbols {
1541             ## my ( $self, $name, $value ) = @_;
1542 13     13   35 my ( $self, undef, $value ) = @_; # Name unused
1543 13         140 my @lst = split '\s+', $value;
1544 13         23 my %hsh;
1545 13         20 my $inx = 0;
1546 13         22 my $maxlen = 0;
1547 13         30 foreach (@lst) {
1548 142 50       208 defined $_ or next;
1549 142 50       228 m/,/ and croak <
1550             Error - Symbols may not contain commas.
1551             eod
1552 142 50       206 exists $hsh{$_} and croak <
1553             Error - Symbol '$_' specified more than once.
1554             eod
1555 142         253 $hsh{$_} = $inx++;
1556 142         241 $maxlen = max ($maxlen, length ($_));
1557             }
1558 13         53 $self->{symbol_list} = \@lst;
1559 13         46 $self->{symbol_hash} = \%hsh;
1560 13         29 $self->{symbol_number} = scalar @lst;
1561 13         32 $self->{biggest_spec} = $self->{biggest_symbol} = $maxlen;
1562 13         37 $self->{allowed_symbols} = {};
1563 13         34 return;
1564             }
1565              
1566             sub _set_topology {
1567             ## my ( $self, $name, @args ) = @_;
1568 11     11   28 my ( $self, undef, @args ) = @_; # Name unused
1569 11         988 $self->{cell} = []; # The cells themselves.
1570 11         361 $self->{set} = {}; # The sets themselves.
1571 11         24 $self->{largest_set} = 0;
1572 11         496 $self->{intersection} = {};
1573 11         23 $self->{cells_unused} = 0;
1574 11         18 my $cell_inx = 0;
1575 11         32 foreach my $cell_def (map {split '\s+', $_} @args) {
  11         360  
1576 938         1707 my $cell = {membership => [], index => $cell_inx};
1577 938         1084 push @{$self->{cell}}, $cell;
  938         1310  
1578 938         1731 foreach my $name (sort grep {$_ ne ''} split ',', $cell_def) {
  2717         4775  
1579 2717         3009 foreach my $other (@{$cell->{membership}}) {
  2717         3640  
1580 2620         3421 my $int = "$other,$name";
1581 2620   100     7975 $self->{intersection}{$int} ||= [];
1582 2620         3243 push @{$self->{intersection}{$int}}, $cell_inx;
  2620         4354  
1583             }
1584 2717         2915 push @{$cell->{membership}}, $name;
  2717         4076  
1585 2717   100     5019 my $set = $self->{set}{$name} ||=
1586             {name => $name, membership => []};
1587 2717         2870 push @{$set->{membership}}, $cell_inx;
  2717         5173  
1588             $self->{largest_set} = max ($self->{largest_set},
1589 2717         3158 scalar @{$set->{membership}});
  2717         5357  
1590             }
1591 938 50       1206 @{$cell->{membership}} or $self->{cells_unused}++;
  938         1522  
1592 938         1260 $cell_inx++;
1593             }
1594 11         335 delete $self->{backtrack_stack}; # Force setting of new problem.
1595 11         44 return;
1596             }
1597              
1598 1     1   2 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 46 my ( $self ) = @_;
1620              
1621 19 50       50 $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       43 $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         43 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 2 my ( $self ) = @_;
1684 0         0 return wantarray ? (@{$self->{backtrack_stack}}) :
1685             defined wantarray ?
1686 1 50       4 $self->_format_constraint (@{$self->{backtrack_stack}}) :
  1 50       4  
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         5 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   32 my ( $self ) = @_;
1723 19   50     50 my $stack = $self->{backtrack_stack} ||= []; # May hit this
1724             # when initializing.
1725 19   50     44 my $used = $self->{constraints_used} ||= {};
1726 19         25 my $iterations;
1727             $iterations = $self->{iteration_limit}
1728 19 50       45 if $self->{iteration_limit} > 0;
1729              
1730             $self->{no_more_solutions} and
1731 19 50       41 return $self->_unload (undef, SUDOKU_NO_SOLUTION);
1732              
1733 19 100       27 @{$self->{backtrack_stack}} and do {
  19         37  
1734 1 50       4 $self->_constraint_remove and
1735             return $self->_unload (undef, SUDOKU_NO_SOLUTION);
1736             };
1737              
1738 18 50       39 $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         32 my $number_of_cells = @{$self->{cell}};
  18         27  
1744              
1745             constraint_loop:
1746             { # Begin outer constraint loop.
1747              
1748 18         25 foreach my $constraint (qw{F N B T ?}) {
  356         593  
1749 685 50       789 confess <{cell}} != $number_of_cells;
  685         1346  
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 685   33     2138 my $method = $constraint_method{$constraint} ||
1755             "_constraint_$constraint";
1756 685 50       1714 my $rslt = $self->$method () or next;
1757 685 100       1344 @$rslt or next;
1758 356         530 foreach my $constr (@$rslt) {
1759 1149 50       1647 if (ref $constr) {
1760 1149         1529 push @$stack, $constr;
1761 1149         1701 $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 356 100       703 return $self->_unload ('', SUDOKU_SUCCESS);
1770 338         700 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 356     356   563 my ( $self ) = @_;
1791 356         464 my @stack;
1792 356         432 my $done = 1;
1793              
1794 356         641 while ($done) {
1795 547         632 $done = 0;
1796 547         660 my $inx = 0; # Cell index.
1797 547         620 foreach my $cell (@{$self->{cell}}) {
  547         882  
1798 65630 100       94422 next if $cell->{content}; # Skip already-assigned cells.
1799 30499 50       32243 next unless @{$cell->{membership}}; # Skip unused cells.
  30499         45535  
1800 30499         33386 my $pos = 0;
1801 30499 100       32180 foreach (values %{$cell->{possible}}) {$_ or $pos++};
  30499         51903  
  385548         539419  
1802 30499 100       41186 if ($pos > 1) { # > 1 possibility. Can't apply.
    50          
1803             } elsif ($pos == 1) { # Exactly 1 possibility. Apply.
1804 856         952 my $val;
1805 856         921 foreach (keys %{$cell->{possible}}) {
  856         2338  
1806 4582 100       7032 next if $cell->{possible}{$_};
1807 856         1019 $val = $_;
1808 856         945 last;
1809             }
1810 856 50       1781 $self->_try ($cell, $val) and confess <
1811             Programming error - Passed 'F' constraint but _try failed.
1812             eod
1813 856         1708 my $constraint = [F => [$inx, $val]];
1814             $self->{debug} and
1815 856 50       1455 print '# ', $self->_format_constraint ($constraint);
1816 856         986 $done++;
1817 856         1284 push @stack, $constraint;
1818 856 100       1498 $self->{cells_unassigned} or do {$done = 0; last};
  18         22  
  18         41  
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 65612         79445 $inx++;
1833             }
1834             }
1835 356         1028 return \@stack;
1836             }
1837              
1838             # N constraint - the only cell which supplies a necessary value.
1839              
1840             sub _constraint_N {
1841 293     293   528 my ( $self ) = @_;
1842 293         370 while (my ($name, $set) = each %{$self->{set}}) {
  4062         9680  
1843 4032         4615 my @suppliers;
1844 4032         4582 foreach my $inx (@{$set->{membership}}) {
  4032         6494  
1845 51063         60948 my $cell = $self->{cell}[$inx];
1846 51063 100       76886 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 26004         27939 while (my ($val, $count) = each %{$cell->{possible}}) {
  375887         677040  
1850 349883 100       516066 next if $count;
1851 102657   100     182638 $suppliers[$val] ||= [];
1852 102657         105963 push @{$suppliers[$val]}, $inx;
  102657         171296  
1853             }
1854             }
1855 4032         5120 my $limit = @suppliers;
1856 4032         6931 for (my $val = 1; $val < $limit; $val++) {
1857 43333 100 100     68853 next unless $suppliers[$val] && @{$suppliers[$val]} == 1;
  25292         63949  
1858 263         409 my $inx = $suppliers[$val][0];
1859 263 0       645 $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 263         678 my $constraint = [N => [$inx, $val]];
1868             $self->{debug} and
1869 263 50       519 print '# ', $self->_format_constraint ($constraint);
1870 263         292 keys %{$self->{set}}; # Reset iterator.
  263         379  
1871 263         1067 return [$constraint];
1872             }
1873             }
1874 30         111 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 30     30   62 my ( $self ) = @_;
1888 30         42 my $done = 0;
1889 30         64 while (my ($int, $cells) = each %{$self->{intersection}}) {
  5002         11530  
1890 4996 100       8524 next unless @$cells > 1;
1891 1680         1930 my @int_supplies; # Values supplied by the intersection
1892             my %int_cells; # Cells in the intersection
1893 1680         2549 foreach my $inx (@$cells) {
1894 6404 100       11312 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 3548         6230 $int_cells{$inx} = 1;
1898 3548         3937 while (my ($val, $imposs) = each %{
1899 57367         113042 $self->{cell}[$inx]{possible}}) {
1900 53819 100       85566 $int_supplies[$val] = 1 unless $imposs;
1901             }
1902             }
1903 1680         2034 my %ext_supplies; # Intersection values also supplied outside.
1904             my %ext_cells; # Cells not in the intersection.
1905 1680         3756 my @set_names = split ',', $int;
1906 1680         2248 foreach my $set (@set_names) {
1907 3360         5736 $ext_supplies{$set} = [];
1908 3360         4750 $ext_cells{$set} = [];
1909 3360         3875 foreach my $inx (@{$self->{set}{$set}{membership}}) {
  3360         6211  
1910 49362 100       72547 next if $int_cells{$inx}; # Skip cells in intersection.
1911 42266 100       70518 next if $self->{cell}[$inx]{content};
1912 20236         21806 push @{$ext_cells{$set}}, $inx;
  20236         33960  
1913 20236         23596 while (my ($val, $imposs) = each %{
1914 332372         644509 $self->{cell}[$inx]{possible}}) {
1915 312136 100 100     564387 $ext_supplies{$set}[$val] = 1
1916             if !$imposs && $int_supplies[$val];
1917             }
1918             }
1919             }
1920 1680         4125 for (my $val = 1; $val < @int_supplies; $val++) {
1921 19614 100       32212 next unless $int_supplies[$val];
1922 8261         9998 my @occurs_in = grep {$ext_supplies{$_}[$val]} @set_names;
  16522         26924  
1923 8261 100 100     31253 next unless @occurs_in && @occurs_in < @set_names;
1924 24         42 my %cells_claimed;
1925 24         63 foreach my $set (@occurs_in) {
1926 24         29 foreach my $inx (@{$ext_cells{$set}}) {
  24         57  
1927 127 100       243 next if $self->{cell}[$inx]{possible}{$val};
1928 60         103 $cells_claimed{$inx} = 1;
1929 60         79 $self->{cell}[$inx]{possible}{$val} = 1;
1930 60         83 $done++;
1931             }
1932             }
1933 24 50       89 next unless $done;
1934 24         256 my $constraint = [B => [[sort keys %cells_claimed], $val]];
1935             $self->{debug} and
1936 24 50       95 print '# ', $self->_format_constraint ($constraint);
1937 24         42 keys %{$self->{intersection}}; # Reset iterator.
  24         52  
1938 24         166 return [$constraint];
1939             }
1940             }
1941 6         36 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   15 my ( $self ) = @_;
1967 6         21 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         11 my $syms = @{$self->{symbol_list}};
  6         16  
1971              
1972 6         11 while (my ($name, $set) = each %{$self->{set}}) {
  233         603  
1973 3051         4607 my @open = grep {!$_->{content}}
1974 227 100       257 map {$self->{cell}[$_]} @{$set->{membership}}
  3051         3773  
  227         335  
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 214         392 foreach my $cell (@open) {
1979 1614         2382 for (my $val = 1; $val < $syms; $val++) {
1980 23556 100       40523 $cell->{possible}{$val} and next;
1981 6344   100     9043 $contributors{$name} ||= [];
1982 6344         9555 $contributors{$name}[$val]++;
1983             }
1984             }
1985 214 100       260 @{$contributors{$name}} = map {$_ || 0} @{$contributors{$name}};
  214         398  
  2912         4879  
  214         340  
1986 214         400 $vacant{$name} = \@open;
1987 214   100     534 $tuple[scalar @open] ||= [map {[$_]} 0 .. $#open];
  332         632  
1988             }
1989              
1990 6         29 for (my $order = 2; $order <= $self->{max_tuple}; $order++) {
1991 6         22 for (my $inx = 1; $inx < @tuple; $inx++) {
1992 61 100       111 next unless $tuple[$inx];
1993 45         61 my $max = $inx - 1;
1994 287         393 $tuple[$inx] = [map {my @tpl = @$_;
1995 287         386 map {[@tpl, $_]} $tpl[-1] + 1 .. $max}
  1327         2252  
1996 45         55 grep {$_->[-1] < $max} @{$tuple[$inx]}];
  332         449  
  45         78  
1997 45 50       122 $tuple[$inx] = undef unless @{$tuple[$inx]};
  45         122  
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         49 foreach my $name (keys %vacant) {
2012 49         72 my $open = $vacant{$name};
2013 49 50       91 next unless $tuple[@$open];
2014 49         60 my $contributed = $contributors{$name};
2015 49         57 foreach my $tuple (@{$tuple[@$open]}) {
  49         84  
2016 998         1117 my @tcontr; # number of times each value
2017             # contributed by the tuple.
2018 998         1305 foreach my $inx (@$tuple) {
2019 1996         2404 my $cell = $open->[$inx];
2020 1996         2969 for (my $val = 1; $val < $syms; $val++) {
2021 29990 100       50683 next if $cell->{possible}{$val};
2022 7803         11792 $tcontr[$val]++;
2023             }
2024             }
2025 998 100       1335 @tcontr = map {$_ || 0} @tcontr;
  14866         25182  
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 998         1387 my $discrete = grep {$_} @tcontr;
  14866         16395  
2040 998         1171 my $constraint;
2041             my @tuple_member;
2042 998 100       1747 if ($discrete == $order) {
    50          
2043 11         24 for (my $val = 1; $val < @tcontr; $val++) {
2044 70 100 100     155 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     16 $constraint ||= ['T', 'naked', $order];
2050 4 100       9 @tuple_member or map {$tuple_member[$_] = 1} @$tuple;
  4         9  
2051 4         7 my @ccl;
2052 4         11 for (my $inx = 0; $inx < @$open; $inx++) {
2053             next if $tuple_member[$inx] ||
2054 20 100 100     52 $open->[$inx]{possible}{$val};
2055 10         14 $open->[$inx]{possible}{$val} = 1;
2056 10         11 --$contributed->[$val];
2057 10         25 push @ccl, $open->[$inx]{index};
2058             }
2059 4 50       37 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 987         1070 my $within = 0; # Number of values occuring only
2070             # within tuple.
2071 987         1562 for (my $val = 1; $val < @tcontr; $val++) {
2072 13798 100 100     28806 $within++ if $tcontr[$val] &&
2073             $contributed->[$val] == $tcontr[$val];
2074             }
2075 987 100       1995 next unless $within >= $order;
2076 4         18 $constraint = ['T', 'hidden', $order];
2077 4         8 map {$tuple_member[$_] = 1} @$tuple;
  8         13  
2078 4         15 for (my $val = 1; $val < @tcontr; $val++) {
2079 51 100 100     124 next unless $tcontr[$val] &&
2080             $contributed->[$val] > $tcontr[$val];
2081 11         18 my @ccl;
2082 11         30 for (my $inx = 0; $inx < @$open; $inx++) {
2083             next unless $tuple_member[$inx]
2084 84 100 100     187 && !$open->[$inx]{possible}{$val}
2085             ;
2086 12         19 $open->[$inx]{possible}{$val} = 1;
2087 12         19 --$contributed->[$val];
2088 12         42 --$tcontr[$val];
2089 12         34 push @ccl, $open->[$inx]{index};
2090             }
2091              
2092 11 50       55 push @$constraint, [\@ccl, $val] if @ccl;
2093             }
2094             }
2095              
2096 15 100       34 next unless $constraint;
2097             $self->{debug} and
2098 6 50       20 print '# ', $self->_format_constraint ($constraint);
2099 6         288 return [$constraint];
2100             } # Next tuple
2101             } # Next set containing vacant cells
2102             } # Next order
2103              
2104 0         0 return [];
2105             }
2106              
2107             # ? constraint - initiate backtracking.
2108              
2109             sub _constraint_backtrack {
2110 0     0   0 my ( $self ) = @_;
2111             ## --$iterations >= 0 or return $self->_unload ('', SUDOKU_TOO_HARD)
2112             ## if defined $iterations;
2113 0         0 my @try;
2114 0         0 my $syms = @{$self->{symbol_list}};
  0         0  
2115 0         0 foreach my $cell (@{$self->{cell}}) {
  0         0  
2116 0 0       0 next if $cell->{content};
2117 0 0       0 next unless @{$cell->{membership}};
  0         0  
2118 0         0 my $possible = 0;
2119 0         0 for (my $val = 1; $val < $syms; $val++) {
2120 0 0       0 $possible++ unless $cell->{possible}{$val};
2121             }
2122 0 0       0 $possible or return ['backtrack'];
2123 0         0 push @try, [$cell, $possible];
2124             }
2125 0         0 @try = map {$_->[0]} sort {
2126 0 0       0 $a->[1] <=> $b->[1] || $a->[0]{index} <=> $b->[0]{index}} @try;
  0         0  
2127 0         0 my $cell = $try[0];
2128 0         0 for (my $val = 1; $val < $syms; $val++) {
2129 0 0       0 next if $cell->{possible}{$val};
2130 0 0       0 $self->_try ($cell, $val) and confess <
2131             Programming error - Value $val illegal in cell $cell->{index} for ? constraint, but
2132             \$self->{possible}{$val} = $self->{possible}{$val}
2133             eod
2134 0         0 my $constraint = ['?' => [$cell->{index}, $val]];
2135             $self->{debug}
2136 0 0       0 and print '# ', $self->_format_constraint ($constraint);
2137 0         0 return [$constraint];
2138             }
2139 0         0 return [];
2140             }
2141              
2142             # $status_value = $su->_constraint_remove ();
2143              
2144             # This method removes the topmost constraints from the backtrack
2145             # stack. It continues until the next item is a backtrack item or
2146             # the stack is empty. It returns true (SUDOKU_NO_SOLUTION,
2147             # actually) if the stack is emptied, or false (SUDOKU_SUCCESS,
2148             # actually) if it stops because it found a backtrack item.
2149              
2150             # The following arguments may be passed, for use in preparing
2151             # a generated problem:
2152             # - minimum number of cells to leave occupied (no lower limit
2153             # if this is undefined);
2154             # - maximum number of cells to leave occupied (no upper limit
2155             # if this is undefined);
2156             # - a reference to a hash of constraints that it is legal to
2157             # remove. The hash value is the number of times it is
2158             # legal to remove that constraint, or undef if it can
2159             # be removed any number of times.
2160              
2161             sub _constraint_remove {
2162 1     1   4 my ( $self, $min, $max, $removal_ok ) = @_;
2163 1 50       5 $min and $min = @{$self->{cell}} - $min;
  0         0  
2164 1 50       3 $max and $max = @{$self->{cell}} - $max;
  0         0  
2165 1 50       4 $self->{no_more_solutions} and return SUDOKU_NO_SOLUTION;
2166 1 50       4 my $stack = $self->{backtrack_stack} or return SUDOKU_NO_SOLUTION;
2167 1   50     4 my $used = $self->{constraints_used} ||= {};
2168 1         3 my $inx = @$stack;
2169 1         2 my $syms = @{$self->{symbol_list}};
  1         3  
2170 1 50 33     4 ($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     76 ($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         58 my $constraint = $stack->[$inx][0];
2182 45 50       70 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     72 ($max && $self->{cells_unassigned} <= $max &&
      33        
2201             $constraint eq '?')
2202             and next;
2203             }
2204 45         61 --$used->{$constraint};
2205 45 50 66     74 if ($constraint eq 'F' || $constraint eq 'N') {
    0 0        
    0          
2206 45         55 foreach my $ref (reverse @{$stack->[$inx]}) {
  45         64  
2207 90 100       161 $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         87 pop @$stack;
2248             }
2249 1 50       5 $self->{debug} and print <
2250 0         0 # Debug - Backtrack complete. @{[$old - @$stack]} constraints removed.
2251             # No more solutions to the puzzle exist.
2252             eod
2253 1         2 $self->{no_more_solutions} = 1;
2254 1         6 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         3 foreach (@args) {
2298 52         58 my @stuff;
2299 52         70 foreach (@$_) {
2300 104 50       145 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       237 $self->{symbol_list}[$_->[1]],
    50          
    100          
2307             ) . ']' :
2308             $_;
2309             }
2310 52         126 push @steps, join (' ', @stuff) . "\n";
2311             }
2312 1         10 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   83 ( local $_ ) = @_;
2323 44 50 33     160 return 0 if !defined ($_) || ref ($_);
2324 44 50       343 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   4067 my ( $self, $cell, $new ) = @_;
2341 2815 100       4550 $cell = $self->{cell}[$cell] unless ref $cell;
2342 2815 50       4328 defined $new
2343             or _fatal (
2344             "_try called for cell $cell->{index} with new value undefined");
2345 2815 50       4239 defined (my $old = $cell->{content}) or _fatal (
2346             "_try called with old cell $cell->{index} value undefined");
2347 2815         3241 my $rslt = eval {
2348 2815 100       4534 return 0 if $old == $new;
2349 1644 100       2449 if ($new) {
2350 1599         1788 foreach my $set (@{$cell->{membership}}) {
  1599         2529  
2351 4833 50       9123 return 1 if $self->{set}{$set}{content}[$new];
2352             }
2353             }
2354 1644         2377 $cell->{content} = $new;
2355 1644 100       2291 $old and $self->{cells_unassigned}++;
2356 1644 100       2580 $new and --$self->{cells_unassigned};
2357 1644         1765 foreach my $name (@{$cell->{membership}}) {
  1644         2334  
2358 4968         6327 my $set = $self->{set}{$name};
2359 4968         5679 --$set->{content}[$old];
2360 4968 100       6791 $old and do {
2361 135         149 $set->{free}++;
2362 135         143 foreach (@{$set->{membership}}) {
  135         173  
2363 1215         1567 --$self->{cell}[$_]{possible}{$old};
2364             }
2365             };
2366 4968         6663 $set->{content}[$new]++;
2367 4968 100       6936 $new and do {
2368 4833         5371 --$set->{free};
2369 4833         5255 foreach (@{$set->{membership}}) {
  4833         6740  
2370 50421         69566 $self->{cell}[$_]{possible}{$new}++;
2371             }
2372             };
2373             }
2374 1644         2218 return 0;
2375             };
2376 2815 50       4094 $@ and _fatal ("Eval failed in _try", $@);
2377 2815         4552 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   58 my ($self, $prefix, @args) = @_;
2390 23 100       64 defined $prefix or $prefix = '';
2391 23 100       52 @args and do {
2392 19         90 $self->set (status_value => $args[0]);
2393 19 100       51 $args[0] and return;
2394             };
2395 22         39 my $rslt = '';
2396 22         39 my $col = $self->{columns};
2397 22   33     46 my $row = $self->{rows} ||= floor (@{$self->{cell}} / $col);
  0         0  
2398 22         70 my $fmt = "%$self->{biggest_symbol}s";
2399 22         30 foreach (@{$self->{cell}}) {
  22         54  
2400 1894 100       2614 $col == $self->{columns} and $rslt .= $prefix;
2401             # was $self->{ignore_unused}
2402             $rslt .= ($self->{cells_unused} && !@{$_->{membership}}) ?
2403             sprintf ($fmt, ' ') :
2404 1894 50 33     4503 sprintf ($fmt, $self->{symbol_list}[$_->{content} || 0]);
      100        
2405 1894 100       2457 if (--$col > 0) {
2406             $rslt .= $self->{output_delimiter}
2407 1674         2207 } else {
2408             # was $self->{ignore_unused}
2409 220 50       344 $self->{cells_unused} and $rslt =~ s/\s+$//m;
2410 220         262 $rslt .= "\n";
2411 220         264 $col = $self->{columns};
2412 220 100       355 if (--$row <= 0) {
2413 29         38 $rslt .= "\n";
2414 29         52 $row = $self->{rows};
2415             }
2416             }
2417             }
2418 22         86 0 while chomp $rslt;
2419 22         30 $rslt .= "\n";
2420 22         257 return $rslt;
2421             }
2422              
2423             1;
2424              
2425             __END__