1/*
2Redistribution and use in source and binary forms, with or without
3modification, are permitted provided that the following conditions are met:
4
5    * Redistributions of source code must retain the above copyright
6    notice, this list of conditions and the following disclaimer.
7
8    * Redistributions in binary form must reproduce the above copyright
9    notice, this list of conditions and the following disclaimer in the
10    documentation and/or other materials provided with the distribution.
11
12    * Neither the name of "The Computer Language Benchmarks Game" nor the
13    name of "The Computer Language Shootout Benchmarks" nor the names of
14    its contributors may be used to endorse or promote products derived
15    from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27POSSIBILITY OF SUCH DAMAGE.
28*/
29
30/* The Computer Language Benchmarks Game
31 * http://shootout.alioth.debian.org/
32 *
33 * contributed by Christian Vosteen
34 */
35
36#include <stdlib.h>
37#include <stdio.h>
38#define TRUE 1
39#define FALSE 0
40
41/* The board is a 50 cell hexagonal pattern.  For    . . . . .
42 * maximum speed the board will be implemented as     . . . . .
43 * 50 bits, which will fit into a 64 bit long long   . . . . .
44 * int.                                               . . . . .
45 *                                                   . . . . .
46 * I will represent 0's as empty cells and 1's        . . . . .
47 * as full cells.                                    . . . . .
48 *                                                    . . . . .
49 *                                                   . . . . .
50 *                                                    . . . . .
51 */
52
53unsigned long long board = 0xFFFC000000000000ULL;
54
55/* The puzzle pieces must be specified by the path followed
56 * from one end to the other along 12 hexagonal directions.
57 *
58 *   Piece 0   Piece 1   Piece 2   Piece 3   Piece 4
59 *
60 *  O O O O    O   O O   O O O     O O O     O   O
61 *         O    O O           O       O       O O
62 *                           O         O         O
63 *
64 *   Piece 5   Piece 6   Piece 7   Piece 8   Piece 9
65 *
66 *    O O O     O O       O O     O O        O O O O
67 *       O O       O O       O       O O O        O
68 *                  O       O O
69 *
70 * I had to make it 12 directions because I wanted all of the
71 * piece definitions to fit into the same size arrays.  It is
72 * not possible to define piece 4 in terms of the 6 cardinal
73 * directions in 4 moves.
74 */
75
76#define E     0
77#define ESE   1
78#define SE    2
79#define S     3
80#define SW    4
81#define WSW   5
82#define W     6
83#define WNW   7
84#define NW    8
85#define N     9
86#define NE    10
87#define ENE   11
88#define PIVOT 12
89
90char piece_def[10][4] = {
91   {  E,  E,  E, SE},
92   { SE,  E, NE,  E},
93   {  E,  E, SE, SW},
94   {  E,  E, SW, SE},
95   { SE,  E, NE,  S},
96   {  E,  E, SW,  E},
97   {  E, SE, SE, NE},
98   {  E, SE, SE,  W},
99   {  E, SE,  E,  E},
100   {  E,  E,  E, SW}
101};
102
103
104/* To minimize the amount of work done in the recursive solve function below,
105 * I'm going to allocate enough space for all legal rotations of each piece
106 * at each position on the board. That's 10 pieces x 50 board positions x
107 * 12 rotations.  However, not all 12 rotations will fit on every cell, so
108 * I'll have to keep count of the actual number that do.
109 * The pieces are going to be unsigned long long ints just like the board so
110 * they can be bitwise-anded with the board to determine if they fit.
111 * I'm also going to record the next possible open cell for each piece and
112 * location to reduce the burden on the solve function.
113 */
114unsigned long long pieces[10][50][12];
115int piece_counts[10][50];
116char next_cell[10][50][12];
117
118/* Returns the direction rotated 60 degrees clockwise */
119char rotate(char dir) {
120   return (dir + 2) % PIVOT;
121}
122
123/* Returns the direction flipped on the horizontal axis */
124char flip(char dir) {
125   return (PIVOT - dir) % PIVOT;
126}
127
128
129/* Returns the new cell index from the specified cell in the
130 * specified direction.  The index is only valid if the
131 * starting cell and direction have been checked by the
132 * out_of_bounds function first.
133 */
134char shift(char cell, char dir) {
135   switch(dir) {
136      case E:
137         return cell + 1;
138      case ESE:
139         if((cell / 5) % 2)
140            return cell + 7;
141         else
142            return cell + 6;
143      case SE:
144         if((cell / 5) % 2)
145            return cell + 6;
146         else
147            return cell + 5;
148      case S:
149         return cell + 10;
150      case SW:
151         if((cell / 5) % 2)
152            return cell + 5;
153         else
154            return cell + 4;
155      case WSW:
156         if((cell / 5) % 2)
157            return cell + 4;
158         else
159            return cell + 3;
160      case W:
161         return cell - 1;
162      case WNW:
163         if((cell / 5) % 2)
164            return cell - 6;
165         else
166            return cell - 7;
167      case NW:
168         if((cell / 5) % 2)
169            return cell - 5;
170         else
171            return cell - 6;
172      case N:
173         return cell - 10;
174      case NE:
175         if((cell / 5) % 2)
176            return cell - 4;
177         else
178            return cell - 5;
179      case ENE:
180         if((cell / 5) % 2)
181            return cell - 3;
182         else
183            return cell - 4;
184      default:
185         return cell;
186   }
187}
188
189/* Returns wether the specified cell and direction will land outside
190 * of the board.  Used to determine if a piece is at a legal board
191 * location or not.
192 */
193char out_of_bounds(char cell, char dir) {
194   char i;
195   switch(dir) {
196      case E:
197         return cell % 5 == 4;
198      case ESE:
199         i = cell % 10;
200         return i == 4 || i == 8 || i == 9 || cell >= 45;
201      case SE:
202         return cell % 10 == 9 || cell >= 45;
203      case S:
204         return cell >= 40;
205      case SW:
206         return cell % 10 == 0 || cell >= 45;
207      case WSW:
208         i = cell % 10;
209         return i == 0 || i == 1 || i == 5 || cell >= 45;
210      case W:
211         return cell % 5 == 0;
212      case WNW:
213         i = cell % 10;
214         return i == 0 || i == 1 || i == 5 || cell < 5;
215      case NW:
216         return cell % 10 == 0 || cell < 5;
217      case N:
218         return cell < 10;
219      case NE:
220         return cell % 10 == 9 || cell < 5;
221      case ENE:
222         i = cell % 10;
223         return i == 4 || i == 8 || i == 9 || cell < 5;
224      default:
225         return FALSE;
226   }
227}
228
229/* Rotate a piece 60 degrees clockwise */
230void rotate_piece(int piece) {
231   int i;
232   for(i = 0; i < 4; i++)
233      piece_def[piece][i] = rotate(piece_def[piece][i]);
234}
235
236/* Flip a piece along the horizontal axis */
237void flip_piece(int piece) {
238   int i;
239   for(i = 0; i < 4; i++)
240      piece_def[piece][i] = flip(piece_def[piece][i]);
241}
242
243/* Convenience function to quickly calculate all of the indices for a piece */
244void calc_cell_indices(char *cell, int piece, char index) {
245   cell[0] = index;
246   cell[1] = shift(cell[0], piece_def[piece][0]);
247   cell[2] = shift(cell[1], piece_def[piece][1]);
248   cell[3] = shift(cell[2], piece_def[piece][2]);
249   cell[4] = shift(cell[3], piece_def[piece][3]);
250}
251
252/* Convenience function to quickly calculate if a piece fits on the board */
253int cells_fit_on_board(char *cell, int piece) {
254   return (!out_of_bounds(cell[0], piece_def[piece][0]) &&
255         !out_of_bounds(cell[1], piece_def[piece][1]) &&
256         !out_of_bounds(cell[2], piece_def[piece][2]) &&
257         !out_of_bounds(cell[3], piece_def[piece][3]));
258}
259
260/* Returns the lowest index of the cells of a piece.
261 * I use the lowest index that a piece occupies as the index for looking up
262 * the piece in the solve function.
263 */
264char minimum_of_cells(char *cell) {
265   char minimum = cell[0];
266   minimum = cell[1] < minimum ? cell[1] : minimum;
267   minimum = cell[2] < minimum ? cell[2] : minimum;
268   minimum = cell[3] < minimum ? cell[3] : minimum;
269   minimum = cell[4] < minimum ? cell[4] : minimum;
270   return minimum;
271}
272
273/* Calculate the lowest possible open cell if the piece is placed on the board.
274 * Used to later reduce the amount of time searching for open cells in the
275 * solve function.
276 */
277char first_empty_cell(char *cell, char minimum) {
278   char first_empty = minimum;
279   while(first_empty == cell[0] || first_empty == cell[1] ||
280         first_empty == cell[2] || first_empty == cell[3] ||
281         first_empty == cell[4])
282      first_empty++;
283   return first_empty;
284}
285
286/* Generate the unsigned long long int that will later be anded with the
287 * board to determine if it fits.
288 */
289unsigned long long bitmask_from_cells(char *cell) {
290   unsigned long long piece_mask = 0ULL;
291   int i;
292   for(i = 0; i < 5; i++)
293      piece_mask |= 1ULL << cell[i];
294   return piece_mask;
295}
296
297/* Record the piece and other important information in arrays that will
298 * later be used by the solve function.
299 */
300void record_piece(int piece, int minimum, char first_empty,
301      unsigned long long piece_mask) {
302   pieces[piece][minimum][piece_counts[piece][minimum]] = piece_mask;
303   next_cell[piece][minimum][piece_counts[piece][minimum]] = first_empty;
304   piece_counts[piece][minimum]++;
305}
306
307
308/* Fill the entire board going cell by cell.  If any cells are "trapped"
309 * they will be left alone.
310 */
311void fill_contiguous_space(char *board, int index) {
312   if(board[index] == 1)
313      return;
314   board[index] = 1;
315   if(!out_of_bounds(index, E))
316      fill_contiguous_space(board, shift(index, E));
317   if(!out_of_bounds(index, SE))
318      fill_contiguous_space(board, shift(index, SE));
319   if(!out_of_bounds(index, SW))
320      fill_contiguous_space(board, shift(index, SW));
321   if(!out_of_bounds(index, W))
322      fill_contiguous_space(board, shift(index, W));
323   if(!out_of_bounds(index, NW))
324      fill_contiguous_space(board, shift(index, NW));
325   if(!out_of_bounds(index, NE))
326      fill_contiguous_space(board, shift(index, NE));
327}
328
329
330/* To thin the number of pieces, I calculate if any of them trap any empty
331 * cells at the edges.  There are only a handful of exceptions where the
332 * the board can be solved with the trapped cells.  For example:  piece 8 can
333 * trap 5 cells in the corner, but piece 3 can fit in those cells, or piece 0
334 * can split the board in half where both halves are viable.
335 */
336int has_island(char *cell, int piece) {
337   char temp_board[50];
338   char c;
339   int i;
340   for(i = 0; i < 50; i++)
341      temp_board[i] = 0;
342   for(i = 0; i < 5; i++)
343      temp_board[((int)cell[i])] = 1;
344   i = 49;
345   while(temp_board[i] == 1)
346      i--;
347   fill_contiguous_space(temp_board, i);
348   c = 0;
349   for(i = 0; i < 50; i++)
350      if(temp_board[i] == 0)
351         c++;
352   if(c == 0 || (c == 5 && piece == 8) || (c == 40 && piece == 8) ||
353         (c % 5 == 0 && piece == 0))
354      return FALSE;
355   else
356      return TRUE;
357}
358
359
360/* Calculate all six rotations of the specified piece at the specified index.
361 * We calculate only half of piece 3's rotations.  This is because any solution
362 * found has an identical solution rotated 180 degrees.  Thus we can reduce the
363 * number of attempted pieces in the solve algorithm by not including the 180-
364 * degree-rotated pieces of ONE of the pieces.  I chose piece 3 because it gave
365 * me the best time ;)
366 */
367 void calc_six_rotations(char piece, char index) {
368   char rotation, cell[5];
369   char minimum, first_empty;
370   unsigned long long piece_mask;
371
372   for(rotation = 0; rotation < 6; rotation++) {
373      if(piece != 3 || rotation < 3) {
374         calc_cell_indices(cell, piece, index);
375         if(cells_fit_on_board(cell, piece) && !has_island(cell, piece)) {
376            minimum = minimum_of_cells(cell);
377            first_empty = first_empty_cell(cell, minimum);
378            piece_mask = bitmask_from_cells(cell);
379            record_piece(piece, minimum, first_empty, piece_mask);
380         }
381      }
382      rotate_piece(piece);
383   }
384}
385
386/* Calculate every legal rotation for each piece at each board location. */
387void calc_pieces(void) {
388   char piece, index;
389
390   for(piece = 0; piece < 10; piece++) {
391      for(index = 0; index < 50; index++) {
392         calc_six_rotations(piece, index);
393         flip_piece(piece);
394         calc_six_rotations(piece, index);
395      }
396   }
397}
398
399
400
401/* Calculate all 32 possible states for a 5-bit row and all rows that will
402 * create islands that follow any of the 32 possible rows.  These pre-
403 * calculated 5-bit rows will be used to find islands in a partially solved
404 * board in the solve function.
405 */
406#define ROW_MASK 0x1F
407#define TRIPLE_MASK 0x7FFF
408char all_rows[32] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
409      17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
410int bad_even_rows[32][32];
411int bad_odd_rows[32][32];
412int bad_even_triple[32768];
413int bad_odd_triple[32768];
414
415int rows_bad(char row1, char row2, int even) {
416   /* even is referring to row1 */
417   int i, in_zeroes, group_okay;
418   char block, row2_shift;
419   /* Test for blockages at same index and shifted index */
420   if(even)
421      row2_shift = ((row2 << 1) & ROW_MASK) | 0x01;
422   else
423      row2_shift = (row2 >> 1) | 0x10;
424   block = ((row1 ^ row2) & row2) & ((row1 ^ row2_shift) & row2_shift);
425   /* Test for groups of 0's */
426   in_zeroes = FALSE;
427   group_okay = FALSE;
428   for(i = 0; i < 5; i++) {
429      if(row1 & (1 << i)) {
430         if(in_zeroes) {
431            if(!group_okay)
432               return TRUE;
433            in_zeroes = FALSE;
434            group_okay = FALSE;
435         }
436      } else {
437         if(!in_zeroes)
438            in_zeroes = TRUE;
439         if(!(block & (1 << i)))
440            group_okay = TRUE;
441      }
442   }
443   if(in_zeroes)
444      return !group_okay;
445   else
446      return FALSE;
447}
448
449/* Check for cases where three rows checked sequentially cause a false
450 * positive.  One scenario is when 5 cells may be surrounded where piece 5
451 * or 7 can fit.  The other scenario is when piece 2 creates a hook shape.
452 */
453int triple_is_okay(char row1, char row2, char row3, int even) {
454   if(even) {
455      /* There are four cases:
456       * row1: 00011  00001  11001  10101
457       * row2: 01011  00101  10001  10001
458       * row3: 011??  00110  ?????  ?????
459       */
460      return ((row1 == 0x03) && (row2 == 0x0B) && ((row3 & 0x1C) == 0x0C)) ||
461            ((row1 == 0x01) && (row2 == 0x05) && (row3 == 0x06)) ||
462            ((row1 == 0x19) && (row2 == 0x11)) ||
463            ((row1 == 0x15) && (row2 == 0x11));
464   } else {
465      /* There are two cases:
466       * row1: 10011  10101
467       * row2: 10001  10001
468       * row3: ?????  ?????
469       */
470      return ((row1 == 0x13) && (row2 == 0x11)) ||
471            ((row1 == 0x15) && (row2 == 0x11));
472   }
473}
474
475
476void calc_rows(void) {
477   int row1, row2, row3;
478   int result1, result2;
479   for(row1 = 0; row1 < 32; row1++) {
480      for(row2 = 0; row2 < 32; row2++) {
481         bad_even_rows[row1][row2] = rows_bad(row1, row2, TRUE);
482         bad_odd_rows[row1][row2] = rows_bad(row1, row2, FALSE);
483      }
484   }
485   for(row1 = 0; row1 < 32; row1++) {
486      for(row2 = 0; row2 < 32; row2++) {
487         for(row3 = 0; row3 < 32; row3++) {
488            result1 = bad_even_rows[row1][row2];
489            result2 = bad_odd_rows[row2][row3];
490            if(result1 == FALSE && result2 == TRUE
491                  && triple_is_okay(row1, row2, row3, TRUE))
492               bad_even_triple[row1+(row2*32)+(row3*1024)] = FALSE;
493            else
494               bad_even_triple[row1+(row2*32)+(row3*1024)] = result1 || result2;
495
496            result1 = bad_odd_rows[row1][row2];
497            result2 = bad_even_rows[row2][row3];
498            if(result1 == FALSE && result2 == TRUE
499                  && triple_is_okay(row1, row2, row3, FALSE))
500               bad_odd_triple[row1+(row2*32)+(row3*1024)] = FALSE;
501            else
502               bad_odd_triple[row1+(row2*32)+(row3*1024)] = result1 || result2;
503         }
504      }
505   }
506}
507
508
509
510/* Calculate islands while solving the board.
511 */
512int boardHasIslands(char cell) {
513   /* Too low on board, don't bother checking */
514   if(cell >= 40)
515      return FALSE;
516   int current_triple = (board >> ((cell / 5) * 5)) & TRIPLE_MASK;
517   if((cell / 5) % 2)
518      return bad_odd_triple[current_triple];
519   else
520      return bad_even_triple[current_triple];
521}
522
523
524/* The recursive solve algorithm.  Try to place each permutation in the upper-
525 * leftmost empty cell.  Mark off available pieces as it goes along.
526 * Because the board is a bit mask, the piece number and bit mask must be saved
527 * at each successful piece placement.  This data is used to create a 50 char
528 * array if a solution is found.
529 */
530short avail = 0x03FF;
531char sol_nums[10];
532unsigned long long sol_masks[10];
533signed char solutions[2100][50];
534int solution_count = 0;
535int max_solutions = 2100;
536
537void record_solution(void) {
538   int sol_no, index;
539   unsigned long long sol_mask;
540   for(sol_no = 0; sol_no < 10; sol_no++) {
541      sol_mask = sol_masks[sol_no];
542      for(index = 0; index < 50; index++) {
543         if(sol_mask & 1ULL) {
544            solutions[solution_count][index] = sol_nums[sol_no];
545            /* Board rotated 180 degrees is a solution too! */
546            solutions[solution_count+1][49-index] = sol_nums[sol_no];
547         }
548         sol_mask = sol_mask >> 1;
549      }
550   }
551   solution_count += 2;
552}
553
554void solve(int depth, int cell) {
555   int piece, rotation, max_rots;
556   unsigned long long *piece_mask;
557   short piece_no_mask;
558
559   if(solution_count >= max_solutions)
560      return;
561
562   while(board & (1ULL << cell))
563      cell++;
564
565   for(piece = 0; piece < 10; piece++) {
566      piece_no_mask = 1 << piece;
567      if(!(avail & piece_no_mask))
568         continue;
569      avail ^= piece_no_mask;
570      max_rots = piece_counts[piece][cell];
571      piece_mask = pieces[piece][cell];
572      for(rotation = 0; rotation < max_rots; rotation++) {
573         if(!(board & *(piece_mask + rotation))) {
574            sol_nums[depth] = piece;
575            sol_masks[depth] = *(piece_mask + rotation);
576            if(depth == 9) {
577               /* Solution found!!!!!11!!ONE! */
578               record_solution();
579               avail ^= piece_no_mask;
580               return;
581            }
582            board |= *(piece_mask + rotation);
583            if(!boardHasIslands(next_cell[piece][cell][rotation]))
584               solve(depth + 1, next_cell[piece][cell][rotation]);
585            board ^= *(piece_mask + rotation);
586         }
587      }
588      avail ^= piece_no_mask;
589   }
590}
591
592
593/* qsort comparator - used to find first and last solutions */
594int solution_sort(const void *elem1, const void *elem2) {
595   signed char *char1 = (signed char *) elem1;
596   signed char *char2 = (signed char *) elem2;
597   int i = 0;
598   while(i < 50 && char1[i] == char2[i])
599      i++;
600   return char1[i] - char2[i];
601}
602
603
604/* pretty print a board in the specified hexagonal format */
605void pretty(signed char *b) {
606   int i;
607   for(i = 0; i < 50; i += 10) {
608      printf("%c %c %c %c %c \n %c %c %c %c %c \n", b[i]+'0', b[i+1]+'0',
609            b[i+2]+'0', b[i+3]+'0', b[i+4]+'0', b[i+5]+'0', b[i+6]+'0',
610            b[i+7]+'0', b[i+8]+'0', b[i+9]+'0');
611   }
612   printf("\n");
613}
614
615int main(int argc, char **argv) {
616   if(argc > 1)
617      max_solutions = atoi(argv[1]);
618   calc_pieces();
619   calc_rows();
620   solve(0, 0);
621   printf("%d solutions found\n\n", solution_count);
622   qsort(solutions, solution_count, 50 * sizeof(signed char), solution_sort);
623   pretty(solutions[0]);
624   pretty(solutions[solution_count-1]);
625   return 0;
626}
627