27{
32 typedef typename compositor_t::function function_t;
33
34 std::vector<T> board =
35 {
36 0, 0, 0, 0, 0, 8, 2, 0, 5,
37 0, 0, 0, 3, 2, 0, 0, 0, 8,
38 0, 0, 0, 0, 0, 5, 6, 0, 0,
39 0, 1, 0, 0, 4, 7, 0, 9, 3,
40 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 8, 6, 0, 2, 3, 0, 0, 1, 0,
42 0, 0, 6, 8, 0, 0, 0, 0, 0,
43 5, 0, 0, 0, 7, 3, 0, 0, 0,
44 4, 0, 3, 9, 0, 0, 0, 0, 0,
45 };
46
48
49 symbol_table_t symbol_table;
50 symbol_table.add_vector ("board", board);
51 symbol_table.add_function("print_digit",
52 [](T v) ->T
53 { printf(" %d ",static_cast<int>(v)); return 0; });
54 symbol_table.add_package (io_package);
55
56 compositor_t compositor(symbol_table);
57
58 compositor.load_variables(true);
59 compositor.load_vectors (true);
60
61 compositor.add(
62 function_t("get_board")
63 .vars("col", "row")
64 .expression
65 ( " board[row * sqrt(board[]) + col]; " ));
66
67 compositor.add(
68 function_t("set_board")
69 .vars("col", "row", "value")
70 .expression
71 ( " board[row * sqrt(board[]) + col] := value; " ));
72
73 compositor.add(
74 function_t("display_board")
75 .expression
76 (
77 " const var n := sqrt(board[]); "
78 " "
79 " for (var row := 0; row < n; row += 1) "
80 " { "
81 " for (var col := 0; col < n; col += 1) "
82 " { "
83 " print_digit(get_board(col,row)); "
84 " "
85 " if ((col > 0) and (col < 8) and (col + 1) % 3 == 0) "
86 " { "
87 " print('|') "
88 " } "
89 " }; "
90 " "
91 " println(''); "
92 " "
93 " if ((row > 0) and (row < 8) and (row + 1) % 3 == 0) "
94 " { "
95 " println('---------+---------+----------'); "
96 " } "
97 " } "
98 ));
99
100 compositor.add(
101 function_t("is_valid")
102 .vars("col", "row", "num")
103 .expression
104 (
105 " const var n := sqrt(board[]); "
106 " "
107 " for (var i := 0; i < n; i += 1) "
108 " { "
109 " if ( "
110 " (get_board(col, i ) == num) or "
111 " (get_board(i , row) == num) "
112 " ) "
113 " { "
114 " return [false]; "
115 " } "
116 " }; "
117 " "
118 " var subgrid_row := row - floor(row % 3); "
119 " var subgrid_col := col - floor(col % 3); "
120 " "
121 " for (var i := subgrid_row; i < subgrid_row + 3; i += 1) "
122 " { "
123 " for (var j := subgrid_col; j < subgrid_col + 3; j += 1) "
124 " { "
125 " if (get_board(j,i) == num) "
126 " { "
127 " return [false]; "
128 " } "
129 " } "
130 " }; "
131 " "
132 " return [true]; "
133 ));
134
135 compositor.add(
136 function_t("solve_sudoku")
137 .expression
138 (
139 " const var n := sqrt(board[]); "
140 " "
141 " for (var row := 0; row < n; row += 1) "
142 " { "
143 " for (var col := 0; col < n; col += 1) "
144 " { "
145 " if (get_board(col, row) != 0) "
146 " { "
147 " continue; "
148 " } "
149 " "
150 " for (var num := 1; num <= 9; num += 1) "
151 " { "
152 " if (not(is_valid(col, row, num))) "
153 " { "
154 " continue; "
155 " } "
156 " "
157 " set_board(col, row, num); "
158 " "
159 " if (solve_sudoku()) "
160 " { "
161 " return [true]; "
162 " }; "
163 " "
164 " set_board(col, row, 0); "
165 " }; "
166 " "
167 " return [false]; "
168 " } "
169 " }; "
170 " "
171 " return [true]; "
172 ));
173
174 const std::string sudoku_solver_program =
175 " if (solve_sudoku()) "
176 " { "
177 " println('Puzzle Solved!'); "
178 " } "
179 " else "
180 " { "
181 " println('Error: Failed to solve puzzle.'); "
182 " }; "
183 " "
184 " display_board(); ";
185
186 expression_t expression;
187 expression.register_symbol_table(symbol_table);
188
189 parser_t parser;
190 parser.compile(sudoku_solver_program,expression);
191
192 expression.value();
193}