00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <gecode/driver.hh>
00039 #include <gecode/int.hh>
00040 #include <gecode/minimodel.hh>
00041
00042 using namespace Gecode;
00043
00044 namespace {
00045
00047 extern const int* specs[];
00049 extern const unsigned int n_examples;
00050
00051 }
00052
00067 class Nonogram : public Script {
00068 protected:
00070 const int* spec;
00072 BoolVarArray b;
00073
00075 int width(void) const {
00076 return spec[0];
00077 }
00079 int height(void) const {
00080 return spec[1];
00081 }
00082
00084 DFA line(int& spos) {
00085 REG r0(0), r1(1);
00086 REG border = *r0;
00087 REG between = +r0;
00088 int hints = spec[spos++];
00089 REG r = border + r1(spec[spos],spec[spos]);
00090 spos++;
00091 for (int i=hints-1; i--; spos++)
00092 r += between + r1(spec[spos],spec[spos]);
00093 return r + border;
00094 }
00095
00096
00097 public:
00099 Nonogram(const SizeOptions& opt)
00100 : spec(specs[opt.size()]), b(*this,width()*height(),0,1) {
00101 Matrix<BoolVarArray> m(b, width(), height());
00102
00103 {
00104 int spos = 2;
00105
00106 for (int w=0; w<width(); w++)
00107 extensional(*this, m.col(w), line(spos));
00108
00109 for (int h=0; h<height(); h++)
00110 extensional(*this, m.row(h), line(spos));
00111 }
00112
00113
00114 int cols = 0;
00115
00116 int rows = 0;
00117
00118 {
00119 int spos = 2;
00120 for (int w=0; w<width(); w++) {
00121 int hint = spec[spos++];
00122 cols += hint; spos += hint;
00123 }
00124 for (int h=0; h<height(); h++) {
00125 int hint = spec[spos++];
00126 rows += hint; spos += hint;
00127 }
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 if (rows*width() > cols*height()) {
00139 for (int w=0; w<width(); w++)
00140 branch(*this, m.col(w), INT_VAR_NONE, INT_VAL_MAX);
00141 } else {
00142 for (int h=0; h<height(); h++)
00143 branch(*this, m.row(h), INT_VAR_NONE, INT_VAL_MAX);
00144 }
00145 }
00146
00148 Nonogram(bool share, Nonogram& s) : Script(share,s), spec(s.spec) {
00149 b.update(*this, share, s.b);
00150 }
00151
00153 virtual Space*
00154 copy(bool share) {
00155 return new Nonogram(share,*this);
00156 }
00157
00159 virtual void
00160 print(std::ostream& os) const {
00161 Matrix<BoolVarArray> m(b, width(), height());
00162 for (int h = 0; h < height(); ++h) {
00163 os << '\t';
00164 for (int w = 0; w < width(); ++w)
00165 os << ((m(w,h).val() == 1) ? '#' : ' ');
00166 os << std::endl;
00167 }
00168 os << std::endl;
00169 }
00170 };
00171
00172
00176 int
00177 main(int argc, char* argv[]) {
00178 SizeOptions opt("Nonogram");
00179 opt.size(8);
00180 opt.parse(argc,argv);
00181 if (opt.size() >= n_examples) {
00182 std::cerr << "Error: size must be between 0 and "
00183 << n_examples-1 << std::endl;
00184 return 1;
00185 }
00186 Script::run<Nonogram,DFS,SizeOptions>(opt);
00187 return 0;
00188 }
00189
00190 namespace {
00191
00203
00204 const int heart[] =
00205 { 9, 9,
00206
00207 1, 3,
00208 2, 2, 3,
00209 2, 2, 2,
00210 2, 2, 2,
00211 2, 2, 2,
00212 2, 2, 2,
00213 2, 2, 2,
00214 2, 2, 3,
00215 1, 3,
00216
00217 2, 2, 2,
00218 2, 4, 4,
00219 3, 1, 3, 1,
00220 3, 2, 1, 2,
00221 2, 1, 1,
00222 2, 2, 2,
00223 2, 2, 2,
00224 1, 3,
00225 1, 1
00226 };
00227
00229 const int bear[] =
00230 { 13, 8,
00231
00232 1, 2,
00233 2, 2, 1,
00234 2, 3, 2,
00235 1, 6,
00236 2, 1, 4,
00237 1, 3,
00238 1, 4,
00239 1, 4,
00240 1, 4,
00241 1, 5,
00242 1, 4,
00243 2, 1, 3,
00244 1, 2,
00245
00246 1, 1,
00247 1, 2,
00248 2, 4, 4,
00249 1, 12,
00250 1, 8,
00251 1, 9,
00252 2, 3, 4,
00253 2, 2, 2
00254 };
00255
00257 const int crocodile[] =
00258 { 15, 9,
00259
00260 1, 3,
00261 1, 4,
00262 2, 2, 2,
00263 2, 3, 1,
00264 2, 2, 3,
00265 2, 3, 2,
00266 2, 2, 3,
00267 2, 4, 2,
00268 2, 3, 2,
00269 1, 6,
00270 2, 1, 3,
00271 2, 1, 3,
00272 2, 1, 4,
00273 1, 5,
00274 1, 5,
00275
00276 1, 3,
00277 3, 2, 3, 2,
00278 2, 10, 3,
00279 1, 15,
00280 5, 1, 1, 1, 1, 6,
00281 2, 1, 7,
00282 2, 1, 4,
00283 2, 1, 4,
00284 1, 4
00285 };
00286
00288 const int unknown[] =
00289 { 10, 10,
00290
00291 1, 3,
00292 2, 2, 1,
00293 2, 2, 2,
00294 2, 2, 1,
00295 3, 1, 2, 1,
00296 2, 1, 1,
00297 3, 1, 4, 1,
00298 3, 1, 1, 2,
00299 2, 3, 1,
00300 1, 4,
00301
00302 1, 3,
00303 2, 2, 1,
00304 2, 1, 1,
00305 2, 1, 4,
00306 4, 1, 1, 1, 1,
00307 4, 2, 1, 1, 1,
00308 3, 2, 1, 1,
00309 2, 1, 2,
00310 2, 2, 3,
00311 1, 3
00312 };
00313
00315 const int pinwheel[] =
00316 { 6, 6,
00317
00318 2, 1, 2,
00319 1, 1,
00320 1, 2,
00321 1, 2,
00322 1, 1,
00323 2, 2, 1,
00324
00325 2, 2, 1,
00326 1, 1,
00327 1, 2,
00328 1, 2,
00329 1, 1,
00330 2, 1, 2
00331 };
00332
00334 const int difficult[] =
00335 { 15, 15,
00336
00337 1, 3,
00338 1, 2,
00339 1, 2,
00340 1, 1,
00341 1, 2,
00342 1, 3,
00343 1, 2,
00344 1, 4,
00345 1, 3,
00346 1, 4,
00347 2, 2, 1,
00348 2, 1, 1,
00349 2, 1, 1,
00350 2, 1, 1,
00351 1, 3,
00352
00353 1, 3,
00354 2, 1, 1,
00355 2, 1, 1,
00356 2, 1, 1,
00357 2, 1, 2,
00358 1, 5,
00359 1, 1,
00360 1, 2,
00361 1, 1,
00362 1, 1,
00363 2, 1, 2,
00364 2, 1, 2,
00365 2, 2, 1,
00366 2, 2, 2,
00367 1, 3
00368 };
00369
00371 const int non_unique[] =
00372 { 11, 15,
00373
00374 1, 5,
00375 3, 1, 2, 4,
00376 3, 2, 1, 3,
00377 4, 2, 2, 1, 1,
00378 4, 1, 1, 1, 1,
00379 2, 1, 5,
00380 5, 2, 1, 1, 3, 2,
00381 5, 2, 1, 1, 1, 1,
00382 3, 1, 4, 1,
00383 2, 1, 1,
00384 1, 1,
00385
00386 2, 2, 2,
00387 2, 2, 2,
00388 1, 4,
00389 2, 1, 1,
00390 2, 1, 1,
00391 4, 1, 1, 1, 1,
00392 2, 1, 1,
00393 2, 1, 4,
00394 3, 1, 1, 1,
00395 3, 1, 1, 4,
00396 2, 1, 3,
00397 2, 1, 2,
00398 1, 5,
00399 2, 2, 2,
00400 2, 3, 3
00401 };
00402
00408 const int dragonfly[] =
00409 { 20, 20,
00410
00411 4, 1, 1, 1, 2,
00412 5, 3, 1, 2, 1, 1,
00413 5, 1, 4, 2, 1, 1,
00414 4, 1, 3, 2, 4,
00415 4, 1, 4, 6, 1,
00416 3, 1, 11, 1,
00417 4, 5, 1, 6, 2,
00418 1, 14,
00419 2, 7, 2,
00420 2, 7, 2,
00421 3, 6, 1, 1,
00422 2, 9, 2,
00423 4, 3, 1, 1, 1,
00424 3, 3, 1, 3,
00425 3, 2, 1, 3,
00426 3, 2, 1, 5,
00427 3, 3, 2, 2,
00428 3, 3, 3, 2,
00429 3, 2, 3, 2,
00430 2, 2, 6,
00431
00432 2, 7, 1,
00433 3, 1, 1, 2,
00434 3, 2, 1, 2,
00435 3, 1, 2, 2,
00436 3, 4, 2, 3,
00437 3, 3, 1, 4,
00438 3, 3, 1, 3,
00439 3, 2, 1, 4,
00440 2, 2, 9,
00441 3, 2, 1, 5,
00442 2, 2, 7,
00443 1, 14,
00444 2, 8, 2,
00445 3, 6, 2, 2,
00446 4, 2, 8, 1, 3,
00447 4, 1, 5, 5, 2,
00448 5, 1, 3, 2, 4, 1,
00449 5, 3, 1, 2, 4, 1,
00450 5, 1, 1, 3, 1, 3,
00451 4, 2, 1, 1, 2
00452 };
00453
00455 const int castle[] = {
00456 60, 35,
00457
00458 7, 2,3,1,5,1,7,1,
00459 7, 2,4,2,3,2,3,5,
00460 8, 2,6,3,1,1,5,1,5,
00461 10, 2,4,2,1,1,1,4,1,1,2,
00462 7, 2,8,2,1,5,2,5,
00463 7, 3,1,6,2,5,1,5,
00464 9, 3,3,3,1,1,6,1,1,1,
00465 9, 3,2,2,2,2,8,1,1,3,
00466 7, 1,4,4,3,7,1,1,
00467 7, 1,2,2,2,3,7,9,
00468 8, 1,2,3,1,1,5,2,2,
00469 7, 2,2,3,1,1,6,1,
00470 6, 1,3,1,5,4,1,
00471 8, 1,3,1,1,6,1,3,1,
00472 8, 3,3,4,5,1,4,2,1,
00473 6, 2,3,3,9,7,1,
00474 8, 2,3,2,2,1,1,3,5,
00475 8, 4,2,1,1,1,1,2,3,
00476 7, 4,2,2,1,4,3,2,
00477 4, 4,3,16,2,
00478 5, 1,2,5,7,1,
00479 6, 4,3,2,2,7,1,
00480 5, 2,3,1,10,1,
00481 6, 2,4,2,1,4,1,
00482 5, 1,6,7,3,1,
00483 4, 3,11,3,1,
00484 5, 7,1,11,2,1,
00485 7, 2,2,2,2,2,2,2,
00486 7, 3,1,1,1,1,2,1,
00487 7, 2,2,2,2,1,1,1,
00488 7, 1,1,1,1,2,1,2,
00489 8, 2,2,2,2,1,1,1,1,
00490 5, 4,1,1,2,2,
00491 5, 5,2,17,2,1,
00492 6, 9,2,3,1,4,2,
00493 6, 9,4,2,1,1,1,
00494 5, 5,4,2,1,4,
00495 7, 11,1,2,1,4,1,2,
00496 5, 3,4,2,4,4,
00497 8, 2,1,4,1,2,1,5,2,
00498 5, 8,4,1,1,2,
00499 5, 1,1,3,2,3,
00500 6, 1,3,1,8,1,6,
00501 4, 2,1,7,14,
00502 7, 1,2,4,4,1,2,3,
00503 10, 1,1,4,2,1,1,1,1,1,4,
00504 6, 3,5,3,1,1,4,
00505 6, 2,4,2,2,1,2,
00506 5, 4,2,3,8,4,
00507 5, 4,15,2,2,4,
00508 6, 4,1,10,2,1,2,
00509 6, 2,12,6,1,2,4,
00510 7, 3,1,3,1,3,3,4,
00511 6, 3,1,2,3,4,1,
00512 7, 5,2,2,2,3,3,3,
00513 9, 1,2,2,2,2,4,1,1,3,
00514 7, 2,1,4,2,7,1,1,
00515 6, 5,2,2,3,6,3,
00516 7, 3,3,2,2,3,2,3,
00517 7, 4,1,2,1,1,2,1,
00518
00519
00520 4, 12,1,1,1,
00521 5, 8,6,3,1,3,
00522 6, 5,8,4,3,1,5,
00523 8, 7,3,4,1,3,5,1,7,
00524 13, 2,2,4,9,1,5,1,1,1,1,1,1,1,
00525 8, 4,5,10,2,1,8,7,1,
00526 7, 5,1,3,3,16,1,2,
00527 8, 8,5,1,2,4,9,1,3,
00528 12, 4,5,3,14,1,1,1,1,4,1,1,3,
00529 19, 3,3,2,2,2,4,1,1,1,1,1,1,1,1,3,1,1,3,2,
00530 11, 8,2,7,2,1,1,2,1,1,3,3,
00531 13, 1,5,9,12,2,1,1,3,1,1,2,2,1,
00532 17, 3,2,2,1,1,1,1,4,1,1,1,3,3,1,1,2,2,
00533 12, 5,2,2,2,2,1,5,2,1,1,2,5,
00534 12, 3,5,9,2,1,1,6,3,1,3,2,3,
00535 12, 1,4,1,1,1,4,1,5,5,3,3,3,
00536 10, 4,1,1,1,1,3,4,6,6,3,
00537 12, 3,1,3,1,1,3,3,1,1,4,6,1,
00538 11, 3,1,5,1,1,3,1,1,9,4,1,
00539 14, 2,1,1,7,1,4,1,1,1,1,1,1,3,5,
00540 11, 9,2,1,3,1,1,1,1,4,2,1,
00541 10, 1,14,1,1,2,2,2,10,1,2,
00542 10, 1,9,2,1,2,6,1,5,3,2,
00543 12, 1,9,9,1,2,2,3,1,1,4,3,1,
00544 10, 10,1,3,4,1,3,2,1,2,8,
00545 9, 9,1,3,5,1,1,1,2,7,
00546 12, 4,5,1,2,5,1,3,1,1,2,1,3,
00547 14, 1,1,1,1,2,6,2,3,2,1,1,2,3,1,
00548 11, 1,6,1,5,7,1,3,3,2,4,3,
00549 10, 1,2,1,2,9,1,5,2,6,2,
00550 8, 10,2,2,13,1,3,3,1,
00551 11, 2,2,1,6,2,3,3,2,2,2,1,
00552 12, 2,2,1,1,12,2,2,9,2,2,2,2,
00553 9, 5,1,2,4,1,5,11,2,2,
00554 3, 15,6,18,
00555 };
00556
00562 const int p200[] =
00563 { 25, 25,
00564
00565 4, 1,1,2,2,
00566 3, 5,5,7,
00567 4, 5,2,2,9,
00568 4, 3,2,3,9,
00569 5, 1,1,3,2,7,
00570 3, 3,1,5,
00571 5, 7,1,1,1,3,
00572 6, 1,2,1,1,2,1,
00573 3, 4,2,4,
00574 4, 1,2,2,2,
00575 3, 4,6,2,
00576 4, 1,2,2,1,
00577 4, 3,3,2,1,
00578 3, 4,1,15,
00579 6, 1,1,1,3,1,1,
00580 6, 2,1,1,2,2,3,
00581 4, 1,4,4,1,
00582 4, 1,4,3,2,
00583 4, 1,1,2,2,
00584 5, 7,2,3,1,1,
00585 5, 2,1,1,1,5,
00586 3, 1,2,5,
00587 4, 1,1,1,3,
00588 3, 4,2,1,
00589 1, 3,
00590
00591 3, 2,2,3,
00592 5, 4,1,1,1,4,
00593 5, 4,1,2,1,1,
00594 7, 4,1,1,1,1,1,1,
00595 6, 2,1,1,2,3,5,
00596 6, 1,1,1,1,2,1,
00597 5, 3,1,5,1,2,
00598 6, 3,2,2,1,2,2,
00599 7, 2,1,4,1,1,1,1,
00600 6, 2,2,1,2,1,2,
00601 6, 1,1,1,3,2,3,
00602 5, 1,1,2,7,3,
00603 5, 1,2,2,1,5,
00604 5, 3,2,2,1,2,
00605 4, 3,2,1,2,
00606 3, 5,1,2,
00607 4, 2,2,1,2,
00608 4, 4,2,1,2,
00609 4, 6,2,3,2,
00610 4, 7,4,3,2,
00611 3, 7,4,4,
00612 3, 7,1,4,
00613 3, 6,1,4,
00614 3, 4,2,2,
00615 2, 2,1
00616 };
00617
00618
00619 const int *specs[] = {heart, bear, crocodile, unknown,
00620 pinwheel, difficult, non_unique, dragonfly,
00621 castle, p200};
00622 const unsigned n_examples = sizeof(specs)/sizeof(int*);
00624
00625 }
00626
00627