this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Christian Schulte <schulte@gecode.org> 5 * 6 * Contributing authors: 7 * Mikael Lagerkvist <lagerkvist@gecode.org> 8 * 9 * Copyright: 10 * Christian Schulte, 2007 11 * Mikael Lagerkivst, 2007 12 * 13 * This file is part of Gecode, the generic constraint 14 * development environment: 15 * http://www.gecode.org 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining 18 * a copy of this software and associated documentation files (the 19 * "Software"), to deal in the Software without restriction, including 20 * without limitation the rights to use, copy, modify, merge, publish, 21 * distribute, sublicense, and/or sell copies of the Software, and to 22 * permit persons to whom the Software is furnished to do so, subject to 23 * the following conditions: 24 * 25 * The above copyright notice and this permission notice shall be 26 * included in all copies or substantial portions of the Software. 27 * 28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 35 * 36 */ 37 38#include <gecode/driver.hh> 39#include <gecode/int.hh> 40#include <gecode/minimodel.hh> 41 42using namespace Gecode; 43 44namespace { 45 46 /** \name %Kakuro specifications 47 * 48 * Each specification starts with two integers for width and height, 49 * followed by entries for vertical constraints, an integer -1 50 * (signalling the end of the vertical constraints), entries 51 * for the horizontal constraints, and, finally, an integer -1. 52 * 53 * Each entry consists of four integers: 54 * - the x-coordinate of the hint 55 * - the y-coordinate of the hint 56 * - the number of fields in the respective direction 57 * - the sum of the fields 58 * 59 * The example are taken from the website of Nikoli (from the free 60 * section). Thanks to Nikoli for their great puzzles and their 61 * brilliant website: www.nikoli.com. 62 * 63 * \relates Kakuro 64 */ 65 //@{ 66 67 // Easy, Author: Casty 68 const int k0[] = { 69 // Dimension w x h 70 12,10, 71 // Vertical constraints 72 2, 0, 5,16, 3, 0, 2, 4, 5, 0, 3, 6, 6, 0, 2, 4, 73 7, 0, 5,15, 10, 0, 3, 6, 11, 0, 3, 7, 1, 1, 3, 7, 74 9, 1, 5,16, 4, 2, 2, 5, 8, 2, 2, 3, 3, 3, 5,16, 75 6, 3, 3, 8, 5, 4, 5,15, 10, 4, 5,15, 4, 5, 2, 3, 76 8, 5, 2, 4, 11, 5, 3, 7, 1, 6, 3, 6, 2, 6, 3, 7, 77 7, 6, 3, 7, 6, 7, 2, 3, 9, 7, 2, 4, -1, 78 // Horizontal constraints 79 1, 1, 2, 7, 4, 1, 3, 9, 9, 1, 2, 4, 0, 2, 3, 7, 80 4, 2, 3, 7, 8, 2, 3, 6, 0, 3, 2, 3, 3, 3, 2, 4, 81 6, 3, 5,16, 0, 4, 4,10, 5, 4, 4,10, 1, 5, 2,10, 82 4, 5, 3, 6, 8, 5, 2, 5, 2, 6, 4,10, 7, 6, 4,12, 83 0, 7, 5,16, 6, 7, 2, 4, 9, 7, 2, 4, 0, 8, 3, 7, 84 4, 8, 3, 8, 8, 8, 3, 6, 0, 9, 2, 3, 4, 9, 3, 7, 85 8, 9, 2, 3, -1 86 }; 87 88 // Easy, Author: Ogawa Minori 89 const int k1[] = { 90 // Dimension w x h 91 12,10, 92 // Vertical constraints 93 1, 0, 2, 4, 2, 0, 5,15, 5, 0, 5,18, 6, 0, 2,12, 94 7, 0, 3, 8, 10, 0, 3,24, 11, 0, 3,23, 3, 1, 2, 7, 95 9, 1, 3,24, 4, 2, 5,16, 8, 2, 5,35, 1, 3, 2,12, 96 6, 3, 3,17, 7, 4, 5,34, 10, 4, 5,34, 11, 4, 2,16, 97 3, 5, 3, 6, 1, 6, 3, 7, 2, 6, 3, 6, 5, 6, 3,23, 98 9, 6, 2,10, 6, 7, 2,14, 11, 7, 2,10, -1, 99 // Horizontal constraints 100 0, 1, 2, 3, 4, 1, 3,15, 9, 1, 2,16, 0, 2, 3, 6, 101 4, 2, 3, 7, 8, 2, 3,24, 1, 3, 4,11, 6, 3, 5,34, 102 0, 4, 2,14, 3, 4, 3,23, 7, 4, 2,14, 0, 5, 2, 7, 103 3, 5, 5,15, 9, 5, 2,17, 2, 6, 2, 6, 5, 6, 3,23, 104 9, 6, 2,13, 0, 7, 5,16, 6, 7, 4,30, 0, 8, 3, 6, 105 4, 8, 3,23, 8, 8, 3, 7, 0, 9, 2, 4, 4, 9, 3,24, 106 9, 9, 2,17, -1 107 }; 108 109 // Easy, Author: SAKAMOTO, Nobuyuki 110 const int k2[] = { 111 // Dimension w x h 112 12,10, 113 // Vertical constraints 114 2, 0, 5,15, 3, 0, 2, 3, 7, 0, 3, 7, 8, 0, 4,23, 115 9, 0, 2,12, 10, 0, 3,20, 11, 0, 3, 9, 4, 1, 3, 7, 116 5, 1, 4,10, 1, 2, 3, 6, 6, 2, 5,15, 9, 3, 2,16, 117 3, 4, 2, 3, 7, 4, 4,13, 10, 4, 5,35, 11, 4, 3,23, 118 4, 5, 4,11, 8, 5, 3,23, 1, 6, 3,23, 2, 6, 3,14, 119 5, 6, 3,11, 3, 7, 2,13, 9, 7, 2,17, -1, 120 // Horizontal constraints 121 1, 1, 2, 4, 6, 1, 5,15, 1, 2, 4,11, 6, 2, 5,34, 122 0, 3, 2, 3, 3, 3, 5,15, 9, 3, 2,10, 0, 4, 2, 4, 123 3, 4, 3, 6, 7, 4, 2,17, 0, 5, 3, 7, 4, 5, 3, 8, 124 8, 5, 3,18, 2, 6, 2, 3, 5, 6, 3,11, 9, 6, 2,16, 125 0, 7, 2,16, 3, 7, 5,16, 9, 7, 2,17, 0, 8, 5,16, 126 6, 8, 4,30, 0, 9, 5,35, 8, 9, 2,17, -1 127 }; 128 129 // Easy, Author: country mushroom 130 const int k3[] = { 131 // Dimension w x h 132 12,10, 133 // Vertical constraints 134 3, 0, 3, 7, 4, 0, 6,21, 7, 0, 4,29, 8, 0, 2,17, 135 10, 0, 4,29, 11, 0, 3,23, 2, 1, 3, 6, 6, 1, 2,16, 136 9, 1, 4,14, 1, 2, 2, 4, 5, 2, 2, 3, 8, 3, 6,22, 137 3, 4, 4,10, 2, 5, 4,11, 5, 5, 4,10, 7, 5, 2,10, 138 10, 5, 3,24, 11, 5, 2,16, 1, 6, 3, 7, 6, 6, 2, 9, 139 9, 6, 3,23, 4, 7, 2, 4, -1, 140 // Horizontal constraints 141 2, 1, 2, 4, 6, 1, 2,17, 9, 1, 2,16, 1, 2, 3, 6, 142 5, 2, 6,39, 0, 3, 7,28, 8, 3, 3,24, 0, 4, 2, 3, 143 3, 4, 2, 3, 6, 4, 4,20, 2, 5, 2, 9, 7, 5, 2, 4, 144 1, 6, 4,10, 6, 6, 2, 3, 9, 6, 2,16, 0, 7, 3, 6, 145 4, 7, 7,42, 0, 8, 6,21, 7, 8, 3,21, 0, 9, 2, 4, 146 3, 9, 2, 3, 7, 9, 2,16, -1 147 }; 148 149 // Medium, Author: Komieda 150 const int k4[] = { 151 // Dimension w x h 152 20,12, 153 // Vertical constraints 154 3, 0, 3,21, 4, 0, 2, 4, 5, 0, 4,11, 8, 0, 2, 8, 155 9, 0, 3, 7, 11, 0, 2, 3, 12, 0, 3, 6, 15, 0, 6,39, 156 16, 0, 2, 3, 17, 0, 3,23, 2, 1, 5,15, 6, 1, 4,10, 157 10, 1, 4,11, 14, 1, 4,11, 18, 1, 3, 6, 1, 2, 3,24, 158 7, 2, 4,14, 13, 2, 2,10, 19, 2, 2,16, 4, 3, 5,18, 159 8, 3, 4,10, 11, 3, 4,12, 16, 3, 5,33, 3, 4, 3,23, 160 9, 4, 4,29, 12, 4, 4,30, 17, 4, 3,18, 5, 5, 6,38, 161 13, 5, 4,29, 18, 5, 5,15, 6, 6, 4,25, 10, 6, 4,12, 162 14, 6, 4,28, 19, 6, 3,21, 1, 7, 2, 4, 2, 7, 3, 7, 163 7, 7, 2, 7, 15, 7, 4,11, 3, 8, 3,19, 8, 8, 3,24, 164 11, 8, 3, 7, 17, 8, 3, 6, 4, 9, 2,16, 9, 9, 2,16, 165 12, 9, 2,17, 16, 9, 2, 5, -1, 166 // Horizontal constraints 167 2, 1, 3, 7, 7, 1, 2, 4, 10, 1, 2, 4, 14, 1, 3,19, 168 1, 2, 5,18, 7, 2, 5,15, 13, 2, 5,16, 0, 3, 3,21, 169 4, 3, 3, 6, 8, 3, 2, 3, 11, 3, 4,11, 16, 3, 3,20, 170 0, 4, 2,14, 3, 4, 5,15, 9, 4, 2, 3, 12, 4, 4,29, 171 17, 4, 2, 8, 0, 5, 4,27, 5, 5, 7,42, 13, 5, 4,12, 172 1, 6, 4,12, 6, 6, 3, 8, 10, 6, 3,20, 14, 6, 4,29, 173 2, 7, 4,28, 7, 7, 7,28, 15, 7, 4,28, 0, 8, 2, 3, 174 3, 8, 4,11, 8, 8, 2,10, 11, 8, 5,35, 17, 8, 2,10, 175 0, 9, 3, 6, 4, 9, 4,30, 9, 9, 2, 3, 12, 9, 3,19, 176 16, 9, 3, 7, 1,10, 5,34, 7,10, 5,34, 13,10, 5,17, 177 2,11, 3,23, 7,11, 2,17, 10,11, 2,10, 14,11, 3, 6, 178 -1 179 }; 180 181 // Medium, Author: crimson 182 const int k5[] = { 183 // Dimension w x h 184 20,12, 185 // Vertical constraints 186 1, 0, 2, 3, 2, 0, 5,33, 4, 0, 2, 8, 5, 0, 4,14, 187 7, 0, 5,15, 8, 0, 3,19, 9, 0, 2,12, 11, 0, 4,11, 188 12, 0, 2, 4, 13, 0, 5,16, 15, 0, 4,11, 16, 0, 2,17, 189 18, 0, 5,34, 19, 0, 2,17, 3, 1, 2, 3, 10, 1, 9,45, 190 17, 1, 2,16, 6, 2, 3,20, 14, 2, 3,12, 1, 3, 2,13, 191 4, 3, 5,33, 9, 3, 3,20, 16, 3, 5,21, 19, 3, 2, 8, 192 3, 4, 3,11, 8, 4, 3,11, 12, 4, 3, 7, 17, 4, 3, 8, 193 11, 5, 3,23, 1, 6, 2,11, 2, 6, 5,15, 6, 6, 3,23, 194 7, 6, 5,27, 13, 6, 5,30, 14, 6, 3, 7, 18, 6, 5,15, 195 19, 6, 2, 3, 5, 7, 4,26, 9, 7, 4,27, 15, 7, 4,27, 196 3, 8, 2, 7, 12, 8, 3,24, 17, 8, 2,17, 1, 9, 2, 5, 197 4, 9, 2, 9, 8, 9, 2, 3, 11, 9, 2,16, 16, 9, 2,16, 198 19, 9, 2,10, -1, 199 // Horizontal constraints 200 0, 1, 2, 4, 3, 1, 2, 7, 6, 1, 3, 7, 10, 1, 3, 7, 201 14, 1, 2,11, 17, 1, 2,16, 0, 2, 5,16, 6, 2, 7,42, 202 14, 2, 5,35, 1, 3, 2,10, 4, 3, 4,15, 9, 3, 2, 6, 203 12, 3, 3, 7, 16, 3, 2,13, 0, 4, 2,17, 3, 4, 4,29, 204 8, 4, 3,19, 12, 4, 4,11, 17, 4, 2, 9, 0, 5, 4,29, 205 5, 5, 5,33, 11, 5, 3, 6, 15, 5, 4,29, 2, 6, 2, 4, 206 7, 6, 5,16, 15, 6, 2, 4, 0, 7, 4,12, 5, 7, 3,10, 207 9, 7, 5,18, 15, 7, 4,12, 0, 8, 2,13, 3, 8, 4,29, 208 8, 8, 3,24, 12, 8, 4,23, 17, 8, 2, 5, 1, 9, 2, 6, 209 4, 9, 3,24, 8, 9, 2, 4, 11, 9, 4,28, 16, 9, 2,11, 210 0,10, 5,15, 6,10, 7,41, 14,10, 5,34, 0,11, 2, 3, 211 3,11, 2,17, 6,11, 3,14, 10,11, 3,23, 14,11, 2,11, 212 17,11, 2, 4, -1 213 }; 214 215 // Hard, Author: Yuichi Saito 216 const int k6[] = { 217 // Dimension w x h 218 20,12, 219 // Vertical constraints 220 1, 0, 2, 6, 2, 0, 2,16, 4, 0, 3,10, 5, 0, 2,12, 221 9, 0, 7,28, 10, 0, 2,12, 11, 0, 3,24, 15, 0, 3,10, 222 16, 0, 2,17, 17, 0, 6,22, 3, 1, 3,18, 6, 1, 4,10, 223 8, 1, 2, 8, 12, 1, 2,10, 13, 1, 3,18, 18, 1, 3,12, 224 7, 2, 4,11, 14, 2, 3, 7, 19, 2, 2, 7, 1, 3, 2, 8, 225 2, 3, 3, 7, 5, 3, 4,25, 10, 3, 2, 4, 16, 3, 4,15, 226 4, 4, 4,11, 11, 4, 7,42, 12, 4, 2,17, 15, 4, 4,26, 227 3, 5, 6,22, 8, 5, 2,16, 13, 5, 4,30, 18, 5, 3,24, 228 6, 6, 3, 7, 10, 6, 2, 4, 14, 6, 4,29, 19, 6, 2,14, 229 1, 7, 2,16, 2, 7, 3,11, 7, 7, 3,24, 17, 7, 3,21, 230 5, 8, 3,23, 8, 8, 2,12, 9, 8, 3,20, 12, 8, 2,17, 231 16, 8, 3, 6, 4, 9, 2, 9, 10, 9, 2,16, 15, 9, 2, 9, 232 18, 9, 2, 3, 19, 9, 2,12, -1, 233 // Horizontal constraints 234 0, 1, 2,10, 3, 1, 2, 5, 8, 1, 3,23, 14, 1, 3,11, 235 0, 2, 6,38, 7, 2, 6,39, 14, 2, 4,30, 2, 3, 2,10, 236 5, 3, 4,11, 10, 3, 5,18, 16, 3, 3, 7, 0, 4, 3, 7, 237 4, 4, 3, 7, 8, 4, 2, 6, 12, 4, 2, 8, 15, 4, 4,11, 238 0, 5, 2, 8, 3, 5, 4,14, 8, 5, 4,24, 13, 5, 4,10, 239 1, 6, 4,13, 6, 6, 3,14, 10, 6, 3,19, 14, 6, 4,29, 240 2, 7, 4,15, 7, 7, 4,14, 12, 7, 4,29, 17, 7, 2,16, 241 0, 8, 4,29, 5, 8, 2,13, 9, 8, 2, 8, 12, 8, 3,23, 242 16, 8, 3,22, 0, 9, 3,10, 4, 9, 5,32, 10, 9, 4,29, 243 15, 9, 2,10, 1,10, 4,14, 6,10, 6,39, 13,10, 6,22, 244 2,11, 3,21, 8,11, 3,23, 14,11, 2, 6, 17,11, 2,11, 245 -1 246 }; 247 248 // Hard, Author: mimic 249 const int k7[] = { 250 // Dimension w x h 251 22,14, 252 // Vertical constraints 253 1, 0, 3,23, 2, 0, 4,29, 3, 0, 2,16, 7, 0, 2, 7, 254 8, 0, 2,10, 9, 0, 5,30, 13, 0, 7,41, 14, 0, 2,16, 255 15, 0, 4,29, 17, 0, 2, 3, 18, 0, 6,21, 20, 0, 3, 7, 256 21, 0, 2, 4, 4, 1, 5,35, 6, 1, 2, 4, 10, 1, 2,17, 257 12, 1, 3,24, 19, 1, 9,45, 5, 2, 3,23, 11, 2, 9,45, 258 16, 2, 4,21, 3, 3, 9,45, 7, 3, 5,15, 8, 3, 4,10, 259 14, 3, 2,10, 17, 3, 2, 3, 6, 4, 2, 4, 10, 4, 4,30, 260 20, 4, 4,11, 2, 5, 4,13, 12, 5, 4,30, 15, 5, 5,35, 261 21, 5, 2, 4, 1, 6, 2, 4, 9, 6, 7,41, 14, 6, 4,29, 262 4, 7, 6,38, 6, 7, 4,11, 16, 7, 2,16, 18, 7, 5,15, 263 5, 8, 2, 9, 8, 8, 2,17, 13, 8, 5,16, 17, 8, 3, 7, 264 7, 9, 4,20, 10, 9, 3,23, 20, 9, 4,12, 2,10, 3,23, 265 12,10, 2, 6, 16,10, 2, 4, 21,10, 3, 9, 1,11, 2,16, 266 5,11, 2,16, 8,11, 2,16, 14,11, 2, 6, 15,11, 2, 4, 267 19,11, 2, 4, -1, 268 // Horizontal constraints 269 0, 1, 3,23, 6, 1, 3, 8, 12, 1, 3,23, 16, 1, 2, 4, 270 19, 1, 2, 4, 0, 2, 4,30, 5, 2, 5,31, 11, 2, 4,29, 271 16, 2, 5,15, 0, 3, 2,16, 3, 3, 3,19, 8, 3, 5,32, 272 14, 3, 2,17, 17, 3, 3, 8, 1, 4, 4,29, 6, 4, 3, 9, 273 10, 4, 9,45, 2, 5, 9,45, 12, 5, 2,17, 15, 5, 5,16, 274 1, 6, 3,24, 5, 6, 3, 6, 9, 6, 4,30, 14, 6, 2,16, 275 17, 6, 4,11, 0, 7, 3, 7, 6, 7, 9,45, 18, 7, 3, 7, 276 0, 8, 4,11, 5, 8, 2, 4, 8, 8, 4,29, 13, 8, 3,23, 277 17, 8, 3, 7, 1, 9, 5,16, 7, 9, 2,17, 10, 9, 9,45, 278 2,10, 9,45, 12,10, 3,23, 16,10, 4,14, 1,11, 3,24, 279 5,11, 2, 6, 8,11, 5,16, 15,11, 3, 7, 19,11, 2, 8, 280 0,12, 5,35, 6,12, 4,30, 11,12, 5,15, 17,12, 4,11, 281 0,13, 2,17, 3,13, 2,16, 6,13, 3,24, 12,13, 3, 6, 282 18,13, 3, 7, -1 283 }; 284 285 // Hard, Author: OX 286 const int k8[] = { 287 // Dimension w x h 288 22,14, 289 // Vertical constraints 290 1, 0, 2, 4, 2, 0, 5,15, 5, 0, 5,16, 6, 0, 2,10, 291 7, 0, 3,18, 8, 0, 4,29, 10, 0, 5,16, 11, 0, 2, 6, 292 13, 0, 2, 8, 14, 0, 5,16, 15, 0, 6,38, 18, 0, 5,15, 293 19, 0, 2, 8, 20, 0, 3, 7, 21, 0, 3, 8, 3, 1, 9,45, 294 16, 1, 2, 4, 4, 2, 2, 3, 9, 2, 8,39, 17, 2, 2, 3, 295 1, 3, 2, 5, 6, 3, 6,22, 11, 3, 3,22, 13, 3, 8,38, 296 19, 3, 9,45, 7, 4, 2, 4, 12, 4, 3,24, 16, 4, 6,38, 297 20, 4, 3,24, 4, 5, 2,16, 8, 5, 2,14, 17, 5, 2,16, 298 21, 5, 2,11, 1, 6, 2, 4, 2, 6, 3, 8, 5, 6, 2, 7, 299 10, 6, 3,18, 14, 6, 2,16, 18, 6, 2,16, 7, 7, 6,22, 300 11, 7, 3, 7, 15, 7, 2,15, 4, 8, 5,35, 8, 8, 5,34, 301 12, 8, 5,34, 17, 8, 5,34, 20, 8, 5,34, 21, 8, 2, 3, 302 5, 9, 2,16, 14, 9, 4,12, 18, 9, 2, 7, 1,10, 3,23, 303 2,10, 3,21, 6,10, 2, 9, 15,10, 3,20, 3,11, 2,17, 304 9,11, 2, 4, 11,11, 2, 4, 16,11, 2,10, 21,11, 2,16, 305 -1, 306 // Horizontal constraints 307 0, 1, 2, 6, 4, 1, 4,30, 9, 1, 2, 6, 12, 1, 3,10, 308 17, 1, 4,12, 0, 2, 3, 8, 4, 2, 4,11, 9, 2, 2, 4, 309 12, 2, 4,20, 17, 2, 4,11, 1, 3, 4,12, 6, 3, 4,28, 310 13, 3, 5,15, 19, 3, 2, 5, 0, 4, 6,22, 7, 4, 4,28, 311 12, 4, 3, 8, 16, 4, 3, 6, 0, 5, 3, 7, 4, 5, 3, 7, 312 8, 5, 8,40, 17, 5, 3,22, 2, 6, 2, 8, 5, 6, 4,12, 313 10, 6, 3,23, 14, 6, 3,22, 18, 6, 3,22, 0, 7, 6,38, 314 7, 7, 3,24, 11, 7, 3,23, 15, 7, 6,39, 0, 8, 3, 6, 315 4, 8, 3, 6, 8, 8, 3, 6, 12, 8, 4,29, 17, 8, 2,14, 316 1, 9, 3,18, 5, 9, 8,36, 14, 9, 3,22, 18, 9, 3,10, 317 2,10, 3,22, 6,10, 3,24, 10,10, 4,10, 15,10, 6,21, 318 0,11, 2,16, 3,11, 5,34, 11,11, 4,29, 16,11, 4,30, 319 0,12, 4,29, 5,12, 4,12, 10,12, 2,10, 13,12, 4,10, 320 18,12, 3,23, 0,13, 4,28, 6,13, 3, 7, 10,13, 2,11, 321 13,13, 4,28, 19,13, 2,13, -1 322 }; 323 324 // Hard, Author: TAKEI Daisuke 325 const int k9[] = { 326 // Dimension w x h 327 22,14, 328 // Vertical constraints 329 1, 0, 4,10, 2, 0, 4,24, 3, 0, 3, 7, 7, 0, 3, 8, 330 8, 0, 2,17, 9, 0, 3,13, 13, 0, 3,22, 14, 0, 2,12, 331 15, 0, 3,24, 19, 0, 3,19, 20, 0, 4,28, 21, 0, 4,14, 332 4, 1, 5,16, 6, 1, 5,17, 10, 1, 5,32, 12, 1, 5,34, 333 16, 1, 5,35, 18, 1, 5,31, 5, 2, 3, 9, 11, 2, 3, 7, 334 17, 2, 3, 7, 3, 4, 5,27, 7, 4, 5,16, 9, 4, 5,20, 335 13, 4, 5,30, 15, 4, 5,30, 19, 4, 5,26, 1, 5, 3,12, 336 2, 5, 3,20, 8, 5, 3,22, 14, 5, 3, 9, 20, 5, 3,10, 337 21, 5, 3,20, 4, 7, 5,31, 6, 7, 5,16, 10, 7, 5,17, 338 12, 7, 5,32, 16, 7, 5,19, 18, 7, 5,34, 5, 8, 3, 8, 339 11, 8, 3,24, 17, 8, 3,24, 1, 9, 4,10, 2, 9, 4,15, 340 20, 9, 4,30, 21, 9, 4,12, 3,10, 3,20, 7,10, 3, 6, 341 9,10, 3, 9, 13,10, 3, 6, 15,10, 3, 7, 19,10, 3,24, 342 8,11, 2, 8, 14,11, 2, 7, -1, 343 // Horizontal constraints 344 0, 1, 3, 7, 6, 1, 3,12, 12, 1, 3,23, 18, 1, 3,23, 345 0, 2, 4,11, 5, 2, 5,19, 11, 2, 5,33, 17, 2, 4,28, 346 0, 3, 7,28, 8, 3, 5,34, 14, 3, 7,29, 0, 4, 2,12, 347 3, 4, 3, 7, 9, 4, 3,16, 15, 4, 3,10, 19, 4, 2,10, 348 2, 5, 5,18, 8, 5, 5,20, 14, 5, 5,29, 0, 6, 4,24, 349 5, 6, 5,35, 11, 6, 5,23, 17, 6, 4,26, 0, 7, 3,23, 350 6, 7, 3, 9, 12, 7, 3,10, 18, 7, 3,23, 0, 8, 4,15, 351 5, 8, 5,19, 11, 8, 5,33, 17, 8, 4,10, 2, 9, 5,19, 352 8, 9, 5,35, 14, 9, 5,31, 0,10, 2, 4, 3,10, 3,10, 353 9,10, 3,18, 15,10, 3,24, 19,10, 2,12, 0,11, 7,41, 354 8,11, 5,23, 14,11, 7,36, 0,12, 4,14, 5,12, 5,17, 355 11,12, 5,15, 17,12, 4,26, 0,13, 3, 7, 6,13, 3, 7, 356 12,13, 3, 6, 18,13, 3,23, -1 357 }; 358 //@} 359 360 /// Array of all examples 361 const int* examples[] = { 362 &k0[0], &k1[0], &k2[0], &k3[0], &k4[0], 363 &k5[0], &k6[0], &k7[0], &k8[0], &k9[0] 364 }; 365 /// Number of examples 366 const unsigned int n_examples = sizeof(examples)/sizeof(const int*); 367 368 369 /** \brief Class for solutions of a distinct-linear constraint problem. 370 * \relates Kakuro 371 */ 372 class DistinctLinear : public Space { 373 protected: 374 /// The variables 375 IntVarArray x; 376 public: 377 /// The actual problem 378 DistinctLinear(int n, int s) : x(*this,n,1,9) { 379 distinct(*this, x); 380 linear(*this, x, IRT_EQ, s); 381 branch(*this, x, INT_VAR_NONE(), INT_VAL_SPLIT_MIN()); 382 } 383 /// Constructor for cloning \a s 384 DistinctLinear(DistinctLinear& s) : Space(s) { 385 x.update(*this, s.x); 386 } 387 /// Perform copying during cloning 388 virtual Space* 389 copy(void) { 390 return new DistinctLinear(*this); 391 } 392 /// Return a solution 393 IntArgs solution(void) const { 394 IntArgs s(x.size()); 395 for (int i=0; i<x.size(); i++) 396 s[i]=x[i].val(); 397 return s; 398 } 399 }; 400 401 /** \brief Generate tuple set for \a n distinct variables with sum \a c 402 * \relates Kakuro 403 */ 404 TupleSet generate(int n, int c) { 405 // Setup search engine that enumerates all solutions 406 DistinctLinear* e = new DistinctLinear(n,c); 407 DFS<DistinctLinear> d(e); 408 delete e; 409 TupleSet ts(n); 410 while (DistinctLinear* s = d.next()) { 411 ts.add(s->solution()); delete s; 412 } 413 ts.finalize(); 414 return ts; 415 } 416 417 /** \brief Class to remember already computed specifications 418 * \relates Kakuro 419 */ 420 class Cache { 421 private: 422 /// Cache entry 423 class Entry { 424 public: 425 int n; ///< Number of variables 426 int c; ///< Sum of variables 427 TupleSet ts; ///< The previously computed tuple set 428 Entry* next; ///< The next cache entry 429 }; 430 Entry* cache; ///< Where all entries start 431 public: 432 /// Initialize cache as empty 433 Cache(void) : cache(nullptr) {} 434 /// Return possibly cached Data for \a n distinct variables with sum \a c 435 TupleSet get(int n, int c) { 436 for (Entry* e = cache; e != nullptr; e = e->next) 437 if ((e->n == n) && (e->c == c)) 438 return e->ts; 439 { 440 Entry* e = new Entry; 441 e->n = n; 442 e->c = c; 443 e->ts = generate(n,c); 444 e->next = cache; 445 cache = e; 446 } 447 return cache->ts; 448 } 449 /// Delete cache entries 450 ~Cache(void) { 451 Entry* e = cache; 452 while (e != nullptr) { 453 Entry* d = e; 454 e = e->next; 455 delete d; 456 } 457 } 458 }; 459 460} 461 462 463/** 464 * \brief %Example: %Kakuro 465 * 466 * Another puzzle in the style of Sudoku. 467 * 468 * Note that "Modeling and Programming with Gecode" uses this example 469 * as a case study. 470 * 471 * \ingroup Example 472 */ 473class Kakuro : public Script { 474protected: 475 const int w; ///< Width of board 476 const int h; ///< Height of board 477 IntVarArray f; ///< Variables for fields of board 478public: 479 /// Model variants 480 enum { 481 MODEL_DECOMPOSE,///< Decompose constraints 482 MODEL_COMBINE, ///< Combine distinct and linear constraint 483 }; 484 /// Init the variable \a x if necessary 485 IntVar init(IntVar& x) { 486 if (x.min() == 0) 487 x = IntVar(*this,1,9); 488 return x; 489 } 490 /// Post a distinct-linear constraint on variables \a x with sum \a c 491 void distinctlinear(Cache& dc, const IntVarArgs& x, int c, 492 const SizeOptions& opt) { 493 int n=x.size(); 494 if (opt.model() == MODEL_DECOMPOSE) { 495 if (n < 8) 496 linear(*this, x, IRT_EQ, c, opt.ipl()); 497 else if (n == 8) 498 rel(*this, x, IRT_NQ, 9*(9+1)/2 - c); 499 distinct(*this, x, opt.ipl()); 500 } else { 501 switch (n) { 502 case 0: 503 return; 504 case 1: 505 rel(*this, x[0], IRT_EQ, c); 506 return; 507 case 8: 508 // Prune the single missing digit 509 rel(*this, x, IRT_NQ, 9*(9+1)/2 - c); 510 break; 511 case 9: 512 break; 513 default: 514 if (c == n*(n+1)/2) { 515 // sum has unique decomposition: 1 + ... + n 516 rel(*this, x, IRT_LQ, n); 517 } else if (c == n*(n+1)/2 + 1) { 518 // sum has unique decomposition: 1 + ... + n-1 + n+1 519 rel(*this, x, IRT_LQ, n+1); 520 rel(*this, x, IRT_NQ, n); 521 } else if (c == 9*(9+1)/2 - (9-n)*(9-n+1)/2) { 522 // sum has unique decomposition: (9-n+1) + (9-n+2) + ... + 9 523 rel(*this, x, IRT_GQ, 9-n+1); 524 } else if (c == 9*(9+1)/2 - (9-n)*(9-n+1)/2 + 1) { 525 // sum has unique decomposition: (9-n) + (9-n+2) + ... + 9 526 rel(*this, x, IRT_GQ, 9-n); 527 rel(*this, x, IRT_NQ, 9-n+1); 528 } else { 529 extensional(*this, x, dc.get(n,c)); 530 return; 531 } 532 } 533 distinct(*this, x, opt.ipl()); 534 } 535 } 536 /// The actual problem 537 Kakuro(const SizeOptions& opt) 538 : Script(opt), 539 w(examples[opt.size()][0]), h(examples[opt.size()][1]), 540 f(*this,w*h) { 541 IntVar black(*this,0,0); 542 // Initialize all fields as black (unused). Only if a field 543 // is actually used in a constraint, create a fresh variable 544 // for it (done via init). 545 for (int i=w*h; i--; ) 546 f[i] = black; 547 548 // Cache of already computed tuple sets 549 Cache cache; 550 551 // Matrix for accessing board fields 552 Matrix<IntVarArray> b(f,w,h); 553 // Access to hints 554 const int* k = &examples[opt.size()][2]; 555 556 // Process vertical hints 557 while (*k >= 0) { 558 int x=*k++; int y=*k++; int n=*k++; int s=*k++; 559 IntVarArgs col(n); 560 for (int i=n; i--; ) 561 col[i]=init(b(x,y+i+1)); 562 distinctlinear(cache,col,s,opt); 563 } 564 k++; 565 566 // Process horizontal hints 567 while (*k >= 0) { 568 int x=*k++; int y=*k++; int n=*k++; int s=*k++; 569 IntVarArgs row(n); 570 for (int i=n; i--; ) 571 row[i]=init(b(x+i+1,y)); 572 distinctlinear(cache,row,s,opt); 573 } 574 branch(*this, f, INT_VAR_AFC_SIZE_MAX(opt.decay()), INT_VAL_SPLIT_MIN()); 575 } 576 /// Constructor for cloning \a s 577 Kakuro(Kakuro& s) : Script(s), w(s.w), h(s.h) { 578 f.update(*this, s.f); 579 } 580 /// Perform copying during cloning 581 virtual Space* 582 copy(void) { 583 return new Kakuro(*this); 584 } 585 /// Print solution 586 virtual void 587 print(std::ostream& os) const { 588 Matrix<IntVarArray> b(f,w,h); 589 for (int y=0; y<h; y++) { 590 os << '\t'; 591 for (int x=0; x<w; x++) 592 if (b(x,y).min() == 0) 593 os << ". "; 594 else 595 os << b(x,y) << ' '; 596 os << std::endl; 597 } 598 } 599}; 600 601 602/** \brief Main-function 603 * \relates Kakuro 604 */ 605int 606main(int argc, char* argv[]) { 607 SizeOptions opt("Kakuro"); 608 opt.model(Kakuro::MODEL_COMBINE); 609 opt.model(Kakuro::MODEL_DECOMPOSE, 610 "decompose","decompose distinct and linear constraints"); 611 opt.model(Kakuro::MODEL_COMBINE, 612 "combine","combine distinct and linear constraints"); 613 opt.ipl(IPL_DOM); 614 opt.parse(argc,argv); 615 if (opt.size() >= n_examples) { 616 std::cerr << "Error: size must be between 0 and " 617 << n_examples-1 << std::endl; 618 return 1; 619 } 620 Script::run<Kakuro,DFS,SizeOptions>(opt); 621 return 0; 622} 623 624// STATISTICS: example-any