| 1 | program insane(input, output); |
| 2 | label |
| 3 | 1; |
| 4 | type |
| 5 | alfa = packed array[1..10] of char; |
| 6 | face = (front, back, top, bottom, left, right); |
| 7 | pair = (one2, three4, five6); |
| 8 | color = (red, blue, green, white); |
| 9 | blockno = 1..4; |
| 10 | var |
| 11 | nosolutions: Boolean; |
| 12 | index, halfindex: integer; |
| 13 | pointr: integer; |
| 14 | data: array[blockno, face] of alfa; |
| 15 | sum: array[blockno, pair, color] of integer; |
| 16 | halfsolution: array[blockno, 1..30] of pair; |
| 17 | |
| 18 | function word(alf: alfa): color; |
| 19 | begin |
| 20 | if alf = 'red' then |
| 21 | word := red else |
| 22 | if alf = 'blue' then |
| 23 | word := blue else |
| 24 | if alf = 'green' then |
| 25 | word := green else |
| 26 | word := white; |
| 27 | end; |
| 28 | |
| 29 | procedure readin; |
| 30 | var |
| 31 | hue: alfa; |
| 32 | ch: char; |
| 33 | cube: blockno; |
| 34 | position: face; |
| 35 | |
| 36 | procedure tone; |
| 37 | begin |
| 38 | case ch of |
| 39 | 'r': hue := 'red'; |
| 40 | 'w': hue := 'white'; |
| 41 | 'g': hue := 'green'; |
| 42 | 'b': hue := 'blue'; |
| 43 | end; |
| 44 | end; |
| 45 | |
| 46 | begin |
| 47 | for cube := 1 to 4 do |
| 48 | begin |
| 49 | for position := front to right do |
| 50 | begin |
| 51 | read(ch); |
| 52 | tone; |
| 53 | data[cube, position] := hue; |
| 54 | end; |
| 55 | readln; |
| 56 | end; |
| 57 | end; |
| 58 | |
| 59 | procedure sumcolors; |
| 60 | var |
| 61 | cube: blockno; |
| 62 | side: face; |
| 63 | function facepair(aface: face): pair; |
| 64 | begin |
| 65 | case aface of |
| 66 | front, back: facepair := one2; |
| 67 | top, bottom: facepair := three4; |
| 68 | left, right: facepair := five6 |
| 69 | end; |
| 70 | end; |
| 71 | |
| 72 | procedure initializesum; |
| 73 | var |
| 74 | cube: blockno; |
| 75 | side: face; |
| 76 | technicolor: color; |
| 77 | begin |
| 78 | for cube := 1 to 4 do |
| 79 | for side := front to right do |
| 80 | for technicolor := red to white do |
| 81 | sum[cube, facepair(side), technicolor] := 0; |
| 82 | end; |
| 83 | |
| 84 | begin |
| 85 | initializesum; |
| 86 | for cube := 1 to 4 do |
| 87 | for side := front to right do |
| 88 | sum[cube, facepair(side), word(data[cube,side])] := |
| 89 | sum[cube, facepair(side), word(data[cube,side])] + 1; |
| 90 | end; |
| 91 | |
| 92 | procedure find2222; |
| 93 | var |
| 94 | subtotals: array[red..white] of integer; |
| 95 | pair1, pair2, pair3, pair4: pair; |
| 96 | |
| 97 | function two222(pair1, pair2, pair3, pair4: pair): Boolean; |
| 98 | var |
| 99 | hue: color; |
| 100 | begin |
| 101 | for hue := red to white do |
| 102 | subtotals[hue] := |
| 103 | sum[1, pair1, hue]+ |
| 104 | sum[2, pair2, hue]+ |
| 105 | sum[3, pair3, hue]+ |
| 106 | sum[4, pair4, hue]; |
| 107 | if (subtotals[red]=2) and |
| 108 | (subtotals[blue]=2) and |
| 109 | (subtotals[green]=2) and |
| 110 | (subtotals[white]=2) then |
| 111 | two222 := true else |
| 112 | two222 := false; |
| 113 | end; |
| 114 | |
| 115 | procedure listsolution; |
| 116 | begin |
| 117 | halfsolution[1, halfindex] := pair1; |
| 118 | halfsolution[2, halfindex] := pair2; |
| 119 | halfsolution[3, halfindex] := pair3; |
| 120 | halfsolution[4, halfindex] := pair4; |
| 121 | halfindex := halfindex + 1; |
| 122 | end; |
| 123 | |
| 124 | begin |
| 125 | halfindex := 1; |
| 126 | for pair1 := one2 to five6 do |
| 127 | for pair2 := one2 to five6 do |
| 128 | for pair3 := one2 to five6 do |
| 129 | for pair4 := one2 to five6 do |
| 130 | if two222(pair1, pair2, pair3, pair4) then |
| 131 | listsolution; |
| 132 | if halfindex <= 2 then |
| 133 | begin |
| 134 | nosolutions := true; |
| 135 | goto 1; |
| 136 | end; |
| 137 | end; |
| 138 | |
| 139 | procedure simultaneous; |
| 140 | var |
| 141 | done: Boolean; |
| 142 | begin |
| 143 | nosolutions := false; |
| 144 | pointr := 0; |
| 145 | done := false; |
| 146 | repeat |
| 147 | pointr := pointr + 1; |
| 148 | repeat |
| 149 | index := succ(pointr); |
| 150 | if (halfsolution[1, pointr]<>halfsolution[1,index]) and |
| 151 | (halfsolution[2, pointr]<>halfsolution[2,index]) and |
| 152 | (halfsolution[3, pointr]<>halfsolution[3,index]) and |
| 153 | (halfsolution[4, pointr]<>halfsolution[4,index]) then |
| 154 | done := true else |
| 155 | index := index + 1; |
| 156 | until done or (index = pred(halfindex)); |
| 157 | until done or (pointr = halfindex); |
| 158 | if pointr = halfindex then |
| 159 | begin |
| 160 | nosolutions := true; |
| 161 | goto 1; |
| 162 | end; |
| 163 | end; |
| 164 | |
| 165 | procedure rearrange; |
| 166 | var |
| 167 | box: blockno; |
| 168 | a, b: pair; |
| 169 | |
| 170 | procedure put(a, b: pair); |
| 171 | var |
| 172 | old1, new1, old2, new2: face; |
| 173 | save1, save2: alfa; |
| 174 | |
| 175 | procedure oldpair(c: pair); |
| 176 | begin |
| 177 | case c of |
| 178 | one2: |
| 179 | begin |
| 180 | old1 := front; |
| 181 | old2 := back; |
| 182 | end; |
| 183 | three4: |
| 184 | begin |
| 185 | old1 := top; |
| 186 | old2 := bottom; |
| 187 | end; |
| 188 | five6: |
| 189 | begin |
| 190 | old1 := left; |
| 191 | old2 := right; |
| 192 | end |
| 193 | end; |
| 194 | end; |
| 195 | procedure newpair(d: pair); |
| 196 | begin |
| 197 | oldpair(b); |
| 198 | new1 := old1; |
| 199 | new2 := old2; |
| 200 | end; |
| 201 | |
| 202 | begin |
| 203 | newpair(b); |
| 204 | oldpair(a); |
| 205 | save1 := data[box, new1]; |
| 206 | data[box, new1] := data[box, old1]; |
| 207 | data[box, old1] := save1; |
| 208 | save2 := data[box, new2]; |
| 209 | data[box, new2] := data[box, old2]; |
| 210 | data[box, old2] := save2; |
| 211 | end; |
| 212 | |
| 213 | begin |
| 214 | for box := 1 to 4 do |
| 215 | begin |
| 216 | a := halfsolution[box, pointr]; |
| 217 | b := halfsolution[box, index]; |
| 218 | if (a=one2) and (b=five6) then |
| 219 | put(five6, three4) else |
| 220 | begin |
| 221 | if a = three4 then |
| 222 | begin |
| 223 | if b = one2 then |
| 224 | begin |
| 225 | put(one2, five6); |
| 226 | put(three4, one2); |
| 227 | put(five6, three4); |
| 228 | end else |
| 229 | begin |
| 230 | put(three4, one2); |
| 231 | put(five6, three4); |
| 232 | end |
| 233 | end else |
| 234 | if b = one2 then |
| 235 | begin |
| 236 | put(one2, three4); |
| 237 | put(five6, one2); |
| 238 | end else |
| 239 | put(five6, one2); |
| 240 | end; |
| 241 | end; |
| 242 | end; |
| 243 | |
| 244 | procedure correct; |
| 245 | var |
| 246 | list: array[1..8] of integer; |
| 247 | done: Boolean; |
| 248 | side: face; |
| 249 | counter: integer; |
| 250 | |
| 251 | procedure check; |
| 252 | var |
| 253 | delux: array[red..white] of integer; |
| 254 | kolor: color; |
| 255 | counter: integer; |
| 256 | begin |
| 257 | done := true; |
| 258 | for kolor := red to white do |
| 259 | for counter := 1 to 4 do |
| 260 | delux[kolor] := 0; |
| 261 | for counter := 1 to 4 do |
| 262 | begin |
| 263 | delux[word(data[counter,side])] := |
| 264 | delux[word(data[counter,side])] + 1; |
| 265 | if delux[word(data[counter,side])] >= 2 then |
| 266 | done := false; |
| 267 | end; |
| 268 | end; |
| 269 | |
| 270 | procedure rotate; |
| 271 | var |
| 272 | save: alfa; |
| 273 | opposite: face; |
| 274 | begin |
| 275 | if side = back then |
| 276 | opposite := front else |
| 277 | if side = front then |
| 278 | opposite := back else |
| 279 | if side = top then |
| 280 | opposite := bottom else |
| 281 | if side = bottom then |
| 282 | opposite := top; |
| 283 | save := data[list[counter], side]; |
| 284 | data[list[counter], side] := data[list[counter], opposite]; |
| 285 | data[list[counter], opposite] := save; |
| 286 | end; |
| 287 | |
| 288 | begin |
| 289 | list[1] := 4; |
| 290 | list[2] := 3; |
| 291 | list[3] := 4; |
| 292 | list[4] := 2; |
| 293 | list[5] := 4; |
| 294 | list[6] := 3; |
| 295 | list[7] := 4; |
| 296 | list[8] := 3; |
| 297 | for side := back to top do |
| 298 | begin |
| 299 | counter := 0; |
| 300 | check; |
| 301 | while not done do |
| 302 | begin |
| 303 | counter := counter + 1; |
| 304 | rotate; |
| 305 | check; |
| 306 | end; |
| 307 | end |
| 308 | end; |
| 309 | |
| 310 | procedure printout; |
| 311 | var |
| 312 | space: integer; |
| 313 | cube: integer; |
| 314 | side: face; |
| 315 | begin |
| 316 | if nosolutions then |
| 317 | writeln('no solutions') else |
| 318 | begin |
| 319 | writeln('solution to instant insanity'); |
| 320 | for cube := 1 to 4 do |
| 321 | begin |
| 322 | write(cube, ' '); |
| 323 | for side := front to bottom do |
| 324 | write(data[cube, side]); |
| 325 | writeln; |
| 326 | end; |
| 327 | end; |
| 328 | end; |
| 329 | |
| 330 | begin |
| 331 | reset(input, 'insan.d'); |
| 332 | readin; |
| 333 | sumcolors; |
| 334 | find2222; |
| 335 | simultaneous; |
| 336 | rearrange; |
| 337 | correct; |
| 338 | 1: |
| 339 | printout; |
| 340 | end. |
| 341 | { |
| 342 | wbggrb |
| 343 | wbrgrr |
| 344 | wbgwrg |
| 345 | wrgwbr |
| 346 | } |