Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/games/quantumino.py
4077 views
1
# coding=utf-8
2
r"""
3
Family Games America's Quantumino solver
4
5
This module allows to solve the `Quantumino puzzle
6
<http://familygamesamerica.com/mainsite/consumers/productview.php?pro_id=274&search=quantumino>`_
7
made by Family Games America (see also `this video
8
<http://www.youtube.com/watch?v=jX_VKzakZi8>`_ on Youtube). This puzzle was
9
left at the dinner room of the Laboratoire de Combinatoire Informatique
10
Mathematique in Montreal by Franco Saliola during winter 2011.
11
12
The solution uses the dancing links code which is in Sage and is based on
13
the more general code available in the module :mod:`sage.combinat.tiling`.
14
Dancing links were originally introduced by Donald Knuth in 2000
15
(`arXiv:cs/0011047 <http://arxiv.org/abs/cs/0011047>`_). In particular,
16
Knuth used dancing links to solve tilings of a region by 2D pentaminos.
17
Here we extend the method for 3D pentaminos.
18
19
This module defines two classes :
20
21
- :class:`sage.games.quantumino.QuantuminoState` class, to represent a
22
state of the Quantumino game, i.e. a solution or a partial solution.
23
24
- :class:`sage.games.quantumino.QuantuminoSolver` class, to find, enumerate
25
and count the number of solutions of the Quantumino game where one of the
26
piece is put aside.
27
28
AUTHOR:
29
30
- Sebastien Labbe, April 28th, 2011
31
32
DESCRIPTION (from [1]):
33
34
"
35
Pentamino games have been taken to a whole different level; a 3-D
36
level, with this colorful creation! Using the original pentamino
37
arrangements of 5 connected squares which date from 1907, players are
38
encouraged to "think inside the box" as they try to fit 16 of the 17
39
3-D pentamino pieces inside the playing perimeters. Remove a different
40
piece each time you play for an entirely new challenge! Thousands of
41
solutions to be found!
42
Quantumino hands-on educational tool where players learn how shapes
43
can be transformed or arranged into predefined shapes and spaces.
44
Includes:
45
1 wooden frame, 17 wooden blocks, instruction booklet.
46
Age: 8+
47
"
48
49
EXAMPLES:
50
51
Here are the 17 wooden blocks of the Quantumino puzzle numbered from 0 to 16 in
52
the following 3d picture. They will show up in 3D in your default (=Jmol)
53
viewer::
54
55
sage: from sage.games.quantumino import show_pentaminos
56
sage: show_pentaminos()
57
58
To solve the puzzle where the pentamino numbered 12 is put aside::
59
60
sage: from sage.games.quantumino import QuantuminoSolver
61
sage: s = QuantuminoSolver(12).solve().next() # long time (10 s)
62
sage: s # long time (<1s)
63
Quantumino state where the following pentamino is put aside :
64
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (2, 1, 1)], Color: blue
65
sage: s.show3d() # long time (<1s)
66
67
To remove the frame::
68
69
sage: s.show3d().show(frame=False) # long time (<1s)
70
71
To solve the puzzle where the pentamino numbered 7 is put aside::
72
73
sage: s = QuantuminoSolver(7).solve().next() # long time (10 s)
74
sage: s # long time (<1s)
75
Quantumino state where the following pentamino is put aside :
76
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 0, 0)], Color: orange
77
sage: s.show3d() # long time (<1s)
78
79
The solution is iterable. This may be used to explicitly list the positions of each
80
pentamino::
81
82
sage: for p in s: p # long time (<1s)
83
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink
84
Polyomino: [(0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 1), (1, 2, 1)], Color: deeppink
85
Polyomino: [(0, 2, 0), (0, 3, 0), (0, 4, 0), (1, 4, 0), (1, 4, 1)], Color: green
86
Polyomino: [(0, 3, 1), (1, 3, 1), (2, 2, 0), (2, 2, 1), (2, 3, 1)], Color: green
87
Polyomino: [(1, 3, 0), (2, 3, 0), (2, 4, 0), (2, 4, 1), (3, 4, 0)], Color: red
88
Polyomino: [(1, 0, 1), (2, 0, 1), (2, 1, 0), (2, 1, 1), (3, 1, 1)], Color: red
89
Polyomino: [(2, 0, 0), (3, 0, 0), (3, 0, 1), (3, 1, 0), (4, 0, 0)], Color: gray
90
Polyomino: [(3, 2, 0), (4, 0, 1), (4, 1, 0), (4, 1, 1), (4, 2, 0)], Color: purple
91
Polyomino: [(3, 2, 1), (3, 3, 0), (3, 3, 1), (4, 2, 1), (4, 3, 1)], Color: yellow
92
Polyomino: [(3, 4, 1), (3, 5, 1), (4, 3, 0), (4, 4, 0), (4, 4, 1)], Color: blue
93
Polyomino: [(0, 4, 1), (0, 5, 0), (0, 5, 1), (0, 6, 1), (1, 5, 0)], Color: midnightblue
94
Polyomino: [(0, 6, 0), (0, 7, 0), (0, 7, 1), (1, 7, 0), (2, 7, 0)], Color: darkblue
95
Polyomino: [(1, 7, 1), (2, 6, 0), (2, 6, 1), (2, 7, 1), (3, 6, 0)], Color: blue
96
Polyomino: [(1, 5, 1), (1, 6, 0), (1, 6, 1), (2, 5, 0), (2, 5, 1)], Color: yellow
97
Polyomino: [(3, 6, 1), (3, 7, 0), (3, 7, 1), (4, 5, 1), (4, 6, 1)], Color: purple
98
Polyomino: [(3, 5, 0), (4, 5, 0), (4, 6, 0), (4, 7, 0), (4, 7, 1)], Color: orange
99
100
To get all the solutions, use the iterator returned by the ``solve``
101
method. Note that finding the first solution is the most time consuming
102
because it needs to create the complete data to describe the problem::
103
104
sage: it = QuantuminoSolver(7).solve()
105
sage: it.next() # not tested (10s)
106
Quantumino state where the following pentamino is put aside :
107
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 0, 0)], Color: orange
108
sage: it.next() # not tested (0.001s)
109
Quantumino state where the following pentamino is put aside :
110
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 0, 0)], Color: orange
111
sage: it.next() # not tested (0.001s)
112
Quantumino state where the following pentamino is put aside :
113
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 0, 0)], Color: orange
114
115
To get the solution inside other boxes::
116
117
sage: s = QuantuminoSolver(7, box=(4,4,5)).solve().next() # not tested (2s)
118
sage: s.show3d() # not tested (<1s)
119
120
::
121
122
sage: s = QuantuminoSolver(7, box=(2,2,20)).solve().next() # not tested (1s)
123
sage: s.show3d() # not tested (<1s)
124
125
If there are no solution, a StopIteration error is raised::
126
127
sage: QuantuminoSolver(7, box=(3,3,3)).solve().next()
128
Traceback (most recent call last):
129
...
130
StopIteration
131
132
The implementation allows a lot of introspection. From the
133
:class:`~sage.combinat.tiling.TilingSolver` object,
134
it is possible to retrieve the rows that are passed to the DLX
135
solver and count them. It is also possible to get an instance of the DLX
136
solver to play with it::
137
138
sage: q = QuantuminoSolver(0)
139
sage: T = q.tiling_solver()
140
sage: T
141
Tiling solver of 16 pieces into the box (5, 8, 2)
142
Rotation allowed: True
143
Reflection allowed: False
144
Reusing pieces allowed: False
145
sage: rows = T.rows() # not tested (10 s)
146
sage: len(rows) # not tested (but fast)
147
5484
148
sage: x = T.dlx_solver() # long time (10 s)
149
sage: x # long time (fast)
150
<sage.combinat.matrices.dancing_links.dancing_linksWrapper object at ...>
151
152
REFERENCES:
153
154
- [1] `Family Games America's Quantumino
155
<http://familygamesamerica.com/mainsite/consumers/productview.php?pro_id=274&search=quantumino>`_
156
- [2] `Quantumino - How to Play <http://www.youtube.com/watch?v=jX_VKzakZi8>`_ on Youtube
157
- [3] Knuth, Donald (2000). "Dancing links". `arXiv:cs/0011047
158
<http://arxiv.org/abs/cs/0011047>`_.
159
160
"""
161
#*****************************************************************************
162
# Copyright (C) 2011 Sebastien Labbe <[email protected]>
163
#
164
# Distributed under the terms of the GNU General Public License (GPL)
165
# as published by the Free Software Foundation; either version 2 of
166
# the License, or (at your option) any later version.
167
# http://www.gnu.org/licenses/
168
#*****************************************************************************
169
from sage.structure.sage_object import SageObject
170
from sage.plot.all import Graphics
171
from sage.plot.plot3d.platonic import cube
172
from sage.plot.plot3d.shapes2 import text3d
173
from sage.modules.free_module_element import vector
174
from sage.combinat.tiling import Polyomino, TilingSolver
175
176
################################################
177
# Example: The family games america: Quantumino
178
################################################
179
pentaminos = []
180
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,2,0), (1,1,1)], color='deeppink'))
181
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (-1,0,0), (0,0,1)], color='deeppink'))
182
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,2,0), (0,0,1)], color='green'))
183
pentaminos.append(Polyomino([(0,0,0), (0,1,0), (0,2,0), (1,0,0), (1,0,1)], color='green'))
184
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,0,1), (1,-1,1)], color='red'))
185
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,0,1), (2,0,1)], color='red'))
186
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,2,0), (1,2,1)], color='orange'))
187
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (0,1,0), (0,2,0), (0,2,1)], color='orange'))
188
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (0,1,0), (1,1,0), (0,0,1)], color='yellow'))
189
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,1,1), (0,0,1)], color='yellow'))
190
pentaminos.append(Polyomino([(0,0,0), (0,1,0), (1,1,0), (0,2,0), (1,1,1)], color='midnightblue'))
191
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,0,1), (1,2,0)], color='darkblue'))
192
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,1,1), (2,1,1)], color='blue'))
193
pentaminos.append(Polyomino([(0,0,0), (0,1,0), (1,1,0), (1,1,1), (1,2,1)], color='blue'))
194
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (2,1,0), (2,1,1)], color='purple'))
195
pentaminos.append(Polyomino([(0,0,0), (0,1,0), (1,1,0), (1,2,0), (1,2,1)], color='purple'))
196
pentaminos.append(Polyomino([(0,0,0), (1,0,0), (1,1,0), (1,0,1), (1,-1,0)], color='gray'))
197
198
def show_pentaminos(box=(5,8,2)):
199
r"""
200
Show the 17 3-D pentaminos included in the game and the `5 \times 8
201
\times 2` box where 16 of them must fit.
202
203
INPUT:
204
205
- ``box`` - tuple of size three (optional, default: ``(5,8,2)``),
206
size of the box
207
208
OUTPUT:
209
210
3D Graphic object
211
212
EXAMPLES::
213
214
sage: from sage.games.quantumino import show_pentaminos
215
sage: show_pentaminos() # not tested (1s)
216
217
To remove the frame do::
218
219
sage: show_pentaminos().show(frame=False) # not tested (1s)
220
"""
221
G = Graphics()
222
for i,p in enumerate(pentaminos):
223
x = 3.5 * (i%4)
224
y = 3.5 * (i/4)
225
q = p + (x, y, 0)
226
G += q.show3d()
227
G += text3d(str(i), (x,y,2))
228
G += cube(color='gray',opacity=0.5).scale(box).translate((17,6,0))
229
230
# hack to set the aspect ratio to 1
231
a,b = G.bounding_box()
232
a,b = map(vector, (a,b))
233
G.frame_aspect_ratio(tuple(b-a))
234
235
return G
236
237
##############################
238
# Class QuantuminoState
239
##############################
240
class QuantuminoState(SageObject):
241
r"""
242
A state of the Quantumino puzzle.
243
244
Used to represent an solution or a partial solution of the Quantumino
245
puzzle.
246
247
INPUT:
248
249
- ``pentos`` - list of 16 3d pentamino representing the (partial)
250
solution
251
- ``aside`` - 3d polyomino, the unused 3D pentamino
252
253
EXAMPLES::
254
255
sage: from sage.games.quantumino import pentaminos, QuantuminoState
256
sage: p = pentaminos[0]
257
sage: q = pentaminos[5]
258
sage: r = pentaminos[11]
259
sage: S = QuantuminoState([p,q], r)
260
sage: S
261
Quantumino state where the following pentamino is put aside :
262
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 2, 0)], Color: darkblue
263
264
::
265
266
sage: from sage.games.quantumino import QuantuminoSolver
267
sage: QuantuminoSolver(3).solve().next() # not tested (1.5s)
268
Quantumino state where the following pentamino is put aside :
269
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (1, 0, 0), (1, 0, 1)], Color: green
270
"""
271
def __init__(self, pentos, aside):
272
r"""
273
EXAMPLES::
274
275
sage: from sage.games.quantumino import pentaminos, QuantuminoState
276
sage: p = pentaminos[0]
277
sage: q = pentaminos[5]
278
sage: QuantuminoState([p], q)
279
Quantumino state where the following pentamino is put aside :
280
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 0, 1), (1, 1, 0), (2, 0, 1)], Color: red
281
"""
282
assert all(isinstance(p, Polyomino) for p in pentos), "pentos must be an iterable of Polyomino"
283
assert isinstance(aside, Polyomino), "aside must be a Polyomino"
284
self._pentos = pentos
285
self._aside = aside
286
287
def __repr__(self):
288
r"""
289
EXAMPLES::
290
291
sage: from sage.games.quantumino import pentaminos, QuantuminoState
292
sage: p = pentaminos[0]
293
sage: q = pentaminos[5]
294
sage: QuantuminoState([p], q)
295
Quantumino state where the following pentamino is put aside :
296
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 0, 1), (1, 1, 0), (2, 0, 1)], Color: red
297
"""
298
return "Quantumino state where the following pentamino is put aside :\n%s" % self._aside
299
300
def __iter__(self):
301
r"""
302
EXAMPLES::
303
304
sage: from sage.games.quantumino import pentaminos, QuantuminoState
305
sage: p = pentaminos[0]
306
sage: q = pentaminos[5]
307
sage: r = pentaminos[11]
308
sage: S = QuantuminoState([p,q], r)
309
sage: for a in S: a
310
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink
311
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 0, 1), (1, 1, 0), (2, 0, 1)], Color: red
312
"""
313
return iter(self._pentos)
314
315
def list(self):
316
r"""
317
Return the list of 3d polyomino making the solution.
318
319
EXAMPLES::
320
321
sage: from sage.games.quantumino import pentaminos, QuantuminoState
322
sage: p = pentaminos[0]
323
sage: q = pentaminos[5]
324
sage: r = pentaminos[11]
325
sage: S = QuantuminoState([p,q], r)
326
sage: L = S.list()
327
sage: L[0]
328
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink
329
sage: L[1]
330
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 0, 1), (1, 1, 0), (2, 0, 1)], Color: red
331
"""
332
return list(self)
333
334
def show3d(self, size=0.85):
335
r"""
336
Return the solution as a 3D Graphic object.
337
338
OUTPUT:
339
340
3D Graphic Object
341
342
EXAMPLES::
343
344
sage: from sage.games.quantumino import QuantuminoSolver
345
sage: s = QuantuminoSolver(0).solve().next() # not tested (1.5s)
346
sage: G = s.show3d() # not tested (<1s)
347
sage: type(G) # not tested
348
<class 'sage.plot.plot3d.base.Graphics3dGroup'>
349
350
To remove the frame::
351
352
sage: G.show(frame=False) # not tested
353
354
To see the solution with Tachyon viewer::
355
356
sage: G.show(viewer='tachyon', frame=False) # not tested
357
"""
358
G = Graphics()
359
for p in self:
360
G += p.show3d(size=size)
361
aside_pento = self._aside.canonical() + (2.5*size/0.75,-4*size/0.75,0)
362
G += aside_pento.show3d(size=size)
363
364
# hack to set the aspect ratio to 1
365
a,b = G.bounding_box()
366
a,b = map(vector, (a,b))
367
G.frame_aspect_ratio(tuple(b-a))
368
369
return G
370
371
##############################
372
# Class QuantuminoSolver
373
##############################
374
class QuantuminoSolver(SageObject):
375
r"""
376
Return the Quantumino solver for the given box where one of the
377
pentamino is put aside.
378
379
INPUT:
380
381
- ``aside`` - integer, from 0 to 16, the aside pentamino
382
- ``box`` - tuple of size three (optional, default: ``(5,8,2)``),
383
size of the box
384
385
EXAMPLES::
386
387
sage: from sage.games.quantumino import QuantuminoSolver
388
sage: QuantuminoSolver(9)
389
Quantumino solver for the box (5, 8, 2)
390
Aside pentamino number: 9
391
sage: QuantuminoSolver(12, box=(5,4,4))
392
Quantumino solver for the box (5, 4, 4)
393
Aside pentamino number: 12
394
"""
395
def __init__(self, aside, box=(5,8,2)):
396
r"""
397
Constructor.
398
399
EXAMPLES::
400
401
sage: from sage.games.quantumino import QuantuminoSolver
402
sage: QuantuminoSolver(9)
403
Quantumino solver for the box (5, 8, 2)
404
Aside pentamino number: 9
405
"""
406
if not 0 <= aside < 17:
407
raise ValueError, "aside (=%s) must be between 0 and 16" % aside
408
self._aside = aside
409
self._box = box
410
411
def __repr__(self):
412
r"""
413
String representation
414
415
EXAMPLES::
416
417
sage: from sage.games.quantumino import QuantuminoSolver
418
sage: QuantuminoSolver(0)
419
Quantumino solver for the box (5, 8, 2)
420
Aside pentamino number: 0
421
"""
422
s = "Quantumino solver for the box %s\n" % (self._box, )
423
s += "Aside pentamino number: %s" % self._aside
424
return s
425
426
def tiling_solver(self):
427
r"""
428
Return the Tiling solver of the Quantumino Game where one of the
429
pentamino is put aside.
430
431
EXAMPLES::
432
433
sage: from sage.games.quantumino import QuantuminoSolver
434
sage: QuantuminoSolver(0).tiling_solver()
435
Tiling solver of 16 pieces into the box (5, 8, 2)
436
Rotation allowed: True
437
Reflection allowed: False
438
Reusing pieces allowed: False
439
sage: QuantuminoSolver(14).tiling_solver()
440
Tiling solver of 16 pieces into the box (5, 8, 2)
441
Rotation allowed: True
442
Reflection allowed: False
443
Reusing pieces allowed: False
444
sage: QuantuminoSolver(14, box=(5,4,4)).tiling_solver()
445
Tiling solver of 16 pieces into the box (5, 4, 4)
446
Rotation allowed: True
447
Reflection allowed: False
448
Reusing pieces allowed: False
449
"""
450
pieces = pentaminos[:self._aside] + pentaminos[self._aside+1:]
451
return TilingSolver(pieces, box=self._box)
452
453
def solve(self, partial=None):
454
r"""
455
Return an iterator over the solutions where one of the pentamino is
456
put aside.
457
458
INPUT:
459
460
- ``partial`` - string (optional, default: ``None``), whether to
461
include partial (incomplete) solutions. It can be one of the
462
following:
463
464
- ``None`` - include only complete solution
465
- ``'common'`` - common part between two consecutive solutions
466
- ``'incremental'`` - one piece change at a time
467
468
OUTPUT:
469
470
iterator of QuantuminoState
471
472
EXAMPLES:
473
474
Get one solution::
475
476
sage: from sage.games.quantumino import QuantuminoSolver
477
sage: s = QuantuminoSolver(8).solve().next() # long time (9s)
478
sage: s # long time (fast)
479
Quantumino state where the following pentamino is put aside :
480
Polyomino: [(0, 0, 0), (0, 0, 1), (0, 1, 0), (1, 0, 0), (1, 1, 0)], Color: yellow
481
sage: s.show3d() # long time (< 1s)
482
483
The explicit solution::
484
485
sage: for p in s: p # long time (fast)
486
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink
487
Polyomino: [(0, 0, 1), (0, 1, 0), (0, 1, 1), (0, 2, 1), (1, 2, 1)], Color: deeppink
488
Polyomino: [(0, 2, 0), (0, 3, 0), (0, 4, 0), (1, 4, 0), (1, 4, 1)], Color: green
489
Polyomino: [(0, 3, 1), (1, 3, 1), (2, 2, 0), (2, 2, 1), (2, 3, 1)], Color: green
490
Polyomino: [(1, 3, 0), (2, 3, 0), (2, 4, 0), (2, 4, 1), (3, 4, 0)], Color: red
491
Polyomino: [(1, 0, 1), (2, 0, 0), (2, 0, 1), (2, 1, 0), (3, 0, 1)], Color: midnightblue
492
Polyomino: [(0, 4, 1), (0, 5, 0), (0, 5, 1), (0, 6, 0), (1, 5, 0)], Color: red
493
Polyomino: [(2, 1, 1), (3, 0, 0), (3, 1, 0), (3, 1, 1), (4, 0, 0)], Color: blue
494
Polyomino: [(3, 2, 0), (4, 0, 1), (4, 1, 0), (4, 1, 1), (4, 2, 0)], Color: purple
495
Polyomino: [(3, 2, 1), (3, 3, 0), (4, 2, 1), (4, 3, 0), (4, 3, 1)], Color: yellow
496
Polyomino: [(3, 3, 1), (3, 4, 1), (4, 4, 0), (4, 4, 1), (4, 5, 0)], Color: blue
497
Polyomino: [(0, 6, 1), (0, 7, 0), (0, 7, 1), (1, 5, 1), (1, 6, 1)], Color: purple
498
Polyomino: [(1, 6, 0), (1, 7, 0), (1, 7, 1), (2, 7, 0), (3, 7, 0)], Color: darkblue
499
Polyomino: [(2, 5, 0), (2, 6, 0), (3, 6, 0), (4, 6, 0), (4, 6, 1)], Color: orange
500
Polyomino: [(2, 5, 1), (3, 5, 0), (3, 5, 1), (3, 6, 1), (4, 5, 1)], Color: gray
501
Polyomino: [(2, 6, 1), (2, 7, 1), (3, 7, 1), (4, 7, 0), (4, 7, 1)], Color: orange
502
503
Enumerate the solutions::
504
505
sage: it = QuantuminoSolver(0).solve()
506
sage: it.next() # not tested
507
Quantumino state where the following pentamino is put aside :
508
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink
509
sage: it.next() # not tested
510
Quantumino state where the following pentamino is put aside :
511
Polyomino: [(0, 0, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (1, 2, 0)], Color: deeppink
512
513
With the partial solutions included, one can see the evolution
514
between consecutive solutions (an animation would be better)::
515
516
sage: it = QuantuminoSolver(0).solve(partial='common')
517
sage: it.next().show3d() # not tested (2s)
518
sage: it.next().show3d() # not tested (< 1s)
519
sage: it.next().show3d() # not tested (< 1s)
520
521
Generalizations of the game inside different boxes::
522
523
sage: QuantuminoSolver(7, (4,4,5)).solve().next() # long time (2s)
524
Quantumino state where the following pentamino is put aside :
525
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 0, 0)], Color: orange
526
sage: QuantuminoSolver(7, (2,2,20)).solve().next() # long time (1s)
527
Quantumino state where the following pentamino is put aside :
528
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 0, 0)], Color: orange
529
sage: QuantuminoSolver(3, (2,2,20)).solve().next() # long time (1s)
530
Quantumino state where the following pentamino is put aside :
531
Polyomino: [(0, 0, 0), (0, 1, 0), (0, 2, 0), (1, 0, 0), (1, 0, 1)], Color: green
532
533
If the volume of the box is not 80, there is no solution::
534
535
sage: QuantuminoSolver(7, box=(3,3,9)).solve().next()
536
Traceback (most recent call last):
537
...
538
StopIteration
539
540
If the box is too small, there is no solution::
541
542
sage: QuantuminoSolver(4, box=(40,2,1)).solve().next()
543
Traceback (most recent call last):
544
...
545
StopIteration
546
"""
547
T = self.tiling_solver()
548
aside = pentaminos[self._aside]
549
for pentos in T.solve(partial=partial):
550
yield QuantuminoState(pentos, aside)
551
552
def number_of_solutions(self):
553
r"""
554
Return the number of solutions.
555
556
OUTPUT:
557
558
integer
559
560
EXAMPLES::
561
562
sage: from sage.games.quantumino import QuantuminoSolver
563
sage: QuantuminoSolver(4, box=(3,2,2)).number_of_solutions()
564
0
565
566
This computation takes several days::
567
568
sage: QuantuminoSolver(0).number_of_solutions() # not tested
569
??? hundreds of millions ???
570
"""
571
return self.tiling_solver().number_of_solutions()
572
573
574
575