r""" An unpolished initial class the polyomino tutorial. .. MODULEAUTHOR:: Thierry Monteil """ class Polyomino(SageObject): r""" 2-dimensional polyomino, that is a finite subset of ZZ^2. """ def __init__(self, points, check=True, color='blue'): self._points = set(points) self._color = color if check: if not self.check(): raise Exception('Et merde') def check(self): r""" Check that self is indeed a polyomino. """ return all(i in ZZ and j in ZZ for i,j in self._points) def __len__(self): r""" The number of points of self. """ return len(self._points) def __hash__(self): return hash(tuple(sorted(self._points))) def __eq__(self, other): return self._points == other._points def __add__(self, *other): r""" The polyomino whose points is the union of the points of self and the points of other. """ return Polyomino(self._points.union(other._points)) def __repr__(self): if len(self._points) <= 10: return 'Polyomino of size {}: {}'.format(len(self), self._points) else: return 'Polyomino of size {}'.format(len(self)) def plot(self, color=None, layout='polygon'): if color is None: color = self._color if layout == 'polygon': G = Graphics() for i,j in self._points: G += polygon2d([(i,j), (i+1,j), (i+1,j+1), (i,j+1)], aspect_ratio=1, edgecolor="black", color=color) return G elif layout == 'graph': return self.graph().plot(vertex_labels=False, vertex_size=30, vertex_colors=color, edge_colors=color, axes=False) def shift(self,x,y): r""" Shift self by the vector (x,y). """ new_points = set() for i,j in self._points: new_points.add((i+x,j+y)) return Polyomino(new_points, check=False, color=self._color) def swap(self): r""" Swap self along the diagonal. Note that the swapped is normalized if self is. """ return Polyomino({(j,i) for (i,j) in self._points}, check=False, color=self._color) def rotate(self, normalize=True): r""" Rotate self by pi/2. If normalise is False, the rotation is around 0. If normalise is True (default), the rotated of self is normalized. """ if normalize: return Polyomino({(-j,i) for (i,j) in self._points}, check=False, color=self._color).normalize() else: return Polyomino({(-j,i) for (i,j) in self._points}, check=False, color=self._color) def graph(self): r""" Returns the polyomino as a grid graph. """ G = Graph() pos = dict() for (i,j) in self._points: G.add_vertex((i,j)) pos[(i,j)] = (i,j) if (i+1,j) in self._points: G.add_edge((i,j),(i+1,j)) if (i,j+1) in self._points: G.add_edge((i,j),(i,j+1)) G.set_pos(pos) return G class Tiling(SageObject): r""" A set of translated polyominos. """ def __init__(self, polyomino_translates): self._polyomino_translates = set(polyomino_translates) def __repr__(self): return 'hop' def plot(self, layout='graph', coloration='rainbow'): if coloration == 'rainbow': colors = rainbow(len(self._polyomino_translates)) else: colors = len(self._polyomino_translates)*['black'] G = Graphics() for (p,i,j) in self._polyomino_translates: G += p.shift(i,j).plot(layout=layout, color=colors.pop()) return G def cover(self): s = set() for (p,i,j) in self._polyomino_translates: s.add(p.shift(i,j)._points) return Polyomino(s)