| t | from collections import Counter | t | from collections import Counter |
| | | |
| class Spiral: | | class Spiral: |
| | | |
| def __init__(self, string=''): | | def __init__(self, string=''): |
| self.cells = Counter(string) | | self.cells = Counter(string) |
| | | |
| def __iter__(self): | | def __iter__(self): |
| return self.cells.elements() | | return self.cells.elements() |
| | | |
| def __add__(self, other): | | def __add__(self, other): |
| if not isinstance(other, Spiral): | | if not isinstance(other, Spiral): |
| return NotImplemented | | return NotImplemented |
| return type(self)(self.cells + other.cells) | | return type(self)(self.cells + other.cells) |
| | | |
| def __sub__(self, other): | | def __sub__(self, other): |
| if not isinstance(other, Spiral): | | if not isinstance(other, Spiral): |
| return NotImplemented | | return NotImplemented |
| return type(self)(self.cells - other.cells) | | return type(self)(self.cells - other.cells) |
| | | |
| def __mul__(self, n): | | def __mul__(self, n): |
| if not isinstance(n, int) or n < 0: | | if not isinstance(n, int) or n < 0: |
| return NotImplemented | | return NotImplemented |
| return type(self)(list(self) * n) | | return type(self)(list(self) * n) |
| __rmul__ = __mul__ | | __rmul__ = __mul__ |
| | | |
| def __len__(self): | | def __len__(self): |
| return sum(self.cells.values()) | | return sum(self.cells.values()) |
| | | |
| def _square(self): | | def _square(self): |
| dx, dy = ((0, 1, 0, -1), (1, 0, -1, 0)) | | dx, dy = ((0, 1, 0, -1), (1, 0, -1, 0)) |
| field = {} | | field = {} |
| x = y = n = k = j = 0 | | x = y = n = k = j = 0 |
| mx = Mx = my = My = 0 | | mx = Mx = my = My = 0 |
| for i, c in enumerate(self): | | for i, c in enumerate(self): |
| field[x, y] = c | | field[x, y] = c |
| mx, my = (min(mx, x), min(my, y)) | | mx, my = (min(mx, x), min(my, y)) |
| Mx, My = (max(Mx, x), max(My, y)) | | Mx, My = (max(Mx, x), max(My, y)) |
| if i >= n: | | if i >= n: |
| k += 1 | | k += 1 |
| n += k | | n += k |
| j = (j + 1) % 4 | | j = (j + 1) % 4 |
| x += dx[j] | | x += dx[j] |
| y += dy[j] | | y += dy[j] |
| return (field, (mx, Mx), (my, My)) | | return (field, (mx, Mx), (my, My)) |
| | | |
| def __str__(self): | | def __str__(self): |
| field, (mx, Mx), (my, My) = self._square() | | field, (mx, Mx), (my, My) = self._square() |
| return '\n'.join((''.join((field.get((x, y), ' ') for x in range | | return '\n'.join((''.join((field.get((x, y), ' ') for x in range |
| (mx, Mx + 1))) for y in range(my, My + 1))) | | (mx, Mx + 1))) for y in range(my, My + 1))) |