| f | class Spiral: | f | class Spiral: |
| | | |
| n | def __init__(self, text: str): | n | def __init__(self, s: str): |
| self.char_count = {} | | self.counts = {} |
| for char in text: | | for ch in s: |
| self.char_count[char] = self.char_count.get(char, 0) + 1 | | self.counts[ch] = self.counts.get(ch, 0) + 1 |
| self.spiral_string = ''.join((char * count for char, count in se | | self.spiral = ''.join((ch * count for ch, count in self.counts.i |
| lf.char_count.items())) | | tems())) |
| | | |
| n | def build_spiral_layer(self, current_index, previous_layer, size, to | n | def f(self, n, s1, k, l): |
| tal_length): | | |
| if size > 3: | | if k > 3: |
| spiral_grid = Spiral.create_matrix(previous_layer, size) | | s = Spiral.matrix(s1, k) |
| else: | | else: |
| n | spiral_grid = [] | n | s = [] |
| spiral_grid.append(' ' * size) | | s.append(' ' * k) |
| spiral_grid.append(' ' * size) | | s.append(' ' * k) |
| spiral_grid.append(' ' * size) | | s.append(' ' * k) |
| for row in range(2, size): | | for i in range(2, k): |
| if current_index == total_length: | | if n == l: |
| break | | break |
| n | spiral_grid[row] = spiral_grid[row][:1] + self.spiral_string | n | s[i] = s[i][:1] + self.spiral[n] + s[i][2:] |
| [current_index] + spiral_grid[row][2:] | | |
| current_index += 1 | | n += 1 |
| for col in range(2, size): | | for i in range(2, k): |
| if current_index == total_length: | | if n == l: |
| break | | break |
| n | spiral_grid[size - 1] = spiral_grid[size - 1][:col] + self.s | n | s[k - 1] = s[k - 1][:i] + self.spiral[n] + s[k - 1][i + 1:] |
| piral_string[current_index] + spiral_grid[size - 1][col + 1:] | | |
| current_index += 1 | | n += 1 |
| for row in range(size - 2, 0, -1): | | for i in range(k - 2, 0, -1): |
| if current_index == total_length: | | if n == l: |
| break | | break |
| n | spiral_grid[row] = spiral_grid[row][:size - 1] + self.spiral | n | s[i] = s[i][:k - 1] + self.spiral[n] |
| _string[current_index] | | |
| current_index += 1 | | n += 1 |
| for col in range(size): | | for i in range(k): |
| if current_index == total_length: | | if n == l: |
| break | | break |
| n | spiral_grid[0] = spiral_grid[0][:size - 1 - col] + self.spir | n | s[0] = s[0][:k - 1 - i] + self.spiral[n] + s[0][k - i:] |
| al_string[current_index] + spiral_grid[0][size - col:] | | |
| current_index += 1 | | n += 1 |
| return (current_index, spiral_grid) | | return (n, s) |
| | | |
| n | def create_matrix(previous_layer, size): | n | def matrix(s1, k): |
| grid = [] | | s = [] |
| grid.append(' ' * size) | | s.append(' ' * k) |
| grid.append(' ' * size) | | s.append(' ' * k) |
| for line in previous_layer: | | for i in s1: |
| grid.append(' ' * 2 + line + ' ' * 2) | | s.append(' ' * 2 + i + ' ' * 2) |
| grid.append(' ' * size) | | s.append(' ' * k) |
| grid.append(' ' * size) | | s.append(' ' * k) |
| return grid | | return s |
| | | |
| def __str__(self): | | def __str__(self): |
| n | current_index = 0 | n | n = 0 |
| spiral_size = 3 | | k = 3 |
| total_length = len(self.spiral_string) | | l = len(self.spiral) |
| result = self.build_spiral_layer(current_index, None, spiral_siz | | res = self.f(n, None, k, l) |
| e, total_length) | | |
| while result[0] != total_length: | | while res[0] != l: |
| spiral_size += 4 | | k += 4 |
| result = self.build_spiral_layer(result[0], result[1], spira | | res = self.f(res[0], res[1], k, l) |
| l_size, total_length) | | |
| cropped_result = Spiral.crop_matrix(result[1]) | | cropped = Spiral.crop(res[1]) |
| return '\n'.join(cropped_result) | | return '\n'.join(cropped) |
| | | |
| n | def crop_matrix(matrix_lines): | n | def crop(matrix_lines): |
| lines = [line.rstrip() for line in matrix_lines] | | lines = [line.rstrip() for line in matrix_lines] |
| while lines and (not lines[0].strip()): | | while lines and (not lines[0].strip()): |
| lines.pop(0) | | lines.pop(0) |
| while lines and (not lines[-1].strip()): | | while lines and (not lines[-1].strip()): |
| lines.pop(-1) | | lines.pop(-1) |
| n | left_margin = 0 | n | left = 0 |
| right_margin = max((len(line) for line in lines)) | | right = max((len(line) for line in lines)) |
| while left_margin < right_margin and all((len(line) <= left_marg | | while left < right and all((len(line) <= left or line[left] == ' |
| in or line[left_margin] == ' ' for line in lines)): | | ' for line in lines)): |
| left_margin += 1 | | left += 1 |
| while right_margin > left_margin and all((len(line) <= right_mar | | while right > left and all((len(line) <= right - 1 or line[right |
| gin - 1 or line[right_margin - 1] == ' ' for line in lines)): | | - 1] == ' ' for line in lines)): |
| right_margin -= 1 | | right -= 1 |
| return [line[left_margin:right_margin] for line in lines] | | return [line[left:right] for line in lines] |
| | | |
| def __add__(self, other): | | def __add__(self, other): |
| result = Spiral('') | | result = Spiral('') |
| n | result.char_count = self.char_count.copy() | n | result.counts = self.counts.copy() |
| for char, count in other.char_count.items(): | | for ch, count in other.counts.items(): |
| if char in result.char_count: | | if ch in result.counts: |
| result.char_count[char] += count | | result.counts[ch] += count |
| else: | | else: |
| n | result.char_count[char] = count | n | result.counts[ch] = count |
| result.spiral_string = ''.join((char * count for char, count in | | result.spiral = ''.join((ch * count for ch, count in result.coun |
| result.char_count.items())) | | ts.items())) |
| return result | | return result |
| | | |
| def __sub__(self, other): | | def __sub__(self, other): |
| result = Spiral('') | | result = Spiral('') |
| n | result.char_count = self.char_count.copy() | n | result.counts = self.counts.copy() |
| for char, count in other.char_count.items(): | | for ch, count in other.counts.items(): |
| if char in result.char_count: | | if ch in result.counts: |
| result.char_count[char] -= count | | result.counts[ch] -= count |
| if result.char_count[char] <= 0: | | if result.counts[ch] <= 0: |
| del result.char_count[char] | | del result.counts[ch] |
| result.spiral_string = ''.join((char * count for char, count in | | result.spiral = ''.join((ch * count for ch, count in result.coun |
| result.char_count.items())) | | ts.items())) |
| return result | | return result |
| | | |
| n | def __mul__(self, multiplier): | n | def __mul__(self, n): |
| result = Spiral('') | | result = Spiral('') |
| n | result.char_count = {char: count * multiplier for char, count in | n | result.counts = {ch: count * n for ch, count in self.counts.item |
| self.char_count.items()} | | s()} |
| result.spiral_string = ''.join((char * count for char, count in | | result.spiral = ''.join((ch * count for ch, count in result.coun |
| result.char_count.items())) | | ts.items())) |
| return result | | return result |
| | | |
| def __iter__(self): | | def __iter__(self): |
| n | for char, count in self.char_count.items(): | n | for ch, count in self.counts.items(): |
| for _ in range(count): | | for _ in range(count): |
| t | yield char | t | yield ch |