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