david_Yakhin_312 SpiralString 6816
Алмаз Сейтхазин (КФ МГУ, кафедра НДС) SpiralString 6719
t1from collections import OrderedDictt1from collections import OrderedDict
22
3class Spiral:3class Spiral:
44
5    def __init__(self, s):5    def __init__(self, s):
6        counts = OrderedDict()6        counts = OrderedDict()
7        for char in s:7        for char in s:
8            counts[char] = counts.get(char, 0) + 18            counts[char] = counts.get(char, 0) + 1
9        self.groups = [(ch, n) for ch, n in counts.items()]9        self.groups = [(ch, n) for ch, n in counts.items()]
1010
11    def __add__(self, other):11    def __add__(self, other):
12        new_groups = []12        new_groups = []
13        other_dict = dict(other.groups)13        other_dict = dict(other.groups)
14        for ch, n in self.groups:14        for ch, n in self.groups:
15            new_n = n + other_dict.get(ch, 0)15            new_n = n + other_dict.get(ch, 0)
16            new_groups.append((ch, new_n))16            new_groups.append((ch, new_n))
17        for ch, n in other.groups:17        for ch, n in other.groups:
18            if ch not in dict(self.groups):18            if ch not in dict(self.groups):
19                new_groups.append((ch, n))19                new_groups.append((ch, n))
20        return Spiral.from_groups(new_groups)20        return Spiral.from_groups(new_groups)
2121
22    def __sub__(self, other):22    def __sub__(self, other):
23        new_groups = []23        new_groups = []
24        other_dict = dict(other.groups)24        other_dict = dict(other.groups)
25        for ch, n in self.groups:25        for ch, n in self.groups:
26            new_n = n - other_dict.get(ch, 0)26            new_n = n - other_dict.get(ch, 0)
27            if new_n > 0:27            if new_n > 0:
28                new_groups.append((ch, new_n))28                new_groups.append((ch, new_n))
29        return Spiral.from_groups(new_groups)29        return Spiral.from_groups(new_groups)
3030
31    def __mul__(self, num):31    def __mul__(self, num):
32        new_groups = [(ch, n * num) for ch, n in self.groups]32        new_groups = [(ch, n * num) for ch, n in self.groups]
33        return Spiral.from_groups(new_groups)33        return Spiral.from_groups(new_groups)
3434
35    def __iter__(self):35    def __iter__(self):
36        for ch, n in self.groups:36        for ch, n in self.groups:
37            for _ in range(n):37            for _ in range(n):
38                yield ch38                yield ch
3939
40    def __str__(self):40    def __str__(self):
41        total = sum((n for _, n in self.groups))41        total = sum((n for _, n in self.groups))
42        if total == 0:42        if total == 0:
43            return ''43            return ''
44        coords = list(Spiral.spiral_coordinates(total))44        coords = list(Spiral.spiral_coordinates(total))
45        assigned = {}45        assigned = {}
46        index = 046        index = 0
47        for ch, n in self.groups:47        for ch, n in self.groups:
48            for i in range(n):48            for i in range(n):
49                assigned[coords[index]] = ch49                assigned[coords[index]] = ch
50                index += 150                index += 1
51        xs = [x for x, y in coords]51        xs = [x for x, y in coords]
52        ys = [y for x, y in coords]52        ys = [y for x, y in coords]
53        min_x, max_x = (min(xs), max(xs))53        min_x, max_x = (min(xs), max(xs))
54        min_y, max_y = (min(ys), max(ys))54        min_y, max_y = (min(ys), max(ys))
55        grid = []55        grid = []
56        for x in range(min_x, max_x + 1):56        for x in range(min_x, max_x + 1):
57            row = []57            row = []
58            for y in range(min_y, max_y + 1):58            for y in range(min_y, max_y + 1):
59                row.append(assigned.get((x, y), ' '))59                row.append(assigned.get((x, y), ' '))
60            grid.append(''.join(row))60            grid.append(''.join(row))
61        return '\n'.join(grid)61        return '\n'.join(grid)
6262
63    @staticmethod63    @staticmethod
64    def spiral_coordinates(total):64    def spiral_coordinates(total):
65        x, y = (0, 0)65        x, y = (0, 0)
66        yield (x, y)66        yield (x, y)
67        if total == 1:67        if total == 1:
68            return68            return
69        steps = 169        steps = 1
70        directions = [(0, 1), (-1, 0), (0, -1), (1, 0)]70        directions = [(0, 1), (-1, 0), (0, -1), (1, 0)]
71        count = 171        count = 1
72        while count < total:72        while count < total:
73            for dx, dy in directions:73            for dx, dy in directions:
74                for i in range(steps):74                for i in range(steps):
75                    if count >= total:75                    if count >= total:
76                        return76                        return
77                    x += dx77                    x += dx
78                    y += dy78                    y += dy
79                    yield (x, y)79                    yield (x, y)
80                    count += 180                    count += 1
81                steps += 181                steps += 1
8282
83    @classmethod83    @classmethod
84    def from_groups(cls, groups):84    def from_groups(cls, groups):
85        instance = cls('')85        instance = cls('')
86        instance.groups = groups86        instance.groups = groups
87        return instance87        return instance
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op