1import re
2from collections import OrderedDict
3from random import randint
4
5
6def class_method_naughty_decorator(func):
7 def wrapper(self, *args, **kwargs):
8 try:
9 res = func(self, *args, **kwargs)
10 return res
11 except:
12 self.is_naughty = True
13 raise
14 return wrapper
15
16def init_decorator(init_func):
17 def wrapper(self, *args, **kwargs):
18 if init_func:
19 init_func(self, *args, **kwargs)
20 self.is_naughty = False
21 self.age = 0
22 Santa.detect_new_kid(self)
23 return wrapper
24
25
26class SingletonMeta(type):
27
28 _all_instances = {}
29
30 def __call__(cls, *args, **kwargs):
31 if cls not in cls._all_instances:
32 instance = super().__call__(*args, **kwargs)
33 cls._all_instances[cls] = instance
34 return cls._all_instances[cls]
35
36
37class Kid(type):
38
39 def __new__(cls, name, bases, attr_dict):
40 if '__call__' not in attr_dict:
41 raise NotImplementedError("OK stands for OBICHAM KOCETO <3")
42
43 def age_up(self):
44 self.age += 1
45
46 def be_good(self):
47 self.is_naughty = False
48
49 original_init = attr_dict.get('__init__', None)
50
51 attr_dict['__init__'] = init_decorator(original_init)
52 attr_dict['age_up'] = age_up
53 attr_dict['be_good'] = be_good
54
55 for method_name, method in attr_dict.items():
56 if callable(method) and not method_name.startswith('_'):
57 attr_dict[method_name] = class_method_naughty_decorator(method)
58
59 return type.__new__(cls, name, bases, attr_dict)
60
61
62class Santa(metaclass=SingletonMeta):
63
64 _all_kids = {} # id -> instance
65 _gifts = OrderedDict() # id -> gift
66
67 @classmethod
68 def detect_new_kid(cls, kid):
69 cls._all_kids[id(kid)] = kid
70
71 @staticmethod
72 def _get_signature(wish):
73 target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE)
74 return target.group(1)
75
76 @staticmethod
77 def _get_gift(wish):
78 if res := re.search(r'"([A-Za-z0-9 ]+)"', wish):
79 return res.group(1)
80 elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish):
81 return res.group(1)
82
83 def __call__(self, child, call):
84 self._gifts[id(child)] = self._get_gift(call)
85
86 def __matmul__(self, letter):
87 signature = int(self._get_signature(letter))
88 self._gifts[signature] = self._get_gift(letter)
89
90 def __iter__(self):
91 return SantaIter(list(self._gifts.values()))
92
93 def _post_xmas(self):
94 """Age up all kids and make them well-behaved again"""
95
96 for kid in self._all_kids.values():
97 kid.age_up()
98 kid.be_good()
99
100 self._gifts.clear()
101
102 def _get_most_frequent_gifts(self):
103
104 freq_dict = {}
105
106 for gift in self._gifts.values():
107 if gift not in freq_dict:
108 freq_dict[gift] = 1
109 else:
110 freq_dict[gift] += 1
111
112 max_freq = max(freq_dict.values())
113
114 return [gift for gift, count in freq_dict.items() if count == max_freq]
115
116 def _give_gifts(self):
117 most_freq_gifts = self._get_most_frequent_gifts()
118
119 for kid_id, kid in self._all_kids.items():
120 if kid.age < 5:
121 if kid.is_naughty:
122 kid('coal')
123 elif kid_id in self._gifts.keys():
124 kid(self._gifts[kid_id])
125 else:
126 random_idx = randint(0, len(most_freq_gifts) - 1)
127 kid(most_freq_gifts[random_idx])
128
129 def xmas(self):
130 if self._gifts:
131 self._give_gifts()
132 self._post_xmas()
133
134
135class SantaIter:
136
137 def __init__(self, gifts):
138 self.gifts = gifts
139 self.idx = 0
140
141 def __iter__(self):
142 return self
143
144 def __next__(self):
145 if self.idx < len(self.gifts):
146 curr = self.gifts[self.idx]
147 self.idx += 1
148 return curr
149 else:
150 self.idx = 0
151 raise StopIteration
....................
----------------------------------------------------------------------
Ran 20 tests in 0.024s
OK
Ивайло Кънчев
19.12.2024 00:15Надявам се чудесата в метакласа да не счупят тестовете по някаква причина :D
|
| f | 1 | import re | f | 1 | import re |
| 2 | from collections import OrderedDict | 2 | from collections import OrderedDict | ||
| 3 | from random import randint | 3 | from random import randint | ||
| 4 | 4 | ||||
| n | n | 5 | |||
| 5 | def class_method_naughty_decorator(func): | 6 | def class_method_naughty_decorator(func): | ||
| 6 | def wrapper(self, *args, **kwargs): | 7 | def wrapper(self, *args, **kwargs): | ||
| 7 | try: | 8 | try: | ||
| n | 8 | ans = func(self, *args, **kwargs) | n | 9 | res = func(self, *args, **kwargs) |
| 9 | return ans | 10 | return res | ||
| 10 | except Exception: | 11 | except: | ||
| 11 | self.is_naughty = True | 12 | self.is_naughty = True | ||
| 12 | raise | 13 | raise | ||
| 13 | return wrapper | 14 | return wrapper | ||
| 14 | 15 | ||||
| 15 | def init_decorator(init_func): | 16 | def init_decorator(init_func): | ||
| 16 | def wrapper(self, *args, **kwargs): | 17 | def wrapper(self, *args, **kwargs): | ||
| 17 | if init_func: | 18 | if init_func: | ||
| 18 | init_func(self, *args, **kwargs) | 19 | init_func(self, *args, **kwargs) | ||
| 19 | self.is_naughty = False | 20 | self.is_naughty = False | ||
| 20 | self.age = 0 | 21 | self.age = 0 | ||
| 21 | Santa.detect_new_kid(self) | 22 | Santa.detect_new_kid(self) | ||
| 22 | return wrapper | 23 | return wrapper | ||
| 23 | 24 | ||||
| 24 | 25 | ||||
| 25 | class SingletonMeta(type): | 26 | class SingletonMeta(type): | ||
| 26 | 27 | ||||
| 27 | _all_instances = {} | 28 | _all_instances = {} | ||
| 28 | 29 | ||||
| 29 | def __call__(cls, *args, **kwargs): | 30 | def __call__(cls, *args, **kwargs): | ||
| 30 | if cls not in cls._all_instances: | 31 | if cls not in cls._all_instances: | ||
| 31 | instance = super().__call__(*args, **kwargs) | 32 | instance = super().__call__(*args, **kwargs) | ||
| 32 | cls._all_instances[cls] = instance | 33 | cls._all_instances[cls] = instance | ||
| 33 | return cls._all_instances[cls] | 34 | return cls._all_instances[cls] | ||
| 34 | 35 | ||||
| 35 | 36 | ||||
| 36 | class Kid(type): | 37 | class Kid(type): | ||
| 37 | 38 | ||||
| 38 | def __new__(cls, name, bases, attr_dict): | 39 | def __new__(cls, name, bases, attr_dict): | ||
| 39 | if '__call__' not in attr_dict: | 40 | if '__call__' not in attr_dict: | ||
| 40 | raise NotImplementedError("OK stands for OBICHAM KOCETO <3") | 41 | raise NotImplementedError("OK stands for OBICHAM KOCETO <3") | ||
| 41 | 42 | ||||
| 42 | def age_up(self): | 43 | def age_up(self): | ||
| 43 | self.age += 1 | 44 | self.age += 1 | ||
| 44 | 45 | ||||
| 45 | def be_good(self): | 46 | def be_good(self): | ||
| 46 | self.is_naughty = False | 47 | self.is_naughty = False | ||
| 47 | 48 | ||||
| 48 | original_init = attr_dict.get('__init__', None) | 49 | original_init = attr_dict.get('__init__', None) | ||
| 49 | 50 | ||||
| 50 | attr_dict['__init__'] = init_decorator(original_init) | 51 | attr_dict['__init__'] = init_decorator(original_init) | ||
| 51 | attr_dict['age_up'] = age_up | 52 | attr_dict['age_up'] = age_up | ||
| 52 | attr_dict['be_good'] = be_good | 53 | attr_dict['be_good'] = be_good | ||
| 53 | 54 | ||||
| 54 | for method_name, method in attr_dict.items(): | 55 | for method_name, method in attr_dict.items(): | ||
| n | 55 | if callable(method) and not method_name.startswith('_') and not method_name.startswith('__'): | n | 56 | if callable(method) and not method_name.startswith('_'): |
| 56 | attr_dict[method_name] = class_method_naughty_decorator(method) | 57 | attr_dict[method_name] = class_method_naughty_decorator(method) | ||
| 57 | 58 | ||||
| 58 | return type.__new__(cls, name, bases, attr_dict) | 59 | return type.__new__(cls, name, bases, attr_dict) | ||
| 59 | 60 | ||||
| 60 | 61 | ||||
| 61 | class Santa(metaclass=SingletonMeta): | 62 | class Santa(metaclass=SingletonMeta): | ||
| 62 | 63 | ||||
| 63 | _all_kids = {} # id -> instance | 64 | _all_kids = {} # id -> instance | ||
| 64 | _gifts = OrderedDict() # id -> gift | 65 | _gifts = OrderedDict() # id -> gift | ||
| 65 | 66 | ||||
| 66 | @classmethod | 67 | @classmethod | ||
| 67 | def detect_new_kid(cls, kid): | 68 | def detect_new_kid(cls, kid): | ||
| 68 | cls._all_kids[id(kid)] = kid | 69 | cls._all_kids[id(kid)] = kid | ||
| 69 | 70 | ||||
| 70 | @staticmethod | 71 | @staticmethod | ||
| 71 | def _get_signature(wish): | 72 | def _get_signature(wish): | ||
| 72 | target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE) | 73 | target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE) | ||
| 73 | return target.group(1) | 74 | return target.group(1) | ||
| 74 | 75 | ||||
| 75 | @staticmethod | 76 | @staticmethod | ||
| 76 | def _get_gift(wish): | 77 | def _get_gift(wish): | ||
| 77 | if res := re.search(r'"([A-Za-z0-9 ]+)"', wish): | 78 | if res := re.search(r'"([A-Za-z0-9 ]+)"', wish): | ||
| 78 | return res.group(1) | 79 | return res.group(1) | ||
| 79 | elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish): | 80 | elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish): | ||
| 80 | return res.group(1) | 81 | return res.group(1) | ||
| 81 | 82 | ||||
| 82 | def __call__(self, child, call): | 83 | def __call__(self, child, call): | ||
| 83 | self._gifts[id(child)] = self._get_gift(call) | 84 | self._gifts[id(child)] = self._get_gift(call) | ||
| 84 | 85 | ||||
| 85 | def __matmul__(self, letter): | 86 | def __matmul__(self, letter): | ||
| 86 | signature = int(self._get_signature(letter)) | 87 | signature = int(self._get_signature(letter)) | ||
| 87 | self._gifts[signature] = self._get_gift(letter) | 88 | self._gifts[signature] = self._get_gift(letter) | ||
| 88 | 89 | ||||
| 89 | def __iter__(self): | 90 | def __iter__(self): | ||
| 90 | return SantaIter(list(self._gifts.values())) | 91 | return SantaIter(list(self._gifts.values())) | ||
| 91 | 92 | ||||
| 92 | def _post_xmas(self): | 93 | def _post_xmas(self): | ||
| 93 | """Age up all kids and make them well-behaved again""" | 94 | """Age up all kids and make them well-behaved again""" | ||
| 94 | 95 | ||||
| 95 | for kid in self._all_kids.values(): | 96 | for kid in self._all_kids.values(): | ||
| 96 | kid.age_up() | 97 | kid.age_up() | ||
| 97 | kid.be_good() | 98 | kid.be_good() | ||
| 98 | 99 | ||||
| 99 | self._gifts.clear() | 100 | self._gifts.clear() | ||
| 100 | 101 | ||||
| 101 | def _get_most_frequent_gifts(self): | 102 | def _get_most_frequent_gifts(self): | ||
| 102 | 103 | ||||
| 103 | freq_dict = {} | 104 | freq_dict = {} | ||
| n | 104 | most_freq_gifts = [] | n | ||
| 105 | 105 | ||||
| 106 | for gift in self._gifts.values(): | 106 | for gift in self._gifts.values(): | ||
| 107 | if gift not in freq_dict: | 107 | if gift not in freq_dict: | ||
| 108 | freq_dict[gift] = 1 | 108 | freq_dict[gift] = 1 | ||
| 109 | else: | 109 | else: | ||
| 110 | freq_dict[gift] += 1 | 110 | freq_dict[gift] += 1 | ||
| 111 | 111 | ||||
| 112 | max_freq = max(freq_dict.values()) | 112 | max_freq = max(freq_dict.values()) | ||
| 113 | 113 | ||||
| n | 114 | for gift, freq in freq_dict.items(): | n | 114 | return [gift for gift, count in freq_dict.items() if count == max_freq] |
| 115 | if freq == max_freq: | ||||
| 116 | most_freq_gifts.append(gift) | ||||
| 117 | |||||
| 118 | return most_freq_gifts | ||||
| 119 | 115 | ||||
| 120 | def _give_gifts(self): | 116 | def _give_gifts(self): | ||
| 121 | most_freq_gifts = self._get_most_frequent_gifts() | 117 | most_freq_gifts = self._get_most_frequent_gifts() | ||
| 122 | 118 | ||||
| 123 | for kid_id, kid in self._all_kids.items(): | 119 | for kid_id, kid in self._all_kids.items(): | ||
| 124 | if kid.age < 5: | 120 | if kid.age < 5: | ||
| 125 | if kid.is_naughty: | 121 | if kid.is_naughty: | ||
| 126 | kid('coal') | 122 | kid('coal') | ||
| 127 | elif kid_id in self._gifts.keys(): | 123 | elif kid_id in self._gifts.keys(): | ||
| 128 | kid(self._gifts[kid_id]) | 124 | kid(self._gifts[kid_id]) | ||
| 129 | else: | 125 | else: | ||
| 130 | random_idx = randint(0, len(most_freq_gifts) - 1) | 126 | random_idx = randint(0, len(most_freq_gifts) - 1) | ||
| 131 | kid(most_freq_gifts[random_idx]) | 127 | kid(most_freq_gifts[random_idx]) | ||
| 132 | 128 | ||||
| 133 | def xmas(self): | 129 | def xmas(self): | ||
| 134 | if self._gifts: | 130 | if self._gifts: | ||
| 135 | self._give_gifts() | 131 | self._give_gifts() | ||
| 136 | self._post_xmas() | 132 | self._post_xmas() | ||
| 137 | 133 | ||||
| 138 | 134 | ||||
| 139 | class SantaIter: | 135 | class SantaIter: | ||
| 140 | 136 | ||||
| 141 | def __init__(self, gifts): | 137 | def __init__(self, gifts): | ||
| 142 | self.gifts = gifts | 138 | self.gifts = gifts | ||
| 143 | self.idx = 0 | 139 | self.idx = 0 | ||
| 144 | 140 | ||||
| 145 | def __iter__(self): | 141 | def __iter__(self): | ||
| 146 | return self | 142 | return self | ||
| 147 | 143 | ||||
| 148 | def __next__(self): | 144 | def __next__(self): | ||
| 149 | if self.idx < len(self.gifts): | 145 | if self.idx < len(self.gifts): | ||
| 150 | curr = self.gifts[self.idx] | 146 | curr = self.gifts[self.idx] | ||
| 151 | self.idx += 1 | 147 | self.idx += 1 | ||
| 152 | return curr | 148 | return curr | ||
| 153 | else: | 149 | else: | ||
| 154 | self.idx = 0 | 150 | self.idx = 0 | ||
| 155 | raise StopIteration | 151 | raise StopIteration | ||
| t | 156 | t |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import re | f | 1 | import re |
| 2 | from collections import OrderedDict | 2 | from collections import OrderedDict | ||
| 3 | from random import randint | 3 | from random import randint | ||
| 4 | 4 | ||||
| 5 | def class_method_naughty_decorator(func): | 5 | def class_method_naughty_decorator(func): | ||
| 6 | def wrapper(self, *args, **kwargs): | 6 | def wrapper(self, *args, **kwargs): | ||
| 7 | try: | 7 | try: | ||
| 8 | ans = func(self, *args, **kwargs) | 8 | ans = func(self, *args, **kwargs) | ||
| 9 | return ans | 9 | return ans | ||
| 10 | except Exception: | 10 | except Exception: | ||
| 11 | self.is_naughty = True | 11 | self.is_naughty = True | ||
| 12 | raise | 12 | raise | ||
| 13 | return wrapper | 13 | return wrapper | ||
| 14 | 14 | ||||
| 15 | def init_decorator(init_func): | 15 | def init_decorator(init_func): | ||
| 16 | def wrapper(self, *args, **kwargs): | 16 | def wrapper(self, *args, **kwargs): | ||
| 17 | if init_func: | 17 | if init_func: | ||
| 18 | init_func(self, *args, **kwargs) | 18 | init_func(self, *args, **kwargs) | ||
| 19 | self.is_naughty = False | 19 | self.is_naughty = False | ||
| n | 20 | self.age = 1 | n | 20 | self.age = 0 |
| 21 | Santa.detect_new_kid(self) | 21 | Santa.detect_new_kid(self) | ||
| 22 | return wrapper | 22 | return wrapper | ||
| 23 | 23 | ||||
| 24 | 24 | ||||
| 25 | class SingletonMeta(type): | 25 | class SingletonMeta(type): | ||
| 26 | 26 | ||||
| 27 | _all_instances = {} | 27 | _all_instances = {} | ||
| 28 | 28 | ||||
| 29 | def __call__(cls, *args, **kwargs): | 29 | def __call__(cls, *args, **kwargs): | ||
| 30 | if cls not in cls._all_instances: | 30 | if cls not in cls._all_instances: | ||
| 31 | instance = super().__call__(*args, **kwargs) | 31 | instance = super().__call__(*args, **kwargs) | ||
| 32 | cls._all_instances[cls] = instance | 32 | cls._all_instances[cls] = instance | ||
| 33 | return cls._all_instances[cls] | 33 | return cls._all_instances[cls] | ||
| 34 | 34 | ||||
| 35 | 35 | ||||
| 36 | class Kid(type): | 36 | class Kid(type): | ||
| 37 | 37 | ||||
| 38 | def __new__(cls, name, bases, attr_dict): | 38 | def __new__(cls, name, bases, attr_dict): | ||
| 39 | if '__call__' not in attr_dict: | 39 | if '__call__' not in attr_dict: | ||
| 40 | raise NotImplementedError("OK stands for OBICHAM KOCETO <3") | 40 | raise NotImplementedError("OK stands for OBICHAM KOCETO <3") | ||
| 41 | 41 | ||||
| 42 | def age_up(self): | 42 | def age_up(self): | ||
| 43 | self.age += 1 | 43 | self.age += 1 | ||
| 44 | 44 | ||||
| 45 | def be_good(self): | 45 | def be_good(self): | ||
| 46 | self.is_naughty = False | 46 | self.is_naughty = False | ||
| 47 | 47 | ||||
| 48 | original_init = attr_dict.get('__init__', None) | 48 | original_init = attr_dict.get('__init__', None) | ||
| 49 | 49 | ||||
| 50 | attr_dict['__init__'] = init_decorator(original_init) | 50 | attr_dict['__init__'] = init_decorator(original_init) | ||
| 51 | attr_dict['age_up'] = age_up | 51 | attr_dict['age_up'] = age_up | ||
| 52 | attr_dict['be_good'] = be_good | 52 | attr_dict['be_good'] = be_good | ||
| 53 | 53 | ||||
| 54 | for method_name, method in attr_dict.items(): | 54 | for method_name, method in attr_dict.items(): | ||
| 55 | if callable(method) and not method_name.startswith('_') and not method_name.startswith('__'): | 55 | if callable(method) and not method_name.startswith('_') and not method_name.startswith('__'): | ||
| 56 | attr_dict[method_name] = class_method_naughty_decorator(method) | 56 | attr_dict[method_name] = class_method_naughty_decorator(method) | ||
| 57 | 57 | ||||
| 58 | return type.__new__(cls, name, bases, attr_dict) | 58 | return type.__new__(cls, name, bases, attr_dict) | ||
| 59 | 59 | ||||
| 60 | 60 | ||||
| 61 | class Santa(metaclass=SingletonMeta): | 61 | class Santa(metaclass=SingletonMeta): | ||
| 62 | 62 | ||||
| 63 | _all_kids = {} # id -> instance | 63 | _all_kids = {} # id -> instance | ||
| 64 | _gifts = OrderedDict() # id -> gift | 64 | _gifts = OrderedDict() # id -> gift | ||
| 65 | 65 | ||||
| 66 | @classmethod | 66 | @classmethod | ||
| 67 | def detect_new_kid(cls, kid): | 67 | def detect_new_kid(cls, kid): | ||
| 68 | cls._all_kids[id(kid)] = kid | 68 | cls._all_kids[id(kid)] = kid | ||
| 69 | 69 | ||||
| 70 | @staticmethod | 70 | @staticmethod | ||
| 71 | def _get_signature(wish): | 71 | def _get_signature(wish): | ||
| 72 | target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE) | 72 | target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE) | ||
| 73 | return target.group(1) | 73 | return target.group(1) | ||
| 74 | 74 | ||||
| 75 | @staticmethod | 75 | @staticmethod | ||
| 76 | def _get_gift(wish): | 76 | def _get_gift(wish): | ||
| 77 | if res := re.search(r'"([A-Za-z0-9 ]+)"', wish): | 77 | if res := re.search(r'"([A-Za-z0-9 ]+)"', wish): | ||
| 78 | return res.group(1) | 78 | return res.group(1) | ||
| 79 | elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish): | 79 | elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish): | ||
| 80 | return res.group(1) | 80 | return res.group(1) | ||
| 81 | 81 | ||||
| 82 | def __call__(self, child, call): | 82 | def __call__(self, child, call): | ||
| 83 | self._gifts[id(child)] = self._get_gift(call) | 83 | self._gifts[id(child)] = self._get_gift(call) | ||
| 84 | 84 | ||||
| 85 | def __matmul__(self, letter): | 85 | def __matmul__(self, letter): | ||
| 86 | signature = int(self._get_signature(letter)) | 86 | signature = int(self._get_signature(letter)) | ||
| 87 | self._gifts[signature] = self._get_gift(letter) | 87 | self._gifts[signature] = self._get_gift(letter) | ||
| 88 | 88 | ||||
| 89 | def __iter__(self): | 89 | def __iter__(self): | ||
| 90 | return SantaIter(list(self._gifts.values())) | 90 | return SantaIter(list(self._gifts.values())) | ||
| 91 | 91 | ||||
| 92 | def _post_xmas(self): | 92 | def _post_xmas(self): | ||
| 93 | """Age up all kids and make them well-behaved again""" | 93 | """Age up all kids and make them well-behaved again""" | ||
| 94 | 94 | ||||
| 95 | for kid in self._all_kids.values(): | 95 | for kid in self._all_kids.values(): | ||
| 96 | kid.age_up() | 96 | kid.age_up() | ||
| 97 | kid.be_good() | 97 | kid.be_good() | ||
| 98 | 98 | ||||
| 99 | self._gifts.clear() | 99 | self._gifts.clear() | ||
| 100 | 100 | ||||
| 101 | def _get_most_frequent_gifts(self): | 101 | def _get_most_frequent_gifts(self): | ||
| 102 | 102 | ||||
| 103 | freq_dict = {} | 103 | freq_dict = {} | ||
| 104 | most_freq_gifts = [] | 104 | most_freq_gifts = [] | ||
| 105 | 105 | ||||
| 106 | for gift in self._gifts.values(): | 106 | for gift in self._gifts.values(): | ||
| 107 | if gift not in freq_dict: | 107 | if gift not in freq_dict: | ||
| 108 | freq_dict[gift] = 1 | 108 | freq_dict[gift] = 1 | ||
| 109 | else: | 109 | else: | ||
| 110 | freq_dict[gift] += 1 | 110 | freq_dict[gift] += 1 | ||
| 111 | 111 | ||||
| 112 | max_freq = max(freq_dict.values()) | 112 | max_freq = max(freq_dict.values()) | ||
| 113 | 113 | ||||
| 114 | for gift, freq in freq_dict.items(): | 114 | for gift, freq in freq_dict.items(): | ||
| 115 | if freq == max_freq: | 115 | if freq == max_freq: | ||
| 116 | most_freq_gifts.append(gift) | 116 | most_freq_gifts.append(gift) | ||
| 117 | 117 | ||||
| 118 | return most_freq_gifts | 118 | return most_freq_gifts | ||
| 119 | 119 | ||||
| 120 | def _give_gifts(self): | 120 | def _give_gifts(self): | ||
| 121 | most_freq_gifts = self._get_most_frequent_gifts() | 121 | most_freq_gifts = self._get_most_frequent_gifts() | ||
| 122 | 122 | ||||
| 123 | for kid_id, kid in self._all_kids.items(): | 123 | for kid_id, kid in self._all_kids.items(): | ||
| t | 124 | if kid.age <= 5: | t | 124 | if kid.age < 5: |
| 125 | if kid.is_naughty: | 125 | if kid.is_naughty: | ||
| 126 | kid('coal') | 126 | kid('coal') | ||
| 127 | elif kid_id in self._gifts.keys(): | 127 | elif kid_id in self._gifts.keys(): | ||
| 128 | kid(self._gifts[kid_id]) | 128 | kid(self._gifts[kid_id]) | ||
| 129 | else: | 129 | else: | ||
| 130 | random_idx = randint(0, len(most_freq_gifts) - 1) | 130 | random_idx = randint(0, len(most_freq_gifts) - 1) | ||
| 131 | kid(most_freq_gifts[random_idx]) | 131 | kid(most_freq_gifts[random_idx]) | ||
| 132 | 132 | ||||
| 133 | def xmas(self): | 133 | def xmas(self): | ||
| 134 | if self._gifts: | 134 | if self._gifts: | ||
| 135 | self._give_gifts() | 135 | self._give_gifts() | ||
| 136 | self._post_xmas() | 136 | self._post_xmas() | ||
| 137 | 137 | ||||
| 138 | 138 | ||||
| 139 | class SantaIter: | 139 | class SantaIter: | ||
| 140 | 140 | ||||
| 141 | def __init__(self, gifts): | 141 | def __init__(self, gifts): | ||
| 142 | self.gifts = gifts | 142 | self.gifts = gifts | ||
| 143 | self.idx = 0 | 143 | self.idx = 0 | ||
| 144 | 144 | ||||
| 145 | def __iter__(self): | 145 | def __iter__(self): | ||
| 146 | return self | 146 | return self | ||
| 147 | 147 | ||||
| 148 | def __next__(self): | 148 | def __next__(self): | ||
| 149 | if self.idx < len(self.gifts): | 149 | if self.idx < len(self.gifts): | ||
| 150 | curr = self.gifts[self.idx] | 150 | curr = self.gifts[self.idx] | ||
| 151 | self.idx += 1 | 151 | self.idx += 1 | ||
| 152 | return curr | 152 | return curr | ||
| 153 | else: | 153 | else: | ||
| 154 | self.idx = 0 | 154 | self.idx = 0 | ||
| 155 | raise StopIteration | 155 | raise StopIteration | ||
| 156 | 156 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import re | f | 1 | import re |
| 2 | from collections import OrderedDict | 2 | from collections import OrderedDict | ||
| 3 | from random import randint | 3 | from random import randint | ||
| 4 | 4 | ||||
| 5 | def class_method_naughty_decorator(func): | 5 | def class_method_naughty_decorator(func): | ||
| 6 | def wrapper(self, *args, **kwargs): | 6 | def wrapper(self, *args, **kwargs): | ||
| 7 | try: | 7 | try: | ||
| 8 | ans = func(self, *args, **kwargs) | 8 | ans = func(self, *args, **kwargs) | ||
| 9 | return ans | 9 | return ans | ||
| 10 | except Exception: | 10 | except Exception: | ||
| 11 | self.is_naughty = True | 11 | self.is_naughty = True | ||
| 12 | raise | 12 | raise | ||
| 13 | return wrapper | 13 | return wrapper | ||
| 14 | 14 | ||||
| 15 | def init_decorator(init_func): | 15 | def init_decorator(init_func): | ||
| 16 | def wrapper(self, *args, **kwargs): | 16 | def wrapper(self, *args, **kwargs): | ||
| 17 | if init_func: | 17 | if init_func: | ||
| 18 | init_func(self, *args, **kwargs) | 18 | init_func(self, *args, **kwargs) | ||
| 19 | self.is_naughty = False | 19 | self.is_naughty = False | ||
| 20 | self.age = 1 | 20 | self.age = 1 | ||
| 21 | Santa.detect_new_kid(self) | 21 | Santa.detect_new_kid(self) | ||
| 22 | return wrapper | 22 | return wrapper | ||
| 23 | 23 | ||||
| 24 | 24 | ||||
| 25 | class SingletonMeta(type): | 25 | class SingletonMeta(type): | ||
| 26 | 26 | ||||
| 27 | _all_instances = {} | 27 | _all_instances = {} | ||
| 28 | 28 | ||||
| 29 | def __call__(cls, *args, **kwargs): | 29 | def __call__(cls, *args, **kwargs): | ||
| 30 | if cls not in cls._all_instances: | 30 | if cls not in cls._all_instances: | ||
| 31 | instance = super().__call__(*args, **kwargs) | 31 | instance = super().__call__(*args, **kwargs) | ||
| 32 | cls._all_instances[cls] = instance | 32 | cls._all_instances[cls] = instance | ||
| 33 | return cls._all_instances[cls] | 33 | return cls._all_instances[cls] | ||
| 34 | 34 | ||||
| 35 | 35 | ||||
| 36 | class Kid(type): | 36 | class Kid(type): | ||
| 37 | 37 | ||||
| 38 | def __new__(cls, name, bases, attr_dict): | 38 | def __new__(cls, name, bases, attr_dict): | ||
| 39 | if '__call__' not in attr_dict: | 39 | if '__call__' not in attr_dict: | ||
| 40 | raise NotImplementedError("OK stands for OBICHAM KOCETO <3") | 40 | raise NotImplementedError("OK stands for OBICHAM KOCETO <3") | ||
| 41 | 41 | ||||
| 42 | def age_up(self): | 42 | def age_up(self): | ||
| 43 | self.age += 1 | 43 | self.age += 1 | ||
| 44 | 44 | ||||
| 45 | def be_good(self): | 45 | def be_good(self): | ||
| 46 | self.is_naughty = False | 46 | self.is_naughty = False | ||
| 47 | 47 | ||||
| 48 | original_init = attr_dict.get('__init__', None) | 48 | original_init = attr_dict.get('__init__', None) | ||
| 49 | 49 | ||||
| 50 | attr_dict['__init__'] = init_decorator(original_init) | 50 | attr_dict['__init__'] = init_decorator(original_init) | ||
| 51 | attr_dict['age_up'] = age_up | 51 | attr_dict['age_up'] = age_up | ||
| 52 | attr_dict['be_good'] = be_good | 52 | attr_dict['be_good'] = be_good | ||
| 53 | 53 | ||||
| 54 | for method_name, method in attr_dict.items(): | 54 | for method_name, method in attr_dict.items(): | ||
| 55 | if callable(method) and not method_name.startswith('_') and not method_name.startswith('__'): | 55 | if callable(method) and not method_name.startswith('_') and not method_name.startswith('__'): | ||
| 56 | attr_dict[method_name] = class_method_naughty_decorator(method) | 56 | attr_dict[method_name] = class_method_naughty_decorator(method) | ||
| 57 | 57 | ||||
| 58 | return type.__new__(cls, name, bases, attr_dict) | 58 | return type.__new__(cls, name, bases, attr_dict) | ||
| 59 | 59 | ||||
| 60 | 60 | ||||
| 61 | class Santa(metaclass=SingletonMeta): | 61 | class Santa(metaclass=SingletonMeta): | ||
| 62 | 62 | ||||
| 63 | _all_kids = {} # id -> instance | 63 | _all_kids = {} # id -> instance | ||
| 64 | _gifts = OrderedDict() # id -> gift | 64 | _gifts = OrderedDict() # id -> gift | ||
| 65 | 65 | ||||
| 66 | @classmethod | 66 | @classmethod | ||
| 67 | def detect_new_kid(cls, kid): | 67 | def detect_new_kid(cls, kid): | ||
| 68 | cls._all_kids[id(kid)] = kid | 68 | cls._all_kids[id(kid)] = kid | ||
| 69 | 69 | ||||
| 70 | @staticmethod | 70 | @staticmethod | ||
| 71 | def _get_signature(wish): | 71 | def _get_signature(wish): | ||
| 72 | target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE) | 72 | target = re.search(r'^\s*(\d+)\s*$', wish, re.MULTILINE) | ||
| 73 | return target.group(1) | 73 | return target.group(1) | ||
| 74 | 74 | ||||
| 75 | @staticmethod | 75 | @staticmethod | ||
| 76 | def _get_gift(wish): | 76 | def _get_gift(wish): | ||
| 77 | if res := re.search(r'"([A-Za-z0-9 ]+)"', wish): | 77 | if res := re.search(r'"([A-Za-z0-9 ]+)"', wish): | ||
| 78 | return res.group(1) | 78 | return res.group(1) | ||
| 79 | elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish): | 79 | elif res := re.search(r'\'([A-Za-z0-9 ]+)\'', wish): | ||
| 80 | return res.group(1) | 80 | return res.group(1) | ||
| 81 | 81 | ||||
| 82 | def __call__(self, child, call): | 82 | def __call__(self, child, call): | ||
| 83 | self._gifts[id(child)] = self._get_gift(call) | 83 | self._gifts[id(child)] = self._get_gift(call) | ||
| 84 | 84 | ||||
| 85 | def __matmul__(self, letter): | 85 | def __matmul__(self, letter): | ||
| 86 | signature = int(self._get_signature(letter)) | 86 | signature = int(self._get_signature(letter)) | ||
| 87 | self._gifts[signature] = self._get_gift(letter) | 87 | self._gifts[signature] = self._get_gift(letter) | ||
| 88 | 88 | ||||
| 89 | def __iter__(self): | 89 | def __iter__(self): | ||
| 90 | return SantaIter(list(self._gifts.values())) | 90 | return SantaIter(list(self._gifts.values())) | ||
| 91 | 91 | ||||
| 92 | def _post_xmas(self): | 92 | def _post_xmas(self): | ||
| 93 | """Age up all kids and make them well-behaved again""" | 93 | """Age up all kids and make them well-behaved again""" | ||
| 94 | 94 | ||||
| 95 | for kid in self._all_kids.values(): | 95 | for kid in self._all_kids.values(): | ||
| 96 | kid.age_up() | 96 | kid.age_up() | ||
| 97 | kid.be_good() | 97 | kid.be_good() | ||
| 98 | 98 | ||||
| 99 | self._gifts.clear() | 99 | self._gifts.clear() | ||
| 100 | 100 | ||||
| 101 | def _get_most_frequent_gifts(self): | 101 | def _get_most_frequent_gifts(self): | ||
| 102 | 102 | ||||
| 103 | freq_dict = {} | 103 | freq_dict = {} | ||
| 104 | most_freq_gifts = [] | 104 | most_freq_gifts = [] | ||
| 105 | 105 | ||||
| 106 | for gift in self._gifts.values(): | 106 | for gift in self._gifts.values(): | ||
| 107 | if gift not in freq_dict: | 107 | if gift not in freq_dict: | ||
| 108 | freq_dict[gift] = 1 | 108 | freq_dict[gift] = 1 | ||
| 109 | else: | 109 | else: | ||
| 110 | freq_dict[gift] += 1 | 110 | freq_dict[gift] += 1 | ||
| 111 | 111 | ||||
| 112 | max_freq = max(freq_dict.values()) | 112 | max_freq = max(freq_dict.values()) | ||
| 113 | 113 | ||||
| 114 | for gift, freq in freq_dict.items(): | 114 | for gift, freq in freq_dict.items(): | ||
| 115 | if freq == max_freq: | 115 | if freq == max_freq: | ||
| 116 | most_freq_gifts.append(gift) | 116 | most_freq_gifts.append(gift) | ||
| 117 | 117 | ||||
| 118 | return most_freq_gifts | 118 | return most_freq_gifts | ||
| 119 | 119 | ||||
| 120 | def _give_gifts(self): | 120 | def _give_gifts(self): | ||
| 121 | most_freq_gifts = self._get_most_frequent_gifts() | 121 | most_freq_gifts = self._get_most_frequent_gifts() | ||
| 122 | 122 | ||||
| 123 | for kid_id, kid in self._all_kids.items(): | 123 | for kid_id, kid in self._all_kids.items(): | ||
| 124 | if kid.age <= 5: | 124 | if kid.age <= 5: | ||
| 125 | if kid.is_naughty: | 125 | if kid.is_naughty: | ||
| 126 | kid('coal') | 126 | kid('coal') | ||
| 127 | elif kid_id in self._gifts.keys(): | 127 | elif kid_id in self._gifts.keys(): | ||
| 128 | kid(self._gifts[kid_id]) | 128 | kid(self._gifts[kid_id]) | ||
| 129 | else: | 129 | else: | ||
| 130 | random_idx = randint(0, len(most_freq_gifts) - 1) | 130 | random_idx = randint(0, len(most_freq_gifts) - 1) | ||
| 131 | kid(most_freq_gifts[random_idx]) | 131 | kid(most_freq_gifts[random_idx]) | ||
| 132 | 132 | ||||
| 133 | def xmas(self): | 133 | def xmas(self): | ||
| 134 | if self._gifts: | 134 | if self._gifts: | ||
| 135 | self._give_gifts() | 135 | self._give_gifts() | ||
| 136 | self._post_xmas() | 136 | self._post_xmas() | ||
| 137 | 137 | ||||
| 138 | 138 | ||||
| 139 | class SantaIter: | 139 | class SantaIter: | ||
| 140 | 140 | ||||
| 141 | def __init__(self, gifts): | 141 | def __init__(self, gifts): | ||
| 142 | self.gifts = gifts | 142 | self.gifts = gifts | ||
| 143 | self.idx = 0 | 143 | self.idx = 0 | ||
| 144 | 144 | ||||
| n | n | 145 | def __iter__(self): | ||
| 146 | return self | ||||
| 147 | |||||
| 145 | def __next__(self): | 148 | def __next__(self): | ||
| 146 | if self.idx < len(self.gifts): | 149 | if self.idx < len(self.gifts): | ||
| 147 | curr = self.gifts[self.idx] | 150 | curr = self.gifts[self.idx] | ||
| 148 | self.idx += 1 | 151 | self.idx += 1 | ||
| 149 | return curr | 152 | return curr | ||
| 150 | else: | 153 | else: | ||
| t | t | 154 | self.idx = 0 | ||
| 151 | raise StopIteration | 155 | raise StopIteration | ||
| 152 | 156 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
20.12.2024 17:06