Емилиан обнови решението на 29.10.2022 15:14 (преди над 2 години)
+# Task 1
+COMBINATION_TO_LETTER = {
+ (0, 1): " ",
+ (1, 1): "",
+ (2, 1): "A",
+ (2, 2): "B",
+ (2, 3): "C",
+ (3, 1): "D",
+ (3, 2): "E",
+ (3, 3): "F",
+ (4, 1): "G",
+ (4, 2): "H",
+ (4, 3): "I",
+ (5, 1): "J",
+ (5, 2): "K",
+ (5, 3): "L",
+ (6, 1): "M",
+ (6, 2): "N",
+ (6, 3): "O",
+ (7, 1): "P",
+ (7, 2): "Q",
+ (7, 3): "R",
+ (7, 4): "S",
+ (8, 1): "T",
+ (8, 2): "U",
+ (8, 3): "V",
+ (9, 1): "W",
+ (9, 2): "X",
+ (9, 3): "Y",
+ (9, 4): "Z",
+}
+
+NUMBER_TO_SIMPLIFIER = {
+ 0: lambda _: 1,
+ 1: lambda _: 1,
+ 2: lambda x: x % 4,
+ 3: lambda x: x % 4,
+ 4: lambda x: x % 4,
+ 5: lambda x: x % 4,
+ 6: lambda x: x % 4,
+ 7: lambda x: x % 5,
+ 8: lambda x: x % 4,
+ 9: lambda x: x % 5,
+}
+
+
+def simplify_clicks(number: int, clicks: int) -> int:
+ if number not in NUMBER_TO_SIMPLIFIER:
+ return -1
+ return NUMBER_TO_SIMPLIFIER[number](clicks)
+
+
+def get_letter(number: int, clicks: int) -> str:
+ combination = (number, clicks)
+ if combination not in COMBINATION_TO_LETTER:
+ return ""
+ return COMBINATION_TO_LETTER[combination]
+
+
+def add_letter(number: int, clicks: int, result: list[str]) -> str:
+ simplified_clicks = simplify_clicks(number, clicks)
+ letter = get_letter(number, simplified_clicks)
+ return result.append(letter)
+
+
+def nums_to_text(nums: list[int]) -> str:
+ curr_value = -1
+ clicks = -1
+ result = []
+ for number in nums:
+ if number != curr_value:
+ add_letter(curr_value, clicks, result)
+ curr_value = number
+ clicks = 0
+ clicks += 1
+ add_letter(curr_value, clicks, result)
+ return "".join(result)
+
+
+# Task 2
+def text_to_nums(raw_text: str) -> list[int]:
+ letter_to_combination = {v: k for k, v in COMBINATION_TO_LETTER.items()}
Бих направил това извън функцията, за да не се изпълява многократно.
+
+ text = raw_text.upper()
+ result = []
+ previous_number = -1
+ for letter in text:
+ if letter not in letter_to_combination:
+ continue
+
+ combination = letter_to_combination[letter]
+ if previous_number == combination[0]:
+ result.append(-1)
+
+ result.extend([combination[0]] * combination[1])
+ previous_number = combination[0]
+ return result
+
+
+# Task 3
+NUMBER_TO_ANGLE = {
+ 1: 30,
+ 2: 60,
+ 3: 90,
+ 4: 120,
+ 5: 150,
+ 6: 180,
+ 7: 210,
+ 8: 240,
+ 9: 270,
+ 0: 300,
+}
+
+
+def get_angle(number: int) -> int:
+ if number not in NUMBER_TO_ANGLE:
+ return 0
+ return NUMBER_TO_ANGLE[number]
+
+
+def nums_to_angle(nums: list[int]) -> int:
+ total_angle = sum([get_angle(number) for number in nums])
+ return total_angle % 360
+
+
+# Task 4
+RANGE_TO_ANGLE = {
Цитирам изискванията - "В случай на нужда от закръгляване, при която разликата нагоре и надолу е еднаква, закръгляваме надолу."
+ (0, 14): 0,
+ (15, 44): 30,
+ (45, 74): 60,
+ (75, 104): 90,
+ (105, 134): 120,
+ (135, 164): 150,
+ (165, 194): 180,
+ (195, 224): 210,
+ (225, 254): 240,
+ (255, 284): 270,
+ (285, 315): 300,
+ (345, 359): 0,
+}
+
+
+def get_exact_angle(angle: int) -> tuple[int, bool]:
+ for range, concrete_angle in RANGE_TO_ANGLE.items():
+ if angle >= range[0] and angle <= range[1]:
+ return concrete_angle, True
+ return -1, False
+
+
+def normalize_angle(angle: int) -> int:
+ angle %= 360
+ if angle < 0:
Чудя се дали има случай, в който да попаднеш в този if
, имайки предвид предишния ред. Не се сещам, но може и да греша.
+ angle += 360
+ return angle
+
+
+def angles_to_nums(angles: list[int]) -> list[int]:
+ angle_to_number = {v: k for k, v in NUMBER_TO_ANGLE.items()}
+ result = []
+ for angle in angles:
+ angle = normalize_angle(angle)
+ exact_angle, does_exact_angle_exist = get_exact_angle(angle)
+ if not does_exact_angle_exist:
+ continue
+
+ if exact_angle not in angle_to_number:
+ continue
+ number = angle_to_number[exact_angle]
+ result.append(number)
+ return result
+
+
+# Task 5
+def is_phone_tastic(raw_word: str) -> bool:
+ word = raw_word.upper()
+ numbers = text_to_nums(word)
+ angle = nums_to_angle(numbers)
+ return angle % len(word) == 0
+
+
+if __name__ == '__main__':
+ assert nums_to_text([4, 4, 3, 3, 5, 5, 5, -1, 5, 5, 5, 6, 6, 6]) == "HELLO"
+ assert nums_to_text([7, 9, 9, 9, 8, 4, 4, 6, 6, 6, -1, 6, 6]) == "PYTHON"
+ assert text_to_nums('asl pls') == \
+ [2, 7, 7, 7, 7, 5, 5, 5, 0, 7, 5, 5, 5, 7, 7, 7, 7]
+ assert text_to_nums('PYTHON') == \
+ [7, 9, 9, 9, 8, 4, 4, 6, 6, 6, -1, 6, 6]
+ assert nums_to_angle([1, 5, 9]) == 90
+ assert angles_to_nums([16, 14, 90, -120]) == [1, 3, 8]
+ assert is_phone_tastic('GOD') == True
letter_to_combination = {v: k for k, v in COMBINATION_TO_LETTER.items()} просто беше бързо и лесно решение. Съгласен съм, че е доста по-чисто, ако бъде извадено като константа. Другите два коментара мисля, че са предимно от недоглеждане. :D
Цитирам изискванията - "В случай на нужда от закръгляване, при която разликата нагоре и надолу е еднаква, закръгляваме надолу."