Решение на Телефонна любов от Радостин Маринов

Обратно към всички решения

Към профила на Радостин Маринов

Резултати

  • 10 точки от тестове
  • 1 бонус точка
  • 11 точки общо
  • 36 успешни тест(а)
  • 1 неуспешни тест(а)

Код

from decimal import Decimal, ROUND_HALF_DOWN
letter_to_num = {
'a': (2, 1),
'b': (2, 2),
'c': (2, 3),
'd': (3, 1),
'e': (3, 2),
'f': (3, 3),
'g': (4, 1),
'h': (4, 2),
'i': (4, 3),
'j': (5, 1),
'k': (5, 2),
'l': (5, 3),
'm': (6, 1),
'n': (6, 2),
'o': (6, 3),
'p': (7, 1),
'q': (7, 2),
'r': (7, 3),
's': (7, 4),
't': (8, 1),
'u': (8, 2),
'v': (8, 3),
'w': (9, 1),
'x': (9, 2),
'y': (9, 3),
'z': (9, 4),
' ': (0, 1)
}
num_to_letter = dict((v, k) for k, v in letter_to_num.items())
number_to_angle = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
angle_to_number = dict((v, k) for k, v in number_to_angle.items())
def normalize_count(count, number):
if 1 <= number <= 6 or number == 8:
return ((count - 1) % 3) + 1
elif number == 7 or number == 9:
return ((count - 1) % 4) + 1
else:
return 1
def add_letter(count, number, result):
count = normalize_count(count, number)
value = num_to_letter.get((number, count))
if value is not None:
result += value
return result
def convert_number_to_angle(number):
return number_to_angle.get(number)
def convert_angle_to_number(angle):
return angle_to_number.get(angle)
def normalize_angle(angle):
angle %= 360
if angle < 0:
angle += 360
return angle
def round_to_closest_30(angle):
angle = normalize_angle(angle)
return Decimal(angle / 30).quantize(0, ROUND_HALF_DOWN) * 30
def nums_to_text(nums):
previous = -1
count = 0
result = ""
for num in nums:
if num == previous:
count += 1
else:
result = add_letter(count, previous, result)
count = 1
previous = num
result = add_letter(count, previous, result)
return result
def text_to_nums(text):
result = []
previous_number = -1
for letter in text.lower():
value = letter_to_num.get(letter)
if value is not None:
if previous_number == value[0]:
result.append(-1)
result.extend(value[0] for _ in range(value[1]))
previous_number = value[0]
return result
def nums_to_angle(nums):
angles = map(convert_number_to_angle, nums)
angles = filter(lambda x: x is not None, angles)
return sum(angles) % 360
def angles_to_nums(angles):
rounded_angles = map(round_to_closest_30, angles)
numbers = map(convert_angle_to_number, rounded_angles)
numbers = filter(lambda x: x is not None, numbers)
return list(numbers)
def is_phone_tastic(word):
numbers = text_to_nums(word)
angle = nums_to_angle(numbers)
return angle % len(word) == 0

Лог от изпълнението

..........E..........................
======================================================================
ERROR: test_empty_input (test.TestIsPhonetastic)
Test with empty input.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/storage/deedee/data/rails/pyfmi-2022/releases/20221020151654/lib/language/python/runner.py", line 67, in thread
    raise result
ZeroDivisionError: integer division or modulo by zero

----------------------------------------------------------------------
Ran 37 tests in 0.313s

FAILED (errors=1)

История (4 версии и 2 коментара)

Радостин обнови решението на 01.11.2022 21:18 (преди над 1 година)

+letter_to_num = {
+ 'a': (2, 1),
+ 'b': (2, 2),
+ 'c': (2, 3),
+ 'd': (3, 1),
+ 'e': (3, 2),
+ 'f': (3, 3),
+ 'g': (4, 1),
+ 'h': (4, 2),
+ 'i': (4, 3),
+ 'j': (5, 1),
+ 'k': (5, 2),
+ 'l': (5, 3),
+ 'm': (6, 1),
+ 'n': (6, 2),
+ 'o': (6, 3),
+ 'p': (7, 1),
+ 'q': (7, 2),
+ 'r': (7, 3),
+ 's': (7, 4),
+ 't': (8, 1),
+ 'u': (8, 2),
+ 'v': (8, 3),
+ 'w': (9, 1),
+ 'x': (9, 2),
+ 'y': (9, 3),
+ 'z': (9, 4),
+ ' ': (0, 1)
+}
+
+num_to_letter = dict((v, k) for k, v in letter_to_num.items())
+
+number_to_angle = {
+ 1: 30,
+ 2: 60,
+ 3: 90,
+ 4: 120,
+ 5: 150,
+ 6: 180,
+ 7: 210,
+ 8: 240,
+ 9: 270,
+ 0: 300,
+}
+
+angle_to_number = dict((v, k) for k, v in number_to_angle.items())
+
+
+def convert_number_to_angle(number):
+ return number_to_angle.get(number)
+
+
+def convert_angle_to_number(angle):
+ return angle_to_number.get(angle)
+
+
+def round_to_closest_30(angle):
+ return round(angle / 30) * 30
+
+
+def nums_to_text(nums):
+ previous = -1
+ count = 0
+ result = ""
+
+ for num in nums:
+ if num == previous:
+ count += 1
+ else:
+ if 1 <= previous <= 6 or previous == 8:
+ count = ((count - 1) % 3) + 1
+ elif previous == 7 or previous == 9:
+ count = ((count - 1) % 4) + 1
+ else:
+ count = 1
+
+ value = num_to_letter.get((previous, count))
+ if value is not None:
+ result += value
+
+ count = 1
+ previous = num
+
+ value = num_to_letter.get((previous, count))
+ if value is not None:
+ result += value
+
+ return result
+
+
+def text_to_nums(text):
+ result = []
+ previous_number = -1
+ for letter in text.lower():
+ value = letter_to_num.get(letter)
+ if value is not None:
+ if previous_number == value[0]:
+ result.append(-1)
+ result.extend(value[0] for _ in range(value[1]))
+ previous_number = value[0]
+
+ return result
+
+
+def nums_to_angle(nums):
+ angles = map(convert_number_to_angle, nums)
+ angles = filter(lambda x: x is not None, angles)
+ return sum(angles) % 360
+
+
+def angles_to_nums(angles):
+ rounded_angles = map(round_to_closest_30, angles)
+ return list(map(convert_angle_to_number, rounded_angles))
+
+
+def is_phone_tastic(word):
+ numbers = text_to_nums(word)
+ angle = nums_to_angle(numbers)
+ return angle % len(word) == 0

Радостин обнови решението на 01.11.2022 21:33 (преди над 1 година)

letter_to_num = {
'a': (2, 1),
'b': (2, 2),
'c': (2, 3),
'd': (3, 1),
'e': (3, 2),
'f': (3, 3),
'g': (4, 1),
'h': (4, 2),
'i': (4, 3),
'j': (5, 1),
'k': (5, 2),
'l': (5, 3),
'm': (6, 1),
'n': (6, 2),
'o': (6, 3),
'p': (7, 1),
'q': (7, 2),
'r': (7, 3),
's': (7, 4),
't': (8, 1),
'u': (8, 2),
'v': (8, 3),
'w': (9, 1),
'x': (9, 2),
'y': (9, 3),
'z': (9, 4),
' ': (0, 1)
}
num_to_letter = dict((v, k) for k, v in letter_to_num.items())
number_to_angle = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
angle_to_number = dict((v, k) for k, v in number_to_angle.items())
+def normalize_count(count, number):
+ if 1 <= number <= 6 or number == 8:
+ return ((count - 1) % 3) + 1
+ elif number == 7 or number == 9:
+ return ((count - 1) % 4) + 1
+ else:
+ return 1
+
+
+def add_letter(count, number, result):
+ value = num_to_letter.get((number, count))
+ if value is not None:
+ result += value
+ return result
+
+
def convert_number_to_angle(number):
return number_to_angle.get(number)
def convert_angle_to_number(angle):
return angle_to_number.get(angle)
def round_to_closest_30(angle):
return round(angle / 30) * 30
def nums_to_text(nums):
previous = -1
count = 0
result = ""
for num in nums:
if num == previous:
count += 1
else:
- if 1 <= previous <= 6 or previous == 8:
- count = ((count - 1) % 3) + 1
- elif previous == 7 or previous == 9:
- count = ((count - 1) % 4) + 1
- else:
- count = 1
-
- value = num_to_letter.get((previous, count))
- if value is not None:
- result += value
-
+ result = add_letter(normalize_count(count, previous), previous, result)
count = 1
previous = num
- value = num_to_letter.get((previous, count))
- if value is not None:
- result += value
+ result = add_letter(count, previous, result)
return result
def text_to_nums(text):
result = []
previous_number = -1
for letter in text.lower():
value = letter_to_num.get(letter)
if value is not None:
if previous_number == value[0]:
result.append(-1)
result.extend(value[0] for _ in range(value[1]))
previous_number = value[0]
return result
def nums_to_angle(nums):
angles = map(convert_number_to_angle, nums)
angles = filter(lambda x: x is not None, angles)
return sum(angles) % 360
def angles_to_nums(angles):
rounded_angles = map(round_to_closest_30, angles)
return list(map(convert_angle_to_number, rounded_angles))
def is_phone_tastic(word):
numbers = text_to_nums(word)
angle = nums_to_angle(numbers)
return angle % len(word) == 0

Радостин обнови решението на 01.11.2022 21:39 (преди над 1 година)

letter_to_num = {
'a': (2, 1),
'b': (2, 2),
'c': (2, 3),
'd': (3, 1),
'e': (3, 2),
'f': (3, 3),
'g': (4, 1),
'h': (4, 2),
'i': (4, 3),
'j': (5, 1),
'k': (5, 2),
'l': (5, 3),
'm': (6, 1),
'n': (6, 2),
'o': (6, 3),
'p': (7, 1),
'q': (7, 2),
'r': (7, 3),
's': (7, 4),
't': (8, 1),
'u': (8, 2),
'v': (8, 3),
'w': (9, 1),
'x': (9, 2),
'y': (9, 3),
'z': (9, 4),
' ': (0, 1)
}
num_to_letter = dict((v, k) for k, v in letter_to_num.items())
number_to_angle = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
angle_to_number = dict((v, k) for k, v in number_to_angle.items())
def normalize_count(count, number):
if 1 <= number <= 6 or number == 8:
return ((count - 1) % 3) + 1
elif number == 7 or number == 9:
return ((count - 1) % 4) + 1
else:
return 1
def add_letter(count, number, result):
+ count = normalize_count(count, number)
value = num_to_letter.get((number, count))
if value is not None:
result += value
return result
def convert_number_to_angle(number):
return number_to_angle.get(number)
def convert_angle_to_number(angle):
return angle_to_number.get(angle)
def round_to_closest_30(angle):
return round(angle / 30) * 30
def nums_to_text(nums):
previous = -1
count = 0
result = ""
for num in nums:
if num == previous:
count += 1
else:
- result = add_letter(normalize_count(count, previous), previous, result)
+ result = add_letter(count, previous, result)
count = 1
previous = num
result = add_letter(count, previous, result)
return result
def text_to_nums(text):
result = []
previous_number = -1
for letter in text.lower():
value = letter_to_num.get(letter)
if value is not None:
if previous_number == value[0]:
result.append(-1)
result.extend(value[0] for _ in range(value[1]))
previous_number = value[0]
return result
def nums_to_angle(nums):
angles = map(convert_number_to_angle, nums)
angles = filter(lambda x: x is not None, angles)
return sum(angles) % 360
def angles_to_nums(angles):
rounded_angles = map(round_to_closest_30, angles)
return list(map(convert_angle_to_number, rounded_angles))
def is_phone_tastic(word):
numbers = text_to_nums(word)
angle = nums_to_angle(numbers)
- return angle % len(word) == 0
+ return angle % len(word) == 0

Радостин обнови решението на 01.11.2022 22:54 (преди над 1 година)

+from decimal import Decimal, ROUND_HALF_DOWN
+
letter_to_num = {
'a': (2, 1),
'b': (2, 2),
'c': (2, 3),
'd': (3, 1),
'e': (3, 2),
'f': (3, 3),
'g': (4, 1),
'h': (4, 2),
'i': (4, 3),
'j': (5, 1),
'k': (5, 2),
'l': (5, 3),
'm': (6, 1),
'n': (6, 2),
'o': (6, 3),
'p': (7, 1),
'q': (7, 2),
'r': (7, 3),
's': (7, 4),
't': (8, 1),
'u': (8, 2),
'v': (8, 3),
'w': (9, 1),
'x': (9, 2),
'y': (9, 3),
'z': (9, 4),
' ': (0, 1)
}
num_to_letter = dict((v, k) for k, v in letter_to_num.items())
number_to_angle = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
angle_to_number = dict((v, k) for k, v in number_to_angle.items())
def normalize_count(count, number):
if 1 <= number <= 6 or number == 8:
return ((count - 1) % 3) + 1
elif number == 7 or number == 9:
return ((count - 1) % 4) + 1
else:
return 1
def add_letter(count, number, result):
count = normalize_count(count, number)
value = num_to_letter.get((number, count))
if value is not None:
result += value
return result
def convert_number_to_angle(number):
return number_to_angle.get(number)
def convert_angle_to_number(angle):
return angle_to_number.get(angle)
+def normalize_angle(angle):
+ angle %= 360
+ if angle < 0:
+ angle += 360
+ return angle
+
+
def round_to_closest_30(angle):
- return round(angle / 30) * 30
+ angle = normalize_angle(angle)
+ return Decimal(angle / 30).quantize(0, ROUND_HALF_DOWN) * 30
def nums_to_text(nums):
previous = -1
count = 0
result = ""
for num in nums:
if num == previous:
count += 1
else:
result = add_letter(count, previous, result)
count = 1
previous = num
result = add_letter(count, previous, result)
return result
def text_to_nums(text):
result = []
previous_number = -1
for letter in text.lower():
value = letter_to_num.get(letter)
if value is not None:
if previous_number == value[0]:
result.append(-1)
result.extend(value[0] for _ in range(value[1]))
previous_number = value[0]
return result
def nums_to_angle(nums):
angles = map(convert_number_to_angle, nums)
angles = filter(lambda x: x is not None, angles)
return sum(angles) % 360
def angles_to_nums(angles):
rounded_angles = map(round_to_closest_30, angles)
- return list(map(convert_angle_to_number, rounded_angles))
+ numbers = map(convert_angle_to_number, rounded_angles)
+ numbers = filter(lambda x: x is not None, numbers)
+ return list(numbers)
def is_phone_tastic(word):
numbers = text_to_nums(word)
angle = nums_to_angle(numbers)
- return angle % len(word) == 0
+ return angle % len(word) == 0

Нямам забележки, много изчистен стил, чудесна разбивка на функциите. Дори няма да се хвана за едноредовите такива, защото use-case-а е map, което някак оправдава дефинирането на функция, която просто е some_dict.get() (създава окей абстракция и го прави четимо).
Единственото, което прави впечатление са няколкото излишни празни реда в nums_to_text и text_to_nums. Кодът ти е четим и без тях. :)