Решение на Телефонна любов от Александър Стоилов

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

Към профила на Александър Стоилов

Резултати

  • 9 точки от тестове
  • 0 бонус точки
  • 9 точки общо
  • 35 успешни тест(а)
  • 2 неуспешни тест(а)

Код

from typing import List
DIGIT_ROTATION_RANGE = {
-1: 1,
0: 1,
1: 1,
2: 3,
3: 3,
4: 3,
5: 3,
6: 3,
7: 4,
8: 3,
9: 4,
}
DIGIT_REPEAT_TO_CHAR = {
0: {
1: ' ',
},
1: {
1: '',
},
2: {
1: 'A',
2: 'B',
3: 'C',
},
3: {
1: 'D',
2: 'E',
3: 'F',
},
4: {
1: 'G',
2: 'H',
3: 'I',
},
5: {
1: 'J',
2: 'K',
3: 'L',
},
6: {
1: 'M',
2: 'N',
3: 'O',
},
7: {
1: 'P',
2: 'Q',
3: 'R',
4: 'S',
},
8: {
1: 'T',
2: 'U',
3: 'V',
},
9: {
1: 'W',
2: 'X',
3: 'Y',
4: 'Z',
},
}
BREAKER = "#"
CHAR_TO_DIGIT_REPEAT = {
' ': [0, 1],
'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],
}
NORMALISED_ANGLE_MIN_LIMIT = 0
NORMALISED_ANGLE_MAX_LIMIT = 359
NUM_TO_ANGLE = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
def nums_to_text(nums: List[int]) -> str:
commands = []
for num in nums:
if len(commands) == 0 or commands[-1][0] != num:
commands.append([num, 1])
else:
commands[-1][1] += 1
for i in range(len(commands)):
digit = commands[i][0]
repetition = commands[i][1]
if digit in [-1, 1]:
commands[i] = BREAKER
elif digit != 0 and repetition > DIGIT_ROTATION_RANGE[digit]:
diff = repetition % DIGIT_ROTATION_RANGE[digit]
commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
res = []
for data_block in commands:
if data_block == BREAKER:
continue
else:
digit = data_block[0]
repetition = data_block[1]
if digit == 0:
for _ in range(repetition):
res.append(DIGIT_REPEAT_TO_CHAR[digit][1])
else:
res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
return ''.join(res)
def text_to_nums(text: str) -> List[int]:
chars = [char for char in text.upper()]
prev_char = None
res = []
for char in chars:
digit = CHAR_TO_DIGIT_REPEAT[char][0]
repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
res.append(-1)
for _ in range(repetitions):
res.append(digit)
prev_char = char
return res
def nums_to_angle(nums: List[int]) -> int:
angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
total_normalised_angle = 0
for angle in angles:
total_normalised_angle += angle
if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
return total_normalised_angle
def angles_to_nums(angles: List[int]) -> List[int]:
def round_angle(angle: int):
angle /= 30
angle = round(angle)
angle *= 30
angle %= 360
return angle
def normalise_angle(angle: int):
if NORMALISED_ANGLE_MAX_LIMIT < angle:
angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
while angle < NORMALISED_ANGLE_MIN_LIMIT:
angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
return angle
nums = []
for angle in angles:
angle = normalise_angle(angle)
angle = round_angle(angle)
if angle in [0, 330]:
continue
nums.append(ANGLE_TO_NUM[angle])
return nums
def is_phone_tastic(word: str) -> bool:
num_of_chars = 0
for char in word:
if char != ' ':
num_of_chars += 1
nums_from_word = text_to_nums(word)
angle_from_nums = nums_to_angle(nums_from_word)
return angle_from_nums % num_of_chars == 0 if num_of_chars != 0 else False

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

.......FF............................
======================================================================
FAIL: test_random_mixed_case (test.TestAnglesToNums)
Test with a random mixed 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
AssertionError: Lists differ: [5, 1, 2, 4, 9, 2, 8, 0, 9] != [5, 1, 2, 4, 9, 1, 8, 0, 9]

First differing element 5:
2
1

- [5, 1, 2, 4, 9, 2, 8, 0, 9]
?                 ^

+ [5, 1, 2, 4, 9, 1, 8, 0, 9]
?                 ^


======================================================================
FAIL: test_round_angle_direction (test.TestAnglesToNums)
Test with an angle requiring explicit rounding to floor.
----------------------------------------------------------------------
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
AssertionError: Lists differ: [2] != [1]

First differing element 0:
2
1

- [2]
+ [1]

----------------------------------------------------------------------
Ran 37 tests in 0.316s

FAILED (failures=2)

История (6 версии и 1 коментар)

Александър обнови решението на 02.11.2022 02:44 (преди над 1 година)

+from typing import List
+
+
+DIGIT_ROTATION_RANGE = {
+ -1: 1,
+ 0: 1,
+ 1: 1,
+ 2: 3,
+ 3: 3,
+ 4: 3,
+ 5: 3,
+ 6: 3,
+ 7: 4,
+ 8: 3,
+ 9: 4,
+}
+
+DIGIT_REPEAT_TO_CHAR = {
+ 0: {
+ 1: ' ',
+ },
+ 1: {
+ 1: '',
+ },
+ 2: {
+ 1: 'A',
+ 2: 'B',
+ 3: 'C',
+ },
+ 3: {
+ 1: 'D',
+ 2: 'E',
+ 3: 'F',
+ },
+ 4: {
+ 1: 'G',
+ 2: 'H',
+ 3: 'I',
+ },
+ 5: {
+ 1: 'J',
+ 2: 'K',
+ 3: 'L',
+ },
+ 6: {
+ 1: 'M',
+ 2: 'N',
+ 3: 'O',
+ },
+ 7: {
+ 1: 'P',
+ 2: 'Q',
+ 3: 'R',
+ 4: 'S',
+ },
+ 8: {
+ 1: 'T',
+ 2: 'U',
+ 3: 'V',
+ },
+ 9: {
+ 1: 'W',
+ 2: 'X',
+ 3: 'Y',
+ 4: 'Z',
+ },
+}
+
+BREAKER = "#"
+
+CHAR_TO_DIGIT_REPEAT = {
+
+ ' ': [0, 1],
+ '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],
+}
+
+NORMALISED_ANGLE_MIN_LIMIT = 0
+NORMALISED_ANGLE_MAX_LIMIT = 359
+
+NUM_TO_ANGLE = {
+ 1: 30,
+ 2: 60,
+ 3: 90,
+ 4: 120,
+ 5: 150,
+ 6: 180,
+ 7: 210,
+ 8: 240,
+ 9: 270,
+ 0: 300,
+}
+
+ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
+
+
+def nums_to_text(nums: List[int]) -> str:
+ commands = [] # list of 2-sized lists [num; times met consecutively]
+ for num in nums:
+ if len(commands) == 0 or commands[-1][0] != num:
+ commands.append([num, 1])
+ else:
+ commands[-1][1] += 1
+
+ for i in range(len(commands)):
+ digit = commands[i][0]
+ repetition = commands[i][1]
+
+ if digit in [-1, 1]:
+ commands[i] = BREAKER
+ elif digit == 0:
+ # TODO for now, there is a question regarding that in the forum, we wait
+ commands[i][1] = 1
+ elif repetition > DIGIT_ROTATION_RANGE[digit]:
+ diff = repetition % DIGIT_ROTATION_RANGE[digit]
+ commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
+
+ res = []
+ for data_block in commands:
+ if data_block == BREAKER:
+ continue
+ else:
+ digit = data_block[0]
+ repetition = data_block[1]
+ res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
+
+ return ''.join(res)
+
+
+def text_to_nums(text: str) -> List[int]:
+ chars = [char for char in text.upper()]
+
+ prev_char = None
+ res = []
+
+ for char in chars:
+ digit = CHAR_TO_DIGIT_REPEAT[char][0]
+ repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
+ if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
+ # insert breaker
+ res.append(-1)
+ for _ in range(repetitions):
+ res.append(digit)
+ prev_char = char
+
+ return res
+
+
+def nums_to_angle(nums: List[int]) -> int:
+ angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
+
+ total_normalised_angle = 0
+ for angle in angles:
+ total_normalised_angle += angle
+ if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
+ total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
+
+ return total_normalised_angle
+
+
+def angles_to_nums(angles: List[int]) -> List[int]:
+
+ def round_angle(angle: int):
+ angle /= 30
+ angle = round(angle)
+ angle *= 30
+ return angle
+
+ def normalise_angle(angle: int):
+ if NORMALISED_ANGLE_MAX_LIMIT < angle:
+ angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
+
+ while angle < NORMALISED_ANGLE_MIN_LIMIT: # could be -719, need to be added to 360 twice
+ angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
+
+ return angle
+
+ nums = []
+ for angle in angles:
+ angle = normalise_angle(angle)
+ angle = round_angle(angle)
+ if angle in [0, 330]:
+ continue
+ nums.append(ANGLE_TO_NUM[angle])
+
+ return nums
+
+
+def is_phone_tastic(word: str) -> bool:
+ num_of_chars = len(word)
+ nums_from_word = text_to_nums(word)
+ angle_from_nums = nums_to_angle(nums_from_word)
+
+ return angle_from_nums % num_of_chars == 0

Александър обнови решението на 02.11.2022 19:18 (преди над 1 година)

from typing import List
DIGIT_ROTATION_RANGE = {
-1: 1,
0: 1,
1: 1,
2: 3,
3: 3,
4: 3,
5: 3,
6: 3,
7: 4,
8: 3,
9: 4,
}
DIGIT_REPEAT_TO_CHAR = {
0: {
1: ' ',
},
1: {
1: '',
},
2: {
1: 'A',
2: 'B',
3: 'C',
},
3: {
1: 'D',
2: 'E',
3: 'F',
},
4: {
1: 'G',
2: 'H',
3: 'I',
},
5: {
1: 'J',
2: 'K',
3: 'L',
},
6: {
1: 'M',
2: 'N',
3: 'O',
},
7: {
1: 'P',
2: 'Q',
3: 'R',
4: 'S',
},
8: {
1: 'T',
2: 'U',
3: 'V',
},
9: {
1: 'W',
2: 'X',
3: 'Y',
4: 'Z',
},
}
BREAKER = "#"
CHAR_TO_DIGIT_REPEAT = {
' ': [0, 1],
'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],
}
NORMALISED_ANGLE_MIN_LIMIT = 0
NORMALISED_ANGLE_MAX_LIMIT = 359
NUM_TO_ANGLE = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
def nums_to_text(nums: List[int]) -> str:
- commands = [] # list of 2-sized lists [num; times met consecutively]
+ commands = []
for num in nums:
if len(commands) == 0 or commands[-1][0] != num:
commands.append([num, 1])
else:
commands[-1][1] += 1
for i in range(len(commands)):
digit = commands[i][0]
repetition = commands[i][1]
if digit in [-1, 1]:
commands[i] = BREAKER
- elif digit == 0:
- # TODO for now, there is a question regarding that in the forum, we wait
- commands[i][1] = 1
- elif repetition > DIGIT_ROTATION_RANGE[digit]:
+ elif digit != 0 and repetition > DIGIT_ROTATION_RANGE[digit]:
diff = repetition % DIGIT_ROTATION_RANGE[digit]
commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
res = []
for data_block in commands:
if data_block == BREAKER:
continue
else:
digit = data_block[0]
repetition = data_block[1]
- res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
+ if digit == 0:
+ for _ in range(repetition):
+ res.append(DIGIT_REPEAT_TO_CHAR[digit][1])
+ else:
+ res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
return ''.join(res)
def text_to_nums(text: str) -> List[int]:
chars = [char for char in text.upper()]
prev_char = None
res = []
for char in chars:
digit = CHAR_TO_DIGIT_REPEAT[char][0]
repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
- # insert breaker
res.append(-1)
for _ in range(repetitions):
res.append(digit)
prev_char = char
return res
def nums_to_angle(nums: List[int]) -> int:
angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
total_normalised_angle = 0
for angle in angles:
total_normalised_angle += angle
if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
return total_normalised_angle
def angles_to_nums(angles: List[int]) -> List[int]:
def round_angle(angle: int):
angle /= 30
angle = round(angle)
angle *= 30
+ angle %= 360
return angle
def normalise_angle(angle: int):
if NORMALISED_ANGLE_MAX_LIMIT < angle:
angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
- while angle < NORMALISED_ANGLE_MIN_LIMIT: # could be -719, need to be added to 360 twice
+ while angle < NORMALISED_ANGLE_MIN_LIMIT:
angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
return angle
nums = []
for angle in angles:
angle = normalise_angle(angle)
angle = round_angle(angle)
+ print("processed angle = ", angle)
if angle in [0, 330]:
continue
nums.append(ANGLE_TO_NUM[angle])
return nums
def is_phone_tastic(word: str) -> bool:
num_of_chars = len(word)
nums_from_word = text_to_nums(word)
angle_from_nums = nums_to_angle(nums_from_word)
return angle_from_nums % num_of_chars == 0

Александър обнови решението на 02.11.2022 19:19 (преди над 1 година)

from typing import List
DIGIT_ROTATION_RANGE = {
-1: 1,
0: 1,
1: 1,
2: 3,
3: 3,
4: 3,
5: 3,
6: 3,
7: 4,
8: 3,
9: 4,
}
DIGIT_REPEAT_TO_CHAR = {
0: {
1: ' ',
},
1: {
1: '',
},
2: {
1: 'A',
2: 'B',
3: 'C',
},
3: {
1: 'D',
2: 'E',
3: 'F',
},
4: {
1: 'G',
2: 'H',
3: 'I',
},
5: {
1: 'J',
2: 'K',
3: 'L',
},
6: {
1: 'M',
2: 'N',
3: 'O',
},
7: {
1: 'P',
2: 'Q',
3: 'R',
4: 'S',
},
8: {
1: 'T',
2: 'U',
3: 'V',
},
9: {
1: 'W',
2: 'X',
3: 'Y',
4: 'Z',
},
}
BREAKER = "#"
CHAR_TO_DIGIT_REPEAT = {
' ': [0, 1],
'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],
}
NORMALISED_ANGLE_MIN_LIMIT = 0
NORMALISED_ANGLE_MAX_LIMIT = 359
NUM_TO_ANGLE = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
def nums_to_text(nums: List[int]) -> str:
commands = []
for num in nums:
if len(commands) == 0 or commands[-1][0] != num:
commands.append([num, 1])
else:
commands[-1][1] += 1
for i in range(len(commands)):
digit = commands[i][0]
repetition = commands[i][1]
if digit in [-1, 1]:
commands[i] = BREAKER
elif digit != 0 and repetition > DIGIT_ROTATION_RANGE[digit]:
diff = repetition % DIGIT_ROTATION_RANGE[digit]
commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
res = []
for data_block in commands:
if data_block == BREAKER:
continue
else:
digit = data_block[0]
repetition = data_block[1]
if digit == 0:
for _ in range(repetition):
res.append(DIGIT_REPEAT_TO_CHAR[digit][1])
else:
res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
return ''.join(res)
def text_to_nums(text: str) -> List[int]:
chars = [char for char in text.upper()]
prev_char = None
res = []
for char in chars:
digit = CHAR_TO_DIGIT_REPEAT[char][0]
repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
res.append(-1)
for _ in range(repetitions):
res.append(digit)
prev_char = char
return res
def nums_to_angle(nums: List[int]) -> int:
angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
total_normalised_angle = 0
for angle in angles:
total_normalised_angle += angle
if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
return total_normalised_angle
def angles_to_nums(angles: List[int]) -> List[int]:
def round_angle(angle: int):
angle /= 30
angle = round(angle)
angle *= 30
angle %= 360
return angle
def normalise_angle(angle: int):
if NORMALISED_ANGLE_MAX_LIMIT < angle:
angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
while angle < NORMALISED_ANGLE_MIN_LIMIT:
angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
return angle
nums = []
for angle in angles:
angle = normalise_angle(angle)
angle = round_angle(angle)
- print("processed angle = ", angle)
if angle in [0, 330]:
continue
nums.append(ANGLE_TO_NUM[angle])
return nums
def is_phone_tastic(word: str) -> bool:
num_of_chars = len(word)
nums_from_word = text_to_nums(word)
angle_from_nums = nums_to_angle(nums_from_word)
return angle_from_nums % num_of_chars == 0

Александър обнови решението на 02.11.2022 20:41 (преди над 1 година)

from typing import List
DIGIT_ROTATION_RANGE = {
-1: 1,
0: 1,
1: 1,
2: 3,
3: 3,
4: 3,
5: 3,
6: 3,
7: 4,
8: 3,
9: 4,
}
DIGIT_REPEAT_TO_CHAR = {
0: {
1: ' ',
},
1: {
1: '',
},
2: {
1: 'A',
2: 'B',
3: 'C',
},
3: {
1: 'D',
2: 'E',
3: 'F',
},
4: {
1: 'G',
2: 'H',
3: 'I',
},
5: {
1: 'J',
2: 'K',
3: 'L',
},
6: {
1: 'M',
2: 'N',
3: 'O',
},
7: {
1: 'P',
2: 'Q',
3: 'R',
4: 'S',
},
8: {
1: 'T',
2: 'U',
3: 'V',
},
9: {
1: 'W',
2: 'X',
3: 'Y',
4: 'Z',
},
}
BREAKER = "#"
CHAR_TO_DIGIT_REPEAT = {
' ': [0, 1],
'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],
}
NORMALISED_ANGLE_MIN_LIMIT = 0
NORMALISED_ANGLE_MAX_LIMIT = 359
NUM_TO_ANGLE = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
def nums_to_text(nums: List[int]) -> str:
commands = []
for num in nums:
if len(commands) == 0 or commands[-1][0] != num:
commands.append([num, 1])
else:
commands[-1][1] += 1
for i in range(len(commands)):
digit = commands[i][0]
repetition = commands[i][1]
if digit in [-1, 1]:
commands[i] = BREAKER
elif digit != 0 and repetition > DIGIT_ROTATION_RANGE[digit]:
diff = repetition % DIGIT_ROTATION_RANGE[digit]
commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
res = []
for data_block in commands:
if data_block == BREAKER:
continue
else:
digit = data_block[0]
repetition = data_block[1]
if digit == 0:
for _ in range(repetition):
res.append(DIGIT_REPEAT_TO_CHAR[digit][1])
else:
res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
return ''.join(res)
def text_to_nums(text: str) -> List[int]:
chars = [char for char in text.upper()]
prev_char = None
res = []
for char in chars:
digit = CHAR_TO_DIGIT_REPEAT[char][0]
repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
res.append(-1)
for _ in range(repetitions):
res.append(digit)
prev_char = char
return res
def nums_to_angle(nums: List[int]) -> int:
angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
total_normalised_angle = 0
for angle in angles:
total_normalised_angle += angle
if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
return total_normalised_angle
def angles_to_nums(angles: List[int]) -> List[int]:
def round_angle(angle: int):
angle /= 30
angle = round(angle)
angle *= 30
angle %= 360
return angle
def normalise_angle(angle: int):
if NORMALISED_ANGLE_MAX_LIMIT < angle:
angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
while angle < NORMALISED_ANGLE_MIN_LIMIT:
angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
return angle
nums = []
for angle in angles:
angle = normalise_angle(angle)
angle = round_angle(angle)
if angle in [0, 330]:
continue
nums.append(ANGLE_TO_NUM[angle])
return nums
def is_phone_tastic(word: str) -> bool:
- num_of_chars = len(word)
+
+ num_of_chars = 0
+ for char in word:
+ if char != ' ':
+ num_of_chars += 1
nums_from_word = text_to_nums(word)
angle_from_nums = nums_to_angle(nums_from_word)
return angle_from_nums % num_of_chars == 0

Доста интересен подход. Не, че е уникален алгоритъм, по-скоро начинът, по който си го описал, прави впечатление.
Не го приемай нито като критика, нито като похвала. Реално същото може да се постигне по-оптимизирано като код, но твоята имплементация някак интуитивно следва описанието на процеса като flowchart. Това за по-сложни неща ще е нож с две остриета, затова в случаят го казвам само като наблюдение, не като негатив или позитив.

Освен празните редове, които аз намирам за излишни тук таме, стилът е on point (все още се колебая за променливата res, but I'll live with it).

Александър обнови решението на 03.11.2022 15:59 (преди над 1 година)

from typing import List
DIGIT_ROTATION_RANGE = {
-1: 1,
0: 1,
1: 1,
2: 3,
3: 3,
4: 3,
5: 3,
6: 3,
7: 4,
8: 3,
9: 4,
}
DIGIT_REPEAT_TO_CHAR = {
0: {
1: ' ',
},
1: {
1: '',
},
2: {
1: 'A',
2: 'B',
3: 'C',
},
3: {
1: 'D',
2: 'E',
3: 'F',
},
4: {
1: 'G',
2: 'H',
3: 'I',
},
5: {
1: 'J',
2: 'K',
3: 'L',
},
6: {
1: 'M',
2: 'N',
3: 'O',
},
7: {
1: 'P',
2: 'Q',
3: 'R',
4: 'S',
},
8: {
1: 'T',
2: 'U',
3: 'V',
},
9: {
1: 'W',
2: 'X',
3: 'Y',
4: 'Z',
},
}
BREAKER = "#"
CHAR_TO_DIGIT_REPEAT = {
' ': [0, 1],
'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],
}
NORMALISED_ANGLE_MIN_LIMIT = 0
NORMALISED_ANGLE_MAX_LIMIT = 359
NUM_TO_ANGLE = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
def nums_to_text(nums: List[int]) -> str:
commands = []
for num in nums:
if len(commands) == 0 or commands[-1][0] != num:
commands.append([num, 1])
else:
commands[-1][1] += 1
for i in range(len(commands)):
digit = commands[i][0]
repetition = commands[i][1]
if digit in [-1, 1]:
commands[i] = BREAKER
elif digit != 0 and repetition > DIGIT_ROTATION_RANGE[digit]:
diff = repetition % DIGIT_ROTATION_RANGE[digit]
commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
res = []
for data_block in commands:
if data_block == BREAKER:
continue
else:
digit = data_block[0]
repetition = data_block[1]
if digit == 0:
for _ in range(repetition):
res.append(DIGIT_REPEAT_TO_CHAR[digit][1])
else:
res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
return ''.join(res)
def text_to_nums(text: str) -> List[int]:
chars = [char for char in text.upper()]
prev_char = None
res = []
for char in chars:
digit = CHAR_TO_DIGIT_REPEAT[char][0]
repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
res.append(-1)
for _ in range(repetitions):
res.append(digit)
prev_char = char
return res
def nums_to_angle(nums: List[int]) -> int:
angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
total_normalised_angle = 0
for angle in angles:
total_normalised_angle += angle
if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
return total_normalised_angle
def angles_to_nums(angles: List[int]) -> List[int]:
def round_angle(angle: int):
angle /= 30
angle = round(angle)
angle *= 30
angle %= 360
return angle
def normalise_angle(angle: int):
if NORMALISED_ANGLE_MAX_LIMIT < angle:
angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
while angle < NORMALISED_ANGLE_MIN_LIMIT:
angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
return angle
nums = []
for angle in angles:
angle = normalise_angle(angle)
angle = round_angle(angle)
if angle in [0, 330]:
continue
nums.append(ANGLE_TO_NUM[angle])
return nums
def is_phone_tastic(word: str) -> bool:
- num_of_chars = 0
- for char in word:
- if char != ' ':
- num_of_chars += 1
+ num_of_chars = len(word)
nums_from_word = text_to_nums(word)
angle_from_nums = nums_to_angle(nums_from_word)
- return angle_from_nums % num_of_chars == 0
+ return angle_from_nums % num_of_chars == 0 if num_of_chars != 0 else False

Александър обнови решението на 03.11.2022 16:02 (преди над 1 година)

from typing import List
DIGIT_ROTATION_RANGE = {
-1: 1,
0: 1,
1: 1,
2: 3,
3: 3,
4: 3,
5: 3,
6: 3,
7: 4,
8: 3,
9: 4,
}
DIGIT_REPEAT_TO_CHAR = {
0: {
1: ' ',
},
1: {
1: '',
},
2: {
1: 'A',
2: 'B',
3: 'C',
},
3: {
1: 'D',
2: 'E',
3: 'F',
},
4: {
1: 'G',
2: 'H',
3: 'I',
},
5: {
1: 'J',
2: 'K',
3: 'L',
},
6: {
1: 'M',
2: 'N',
3: 'O',
},
7: {
1: 'P',
2: 'Q',
3: 'R',
4: 'S',
},
8: {
1: 'T',
2: 'U',
3: 'V',
},
9: {
1: 'W',
2: 'X',
3: 'Y',
4: 'Z',
},
}
BREAKER = "#"
CHAR_TO_DIGIT_REPEAT = {
' ': [0, 1],
'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],
}
NORMALISED_ANGLE_MIN_LIMIT = 0
NORMALISED_ANGLE_MAX_LIMIT = 359
NUM_TO_ANGLE = {
1: 30,
2: 60,
3: 90,
4: 120,
5: 150,
6: 180,
7: 210,
8: 240,
9: 270,
0: 300,
}
ANGLE_TO_NUM = {angle: num for num, angle in NUM_TO_ANGLE.items()}
def nums_to_text(nums: List[int]) -> str:
commands = []
for num in nums:
if len(commands) == 0 or commands[-1][0] != num:
commands.append([num, 1])
else:
commands[-1][1] += 1
for i in range(len(commands)):
digit = commands[i][0]
repetition = commands[i][1]
if digit in [-1, 1]:
commands[i] = BREAKER
elif digit != 0 and repetition > DIGIT_ROTATION_RANGE[digit]:
diff = repetition % DIGIT_ROTATION_RANGE[digit]
commands[i][1] = diff if diff != 0 else DIGIT_ROTATION_RANGE[digit]
res = []
for data_block in commands:
if data_block == BREAKER:
continue
else:
digit = data_block[0]
repetition = data_block[1]
if digit == 0:
for _ in range(repetition):
res.append(DIGIT_REPEAT_TO_CHAR[digit][1])
else:
res.append(DIGIT_REPEAT_TO_CHAR[digit][repetition])
return ''.join(res)
def text_to_nums(text: str) -> List[int]:
chars = [char for char in text.upper()]
prev_char = None
res = []
for char in chars:
digit = CHAR_TO_DIGIT_REPEAT[char][0]
repetitions = CHAR_TO_DIGIT_REPEAT[char][1]
if prev_char != None and digit == CHAR_TO_DIGIT_REPEAT[prev_char][0]:
res.append(-1)
for _ in range(repetitions):
res.append(digit)
prev_char = char
return res
def nums_to_angle(nums: List[int]) -> int:
angles = [NUM_TO_ANGLE[num] for num in nums if num != -1]
total_normalised_angle = 0
for angle in angles:
total_normalised_angle += angle
if total_normalised_angle > NORMALISED_ANGLE_MAX_LIMIT:
total_normalised_angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
return total_normalised_angle
def angles_to_nums(angles: List[int]) -> List[int]:
def round_angle(angle: int):
angle /= 30
angle = round(angle)
angle *= 30
angle %= 360
return angle
def normalise_angle(angle: int):
if NORMALISED_ANGLE_MAX_LIMIT < angle:
angle %= (NORMALISED_ANGLE_MAX_LIMIT + 1)
while angle < NORMALISED_ANGLE_MIN_LIMIT:
angle += (NORMALISED_ANGLE_MAX_LIMIT + 1)
return angle
nums = []
for angle in angles:
angle = normalise_angle(angle)
angle = round_angle(angle)
if angle in [0, 330]:
continue
nums.append(ANGLE_TO_NUM[angle])
return nums
def is_phone_tastic(word: str) -> bool:
- num_of_chars = len(word)
+ num_of_chars = 0
+ for char in word:
+ if char != ' ':
+ num_of_chars += 1
nums_from_word = text_to_nums(word)
angle_from_nums = nums_to_angle(nums_from_word)
return angle_from_nums % num_of_chars == 0 if num_of_chars != 0 else False