Алгоритмическая задача на питоне, как улучшить код?
Всем привет! Недавно изучаю алгоритмические задачи на питоне, сделал одну задачу, хотел бы узнать, как её можно улучшить? (можно побольше объяснений).
Гоша и Тимофей нашли необычный тренажёр для скоростной печати и хотят освоить его. Тренажёр представляет собой поле из клавиш 4×4, в котором на каждом раунде появляется конфигурация цифр и точек. На клавише написана либо точка, либо цифра от 1 до 9. В момент времени t игрок должен одновременно нажать на все клавиши, на которых написана цифра t. Гоша и Тимофей могут нажать в один момент времени на k клавиш каждый. Если в момент времени t были нажаты все нужные клавиши, то игроки получают 1 балл. Найдите число баллов, которое смогут заработать Гоша и Тимофей, если будут нажимать на клавиши вдвоём.
Формат ввода
В первой строке дано целое число k (1 ≤ k ≤ 5). В четырёх следующих строках задан вид тренажёра –— по 4 символа в каждой строке. Каждый символ —– либо точка, либо цифра от 1 до 9. Символы одной строки идут подряд и не разделены пробелами.
Формат вывода
Выведите единственное число –— максимальное количество баллов, которое смогут набрать Гоша и Тимофей.
Пример 1:
Ввод:
3
1231
2..2
2..2
2..2
Вывод:
2
Пример 2:
Ввод:
4
1111
9999
1111
9911
Вывод:
1
Пример 3:
Ввод:
4
1111
1111
1111
1111
Вывод:
0
Ограничение времени - 1 секунда | Ограничение памяти - 64mb
Мой вариант:
k = int(input()) * 2 #Эти 2 части перенести в if __name__ == "__main__" и сделать def "snake_case"
matrix = []
for i in range(4):
numbers = input()
matrix += numbers
t = 1
score = 0
while t <= 9:
count_t = matrix.count(str(t))
if 0 < count_t <= k:
score += 1 #Тут была идея сделать функцию sum() с условием, чтобы избавиться от лишних строк, но не знаю, нужно это или нет
t += 1
print(score)
Ответы (3 шт):
count_t = matrix.count(str(t))
Вы прогоняете свой список 9 раз. Лучше сделать так:
nums = '12456789'
col_vo = {'1':0, '2':0, '3':0, '4':0, '5':0, '6':0, '7':0, '8':0, '9':0}
for i in matrix:
if i in nums:
col_vo[i] += 1
Вы получаете словарь со всеми цифрами(ключи) и кол-во вхождениями их в список(значения).
Ваше решение нормальное. Единственное плохое место: matrix += numbers. Этот оператор копирует список раз за разом, что может привести к тормозам. Но здесь всего четыре итерации. Замедление не будет заметно.
Решение можно доработать в сторону большей питоничности.
Другой ввод символов из матрицы.
collections.Counter- специальный словарь для подсчёта символов в матрице.Итерация по словарю. Обрабатываем только те цифры, которые есть в матрице.
Суммирование с помощью
sumвместоscore += 1.
Код:
import collections
k = int(input()) * 2
print(sum( # 4
1 # 4
for key, v in collections.Counter( # 2
c for _ in range(4) for c in input() # 1
).items() # 3
if key.isdigit() and v <= k
))
Тоже учусь, и хотел бы поделиться своим решением. Не знаю на сколько оно затратное будет по времени и памяти.
def sleight_of_hand(matrix):
# промежуток времени от 1 до 9
time = range(1, 10)
numerate = []
for v in time:
count = matrix.count(str(v))
numerate.append(count)
points = sum(1 for x in numerate if hands >= x and x != 0)
return points
if __name__ == "__main__":
hands = int(input())*2
matrix = ''
matrix = ''.join([matrix + input() for i in range(4)])
print(sleight_of_hand(matrix))
Ниже второй вариант кода. В обоих случаях мне сказали можно его более оптимизировать.
def sleight_of_hand(matrix):
# промежуток времени от 1 до 9
time = range(1, 10)
points = 0
for v in time:
count = matrix.count(str(v))
if hands >= count and count != 0:
points += 1
return points
if __name__ == "__main__":
hands = int(input())*2
matrix = ''
matrix = ''.join([matrix + input() for i in range(4)])
print(sleight_of_hand(matrix))