В этой статье я хочу поделиться своим путешествием по Codewars. Я хочу завершить Наименьшую возможную сумму. То, что я рекомендую вам сначала попробовать, прежде чем читать эту статью. Вы можете зарегистрироваться на codewars и искать его. Попробуйте выполнить его, и вы обнаружите, что это потрясающее ката сенсея дхабурдзания.

Итак, после того, как вы его завершите. Там будут отличные решения, которые могут быть лучше, чем мои, которые вы сможете найти. Но в этой статье я просто хочу поделиться тем, как я выполняю это ката, улучшая его шаг за шагом. Это, возможно, вы можете применить к любой вашей проблеме.

Важная часть этой статьи, которую я получаю от завершения этой ката, заключается в том, что мы можем улучшить наши коды даже с небольшим шагом. Конечно, вам нужно улучшать свою логику или код снова и снова в реальной жизни, чтобы добиться максимальной производительности. Но вы можете добавить только небольшие вещи, например, чтобы исключить некоторые «ненужные» процессы, чтобы сделать его более эффективным. Это знания, которыми я хочу поделиться.

Первым делом, когда я начинаю работать над этим ката, потому что мы хотим обновить значение внутри него. Поэтому нам нужно сначала глубоко скопировать список.

number_list = a[:]

Во-вторых, сделать петлю, но я не знаю, когда петля закончится, даже если сказано: «Когда преобразования больше невозможны», поэтому я просто взглянул на образец и понял, что именно тогда все номера в списке одинаковые [3, 3, 3]. Итак, что мы хотим сделать, это использовать этот код:

while number_list.count(number_list[0]) != len(number_list):

Мы будем зацикливаться, пока все элементы не будут иметь одинаковые значения. Откуда нам знать? Просто подсчитайте, сколько элементов в списке имеют то же значение, что и первый элемент. Если это то же самое, что и длина списка. Тогда все значения будут одинаковыми.

Далее ищем наименьшее значение. Почему? Я объясню это позже. Вот замечательная встроенная функция в Python, которую вы можете использовать для получения наименьшего значения:

smallest_value = min(number_list)

На мой взгляд и когда я увидел образец вывода образца:

[6, 9, 12]
[6, 9, 6]
[6, 3, 6]
[6, 3, 3]
[3, 3, 3]

Похоже, мы можем вычесть все остальные значения на наименьшее значение. Но нам нужно умножить наименьшее значение, чтобы получить наименьший результат. Но остерегайтесь отрицательного значения, также результат должен быть целым числом. Итак, вот код 1 лайнера:

number_list[:] = [number - (smallest_value * (number//smallest_value)) if number > smallest_value and number - (smallest_value * (number//smallest_value)) != 0 else smallest_value for number in number_list]

Затем, наконец, верните сумму всех чисел в списке, потому что мы знаем, что все числа будут одинаковыми, мы просто умножаем 1-й элемент на длину исходного списка:

return number_list[0] * len(a)

Мы можем проверить результат, он будет правильным! Но мы не можем его подать, потому что он недостаточно эффективен. Если вы можете представить себе этот код или вы можете напечатать number_list во время цикла, чтобы увидеть, как он работает шаг за шагом. Вы можете видеть, что он зацикливается с той же длиной списка, и позже, после процесса вычисления, у нас есть то же число в списке, что не нужно, потому что значение такое же, поэтому мы можем фактически игнорировать значения или удалить его в этом случае, чтобы уменьшить количество циклов. Вы можете добавить этот код ниже в конце цикла while:

number_list[:] = list(dict.fromkeys(number_list))

Тогда, наконец, мы можем отправить код! С минимальной оптимизацией, которая делает код немного эффективнее.

Для полных кодов:

Небольшая оптимизация, но если вы делаете это снова и снова, в конце концов вы получите большое улучшение. Я надеюсь, что вы сможете изучить и испытать удивительное чувство, выполняя и это ката. Вы можете почувствовать процесс:

  1. Столкнулся с проблемой
  2. Поиск решения этой проблемы
  3. Оптимизируйте свое решение
  4. Оптимизировать больше…

Одна из оптимизаций, которую вы можете попробовать, предназначена для математического решения, и она тоже будет работать на удивление.

Что касается этой проблемы, математическое решение с использованием GCD, как показано ниже, в настоящее время является лучшим решением, и это блестящее решение, упомянутое @elyasaf755:

from math import gcd

def solution(a):
    return gcd(*a) * len(a)

Если у вас есть предложение, какую статью мне нужно сделать следующей, или какой-либо отзыв, возможно, лучшее улучшение, которым, по вашему мнению, было бы здорово поделиться. Очень хотелось бы услышать!