Решение
Я не опубликую полное решение, потому что из Project Euler о разделе:
Я так много узнал, решая проблему XXX, так что можно опубликовать мою
решение в другом месте?
Похоже, что вы ответили самостоятельно
вопрос. Ничего подобного "Ага!" момент, когда ты
наконец, победить проблему, над которой вы работали в течение некоторого времени.
Часто из лучших побуждений мы хотим поделиться нашими
понимание, чтобы другие тоже могли насладиться этим моментом. К сожалению, однако,
это не будет иметь место для ваших читателей. Реальное обучение является активным
процесс и видеть, как это делается, еще далеко от
Богоявление открытия. Пожалуйста, не отрицайте других, что у вас так
богато себя ценил.
Однако я дам вам несколько советов.
Структуры данных
Как я уже упоминал в комментарии, использование наборов значительно улучшит производительность вашей программы, потому что доступ к данным в них действительно быстрый (вы можете узнать почему, прибегая к помощи метода, называемого hashing , если ты не знаешь об этом). Точно, производительность со списками будет O(N)
, тогда как с сетами она будет около O(1)
.
Вращения против перестановок
В постановке задачи вам необходимо рассчитать повороты числа. Как отметил @ottomeister, вы должны действительно проверить, выполняет ли ваша программа то, что ожидает от нее постановка задачи. В настоящее время вызов permutations("197")
вернет следующий список - ['791', '917', '179', '971', '719', '197']
- тогда как проблема ожидает, что результат будет ['197', '971', '719']
. Вместо создания перестановок вы должны вычислить вращений , что можно найти, например, перемещая каждую цифру влево (с переносом), пока не будет возвращено начальное число (может сделать такой рекурсивный алгоритм, если он вам действительно нравится).
Первичная проверка
В настоящее время вы проверяете, является ли каждое число простым, выполняя цикл, который проверяет, делится ли число N
на все, вплоть до sqrt(N)
. Как вы заметили, это довольно медленно для многих чисел, и есть лучшие способы проверить, является ли число простым. В вашем сценарии идеальным решением будет просто сделать N in primes
, потому что вы уже сгенерировали простые числа, которые, если вы используете наборы вместо списков, будут O(1)
. Кроме того, вы можете взглянуть на тесты простоты (особенно эвристические и вероятностные тесты)
Наконец
Обычно я рекомендую тестировать ваше собственное решение, прежде всего, вы могли легко заметить, что ваша функция permutations
не соответствует ожидаемым результатам постановки задачи. Я предлагаю разбить вещи дальше на более мелкие функции, например, у вас может быть функция rotations(number)
, аналогичная вашей permutations
, может быть, функция is_circular(number)
, которая проверяет, соответствует ли данное число проблемным требованиям, и функция count_circular(upper_bound)
, которая вычисляет и считает круглые числа. Если вы также прокомментируете все по ходу дела, это значительно упростит отладку, и вы сможете на ходу подтвердить, что все работает, как и ожидалось:)