Рассмотрим функцию, Remove(n, startIndex, count)
которая удаляет count
цифры из числа, n
начиная с цифры в позиции startIndex
. Примеры:
Remove(1234, 1, 1) = 234
Remove(123456, 2, 3) = 156
Remove(1507, 1, 2) = 07 = 7
Remove(1234, 1, 4) = 0
Мы назовем простое число X хрупким, если каждая возможная Remove
операция делает его непростым. Например, 80651 - хрупкое простое число, потому что все следующие числа не просты:
651, 51, 1, 0, 8651, 851, 81, 8, 8051, 801, 80, 8061, 806, 8065
Цель
Напишите программу, которая находит наибольшее хрупкое простое число. Изменить: убрал ограничение по времени, потому что был относительно справедливый способ обойти его.
Счет - это хрупкое простое число, найденное вашей программой. В случае ничьей побеждает более ранняя подача.
правила
- Вы можете использовать любой язык и любые сторонние библиотеки.
- Вы запускаете программу на собственном оборудовании.
- Вы можете использовать вероятностные тесты простоты.
- Все в базе 10.
Ведущие записи
- 6629 цифр по Qualtagh (Java)
- Эмиль, 5048 цифр (Python 2)
- 2268 цифр Якуба (Python 2)
Изменить: я добавил свой собственный ответ.
- 28164 цифр по Suboptimus Prime, основанный на алгоритме Qualtagh (C #)
code-challenge
primes
Suboptimus Prime
источник
источник
Ответы:
Джава -
314433226629 цифр6 0{3314} 8969999
Это решение основано на ответе FryAmTheEggman .
Что если мы будем копать глубже?
Это становится древовидной структурой:
Назовем номер R правым составным, если R и все его окончания составные.
Мы будем перебирать все правильные составные числа в ширину: 1, 9, 01, 81, 91, 09, 49, 69, 99, 001, 801, 901 и т. Д.
Числа, начинающиеся с нуля, не проверяются на простоту, но необходимы для построения дальнейших чисел.
Мы будем искать целевое число N в форме X00 ... 00R, где X является одним из 4, 6, 8 или 9, а R является правым составным. Х не может быть простым. X не может быть 0. И X не может быть 1, потому что, если R заканчивается 1 или 9, тогда N будет содержать 11 или 19.
Если XR содержит простые числа после операции «удалить», то XYR будет содержать их также для любого Y. Поэтому мы не должны проходить ветви, начиная с R.
Пусть X - константа, скажем, 6.
псевдокод:
Мы должны ограничить количество нулей, потому что это может занять слишком много времени, чтобы найти простое число в форме X + нули + R (или навсегда, если все они составные).
Настоящий код довольно многословен и его можно найти здесь .
Проверка первичности чисел в длинном диапазоне int выполняется детерминистическим вариантом теста Миллера. Для номеров BigInteger сначала выполняется пробное деление, а затем тест BailliePSW. Это вероятностно, но вполне определенно. И это быстрее, чем тест Миллера-Рабина (мы должны сделать много итераций для таких больших чисел в Миллере-Рабине, чтобы получить достаточную точность).
Изменить: первая попытка была неверной. Мы также должны игнорировать ветви, начинающиеся с R, если X0 ... 0R простое. Тогда X0 ... 0YR не будет хрупким простым. Поэтому была добавлена дополнительная проверка. Это решение кажется правильным.
Редактировать 2: добавлена оптимизация. Если (X + R) делится на 3, то (X + нули + R) также делится на 3. Так что (X + нули + R) не могут быть простыми в этом случае, и такие R могут быть пропущены.
Редактировать 3: не было необходимости пропускать простые цифры, если они не находятся в последней или первой позиции. Так что концовки вроде 21 или 51 в порядке. Но это ничего не меняет.
Выводы:
источник
Python 2 -
1261221133717192268 цифрПриблизительно len (n) ^ 2 результирующих числа Remove (n, startIndex, count). Я пытался минимизировать эти цифры. Если много цифр рядом друг с другом, то многие из этих результирующих чисел могут быть проигнорированы, потому что они появляются несколько раз.
Таким образом, я взял это до крайности, только 9 и немного премьер в середине. Я также взглянул на хрупкое простое число до 1 миллиона и увидел, что существуют такие хрупкие простое число. Поиск чисел с 2 9 в конце работает действительно хорошо, не знаю почему. 1 число, 3 или 4 9 в конце приводит к меньшим хрупким простым числам.
Он использует модуль pyprimes . Я не уверен, если это хорошо. Он использует тест miller_rabin, поэтому он вероятностный.
Программа находит это 126-значное хрупкое простое число примерно за 1 минуту, а в остальное время ищет безуспешно.
редактировать:
Только что увидел, что вы сняли ограничение по времени. Я буду запускать программу в течение ночи, возможно, появятся действительно большие хрупкие простые числа.
редактировать 2:
Сделал мою оригинальную программу быстрее, но до сих пор нет решения с более чем 126 цифрами. Поэтому я вскочил на поезд и искал x 9s + 1 цифра + y 9s. Преимущество состоит в том, что вы должны проверить O (n) чисел на простоту, если вы исправите y. Он находит 1221 довольно быстро.
редактировать 3:
Для 2268-значного числа я использую ту же программу, только поделил работу на несколько ядер.
источник
Python 2.7 - 429623069
99993799Пока никаких оптимизаций. Просто используя некоторые тривиальные наблюдения о хрупких простых числах (спасибо Rainbolt в чате):
Просто пытаюсь заставить мяч катиться :)
Технически это выполняется чуть более 15 минут, но в дополнительное время проверяется только один номер.
is_prime
взято отсюда (isaacg использовал его здесь ) и является вероятностным.Просто примечание, когда я начинаю это с,
n=429623069
я встаю482704669
. Кажется, лишняя цифра убивает эту стратегию ...источник
Python 2,
828 цифр,5048 цифрКак указал @Jakube, первое простое число, которое я отправил, на самом деле не было хрупким из-за ошибки в моем коде. Исправить ошибку было легко, но это также сделало алгоритм значительно медленнее.
Я ограничил себя легко доступным для поиска подмножеством хрупких простых чисел, а именно теми, которые состоят только из цифры 9 и ровно одной цифры 7.
Я использовал ту же
is_prime
функцию ( отсюда ), что и @FryAmTheEggman.Редактировать:
Я сделал два изменения, чтобы сделать алгоритм быстрее:
Я стараюсь пропустить как можно больше проверок простоты и возвращаюсь назад, только когда обнаружен потенциальный хрупкий простой код, чтобы убедиться, что он действительно хрупкий. Существует небольшое количество повторных проверок, поэтому я грубо запомнил функцию первичной проверки.
Для чисел формы
b*'9' + '7' + c*'9'
я ограничил размерb
. Чем ниже предел, тем меньше чисел нужно проверять, но шансы увеличиваться, чтобы вообще не найти большого хрупкого простого числа. Я как бы произвольно выбрал 222 в качестве предела.При нескольких тысячах разовых простых проверок моя программа может занять несколько секунд. Таким образом, я, вероятно, не могу сделать намного лучше с этим подходом.
Пожалуйста, не стесняйтесь проверить правильность моего представления. Из-за вероятностной проверки простоты мое число теоретически не может быть простым, но если оно есть, оно должно быть хрупким. Или я сделал что-то не так. :-)
источник
C #,
10039,28164 цифрыРедактировать: я сделал другую программу, основанную на алгоритме Qualtagh с некоторыми незначительными изменениями:
Старый ответ:
Вот несколько примечательных шаблонов для хрупких простых чисел:
где Х может быть 1, 2, 4, 5, 7 или 8.
Для таких чисел нам нужно только рассмотреть (длина - 1) возможные
Remove
операции. ДругойRemove
операции производят либо дубликаты, либо явно составные числа. Я попытался найти все такие числа с длиной до 800 цифр и заметил, что 4 шаблона появляются чаще, чем остальные: 8007001, 8004001, 9997999 и 6004009. Поскольку Эмиль и Якуб используют шаблон 999X999, я решил использовать 8004001 просто добавить немного разнообразия.Я добавил следующие оптимизации в алгоритм:
источник
Haskell -
12201277 цифр исправлено для настоящих реаловЛучше один - 1277 цифр
Код Haskell
источник