вступление
Рассмотрим процесс взятия некоторого положительного целого числа n в некоторой базе b и замены каждой цифры ее представлением в основании цифры справа.
- Если цифра справа - 0, используйте основание b .
- Если цифра справа - 1, используйте одинарные с 0 в качестве меток.
- Если справа нет цифры (т. Е. Вы на месте), перейдите к самой значимой цифре.
В качестве примера пусть n = 160 и b = 10. Запуск процесса выглядит следующим образом:
The first digit is 1, the digit to the right is 6, 1 in base 6 is 1.
The next digit is 6, the digit to the right is 0, 0 is not a base so use b, 6 in base b is 6.
The last digit is 0, the digit to the right (looping around) is 1, 0 in base 1 is the empty string (but that's ok).
Concatenating '1', '6', and '' together gives 16, which is read in the original base b = 10.
Точно такую же процедуру, но перемещение влево вместо права также можно сделать:
The first digit is 1, the digit to the left (looping around) is 0, 0 is not a base so use b, 1 in base b is 1.
The next digit is 6, the digit to the left is 1, 6 in base 1 is 000000.
The last digit is 0, the digit to the left is 6, 0 in base 6 is 0.
Concatenating '1', '000000', and '0' together gives 10000000, which is read in the original base b = 10.
Таким образом, мы сделали два числа, связанных с 160 (для b = 10): 16 и 10000000.
Мы определим n как хитрое число, если оно равномерно делит хотя бы одно из двух чисел, сгенерированных в этом процессе, на 2 или более частей.
В примере n хитроумно, потому что 160 делит 10000000 ровно 62500 раз.
203 НЕ является хитрым, потому что итоговые числа - это 2011 и 203, которые не могут равномерно вписываться в 2 или более раз.
Вызов
(Для остальной части проблемы мы рассмотрим только b = 10.)
Задача состоит в том, чтобы написать программу, которая находит наибольшее хитрое число, которое также является простым.
Первые 7 хитроумных простых чисел (и все, что я нашел до сих пор):
2
5
3449
6287
7589
9397
93557 <-- highest so far (I've searched to 100,000,000+)
Официально я не уверен, существуют ли еще, но я ожидаю, что они существуют. Если вы можете доказать, что их конечное число (или их нет), я дам вам +200 повторений.
Победителем станет тот, кто сможет обеспечить наивысшую хитрость, при условии, что очевидно, что они были активны в поиске и преднамеренно не снискали славу у других.
правила
- Вы можете использовать любые удобные инструменты поиска.
- Вы можете использовать вероятностные простые тестеры.
- Вы можете повторно использовать код других людей с указанием авторства . Это совместное усилие. Тактика головокружения недопустима.
- Ваша программа должна активно искать премьер. Вы можете начать поиск с самого высокого известного хитрого прайма.
- Ваша программа должна быть в состоянии вычислить все известные хитрые простые числа в течение 4 часов после экземпляров Amazon EC2 t2.medium (четыре сразу или один за четыре часа или что-то среднее). На самом деле я не буду проверять это на них, и вам, конечно, это не нужно. Это всего лишь ориентир.
Вот мой код Python 3, который я использовал для генерации таблицы выше: (запускается через секунду или две)
import pyprimes
def toBase(base, digit):
a = [
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
['', '0', '00', '000', '0000', '00000', '000000', '0000000', '00000000', '000000000' ],
['0', '1', '10', '11', '100', '101', '110', '111', '1000', '1001'],
['0', '1', '2', '10', '11', '12', '20', '21', '22', '100'],
['0', '1', '2', '3', '10', '11', '12', '13', '20', '21'],
['0', '1', '2', '3', '4', '10', '11', '12', '13', '14'],
['0', '1', '2', '3', '4', '5', '10', '11', '12', '13'],
['0', '1', '2', '3', '4', '5', '6', '10', '11', '12'],
['0', '1', '2', '3', '4', '5', '6', '7', '10', '11'],
['0', '1', '2', '3', '4', '5', '6', '7', '8', '10']
]
return a[base][digit]
def getCrafty(start=1, stop=100000):
for p in pyprimes.primes_above(start):
s = str(p)
left = right = ''
for i in range(len(s)):
digit = int(s[i])
left += toBase(int(s[i - 1]), digit)
right += toBase(int(s[0 if i + 1 == len(s) else i + 1]), digit)
left = int(left)
right = int(right)
if (left % p == 0 and left // p >= 2) or (right % p == 0 and right // p >= 2):
print(p, left, right)
if p >= stop:
break
print('DONE')
getCrafty()
источник
Ответы:
Mathematica, находит 93 557 за 0,3 с (без хитроумных простых чисел ниже 2 * 10 10 )
Это просто наивный исчерпывающий поиск по всем простым числам. Для начала он проверяет около 1 000 000 простых чисел каждые 55 секунд (что становится все медленнее по мере увеличения простых чисел).
Я использую кучу вспомогательных функций:
И тогда этот цикл выполняет фактический поиск:
Я буду обновлять пост, если найду какие-нибудь простые числа или смогу подумать об оптимизации.
В настоящее время он проверяет все простые числа до 100 000 000 примерно за 5,5 минут.
Изменить: я решил последовать примеру ОП и переключился на таблицу поиска для преобразования базы. Это дало примерно 30% ускорения.
Лукавые числа в целом
Сейчас я прекращаю поиск хитрых простых чисел, так как мне нужно несколько дней, чтобы наверстать то, что уже получил ответ Perl. Вместо этого я начал искать все хитрые цифры. Возможно, их распределение помогает найти доказательство того, что число хитрых простых чисел конечно или бесконечно.
Я определяю хитроумные числа, которые делят связанное число, полученное путем интерпретации цифры справа, как нового основания, и числа слева, соответственно. Вероятно, это поможет решить их индивидуально для доказательства.
Вот все левые хитрые числа до 2 210 000 000:
И вот все правильные числа в этом диапазоне:
Обратите внимание, что существует бесконечное число левых и хитрых чисел, потому что есть несколько способов генерировать их из существующих:
0
s к любому левому числу, у которого младшая значащая цифра больше, чем его самая значимая цифра, чтобы получить другое левое число.0
s к любому искусному числу, у которого младшая значащая цифра меньше его самой значимой цифры. Это (и предыдущее утверждение) объясняется тем, что0
они будут добавлены как к хитрому номеру, так и к связанному с ним номеру, эффективно умножая их обоих на 10.2
s или5
s является хитрым.777
s является хитрым.28
соединяемых0
s, like28028028
всегда лукаво.Другие вещи, чтобы отметить:
125
. Возможно, стоит изучить их, чтобы найти другое правило производства.Я полагаю, что этот список был бы более интересным, если бы я опустил те, чье существование подразумевается меньшим хитрым числом, тем более что они никогда не являются простыми числами по правилам построения, обнаруженным до сих пор. Итак, вот все хитрые простые числа, которые не могут быть построены с одним из приведенных выше правил:
Также обратите внимание, что есть несколько хитроумных чисел (те, которые появляются в обоих списках и, следовательно, делят оба связанных числа):
Их тоже существует бесконечно много.
Но , как вы можете видеть, за исключениемНашел контрпример16
,28
,68
все они состоят только из одного (неоднократного) цифры. Было бы также интересно доказать, могут ли какие-либо большие числа быть вдвойне лукавыми, не обладая этим свойством, но это может быть просто следствием доказательства для однократно лукавых чисел.1944919449
.источник
100540625, 100540625
попали в список правых?Perl (1e5 в 0,03 с, 1e8 в 21 с). Макс 93557 до 1е11.
Очень похоже на оригинал. Изменения включают в себя:
Выполняет первые 1e8 простых чисел за 21 секунду на моей быстрой машине, 3,5 минуты за 1e9, 34 минуты за 1e10. Я немного удивлен, что это вообще быстрее, чем код Python для небольших входных данных. Мы могли бы распараллелить (новый Pari / GP
parforprime
был бы хорош для этого). Я полагаю, что это поиск, который мы можем распараллелить вручную (forprimes
может принимать два аргумента).forprimes
в основном похож на Pari / GPforprime
- он выполняет сегментированные сита внутри и вызывает блок с каждым результатом. Это удобно, но для этой проблемы я не думаю, что это область производительности.источник
C ++ 11, с потоками и GMP
Сроки (на MacBook Air):
Требования:
g++ crafty.cpp -o crafty --std=c++11 -ffast-math -lprimesieve -O3 -lgmpxx -lgmp -Wall -Wextra
Вывод:
источник
C, с GMP, многопоточный (1e8 в 17 с для 1 потока)
Схожи по концепции с остальными, возможно, с небольшой оптимизацией здесь и там.
Обобщение:
gcc -I/usr/local/include -Ofast crafty.c -pthread -L/usr/local/lib -lgmp && ./a.out
Пожалуйста, пожертвуйте свой процессор. У меня нет быстрого компьютера.
1e8 за 17 секунд с 1 потоком на моем MacBook Air.
источник
Питон, находит 93557 в 0.28
Очень похоже на код OP в том, что он также использует
pyprimes
. Я написал это сам, хотя xDОн также распечатывает время с начала, когда находит номер.
Вывод:
Формат есть
number left right time
. Для сравнения, код OP находит 93557 около0.37
.источник