Introducción
Considere el proceso de tomar un número entero positivo n en alguna base b y reemplazar cada dígito con su representación en la base del dígito a la derecha.
- Si el dígito a la derecha es a 0, use la base b .
- Si el dígito a la derecha es un 1, use unario con 0 como marcas de conteo.
- Si no hay un dígito a la derecha (es decir, está en el lugar de las unidades), recorra el dígito más significativo.
Como ejemplo, n = 160 yb = 10. La ejecución del proceso se ve así:
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.
El mismo procedimiento exacto pero moviéndose a la izquierda en lugar de a la derecha también se puede hacer:
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.
Por lo tanto, hemos hecho dos números relacionados con 160 (para b = 10): 16 y 10000000.
Definiremos n como un número astuto si divide al menos uno de los dos números generados en este proceso en 2 o más partes
En el ejemplo, n es astuto porque 160 divide 10000000 exactamente 62500 veces.
203 NO es astuto porque los números resultantes son 2011 y 203 en sí, que 203 no pueden caber uniformemente en 2 o más veces.
Desafío
(Para el resto del problema solo consideraremos b = 10.)
El desafío es escribir un programa que encuentre el número astuto más alto que también sea primo.
Los primeros 7 primos astutos (y todo lo que he encontrado hasta ahora) son:
2
5
3449
6287
7589
9397
93557 <-- highest so far (I've searched to 100,000,000+)
Oficialmente no estoy seguro de si existen más, pero espero que existan. Si puedes demostrar que hay (o no) finitamente muchos, te daré +200 repeticiones.
El ganador será la persona que pueda proporcionar el mejor nivel de astucia, siempre que sea evidente que han estado activos en la búsqueda y que no están tomando la gloria intencionalmente de los demás.
Reglas
- Puede usar cualquier herramienta de búsqueda principal que desee.
- Puede utilizar probadores primarios probabilísticos.
- Puede reutilizar el código de otras personas con atribución . Este es un esfuerzo comunitario. Las tácticas feroces no serán toleradas.
- Su programa debe buscar activamente la prima. Puede comenzar su búsqueda en el primer astuto más alto conocido.
- Su programa debería poder calcular todos los primos astutos conocidos dentro de las 4 horas posteriores a las instancias de Amazon EC2 t2.medium (ya sea cuatro a la vez o una durante cuatro horas o algo intermedio). En realidad no lo probaré en ellos y ciertamente no es necesario. Esto es solo un punto de referencia.
Aquí está mi código Python 3 que usé para generar la tabla anterior: (se ejecuta en un segundo o dos)
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()