Intro
Considera il processo di prendere un numero intero positivo n in qualche base b e sostituire ogni cifra con la sua rappresentazione nella base della cifra a destra.
- Se la cifra a destra è uno 0, utilizzare la base b .
- Se la cifra a destra è un 1, utilizzare unario con 0 come segni di conteggio.
- Se non c'è nessuna cifra a destra (cioè sei nel posto giusto), passa alla cifra più significativa.
Ad esempio let n = 160 eb = 10. L'esecuzione del processo è simile alla seguente:
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.
La stessa identica procedura ma spostando a sinistra anziché a destra può anche essere eseguita:
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.
Pertanto, abbiamo creato due numeri relativi a 160 (per b = 10): 16 e 10000000.
Definiremo n come un numero astuto se divide uniformemente almeno uno dei due numeri generati in questo processo in 2 o più parti
Nell'esempio n è furbo perché 160 divide 10000000 esattamente 62500 volte.
203 NON è furbo perché i numeri risultanti sono 2011 e 203 stesso, che 203 non può adattarsi uniformemente in 2 o più volte.
Sfida
(Per il resto del problema considereremo solo b = 10.)
La sfida è quella di scrivere un programma che trova il numero più furbo che sia anche primo.
I primi 7 numeri primi astuti (e tutto quello che ho trovato finora) sono:
2
5
3449
6287
7589
9397
93557 <-- highest so far (I've searched to 100,000,000+)
Non sono ufficialmente certo se ne esistano altri, ma mi aspetto che lo siano. Se riesci a dimostrare che ce ne sono (o non lo sono) finitamente molti, ti darò +200 rappresentanti di taglie.
Il vincitore sarà la persona che sarà in grado di fornire il primo più furbo, a condizione che siano stati attivi nella ricerca e che non stiano prendendo intenzionalmente gloria dagli altri.
Regole
- È possibile utilizzare tutti gli strumenti di ricerca primaria desiderati.
- È possibile utilizzare tester probabilistici.
- Puoi riutilizzare il codice di altre persone con attribuzione . Questo è uno sforzo comune. La tattica della gola non sarà tollerata.
- Il tuo programma deve cercare attivamente il numero primo. È possibile iniziare la ricerca dal più alto numero primo conosciuto.
- Il tuo programma dovrebbe essere in grado di calcolare tutti i primi furbi noti entro 4 ore dalle istanze di Amazon EC2 t2.medium (quattro alla volta o una per quattro ore o una via di mezzo). In realtà non lo proverò su di loro e di certo non è necessario. Questo è solo un punto di riferimento.
Ecco il mio codice Python 3 che ho usato per generare la tabella sopra: (funziona in un secondo o due)
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()