はじめに
ある基数bでいくつかの正の整数nを取り、各数字をその数字の基数の右側の表現で置き換えるプロセスを検討してください。
- 右側の数字が0の場合は、基数bを使用します。
- 右側の数字が1の場合、タリーマークとして0の単項を使用します。
- 右側に数字がない場合(つまり、1の場所にいる場合)は、最上位の数字までループします。
例として、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に関連する2つの数値(b = 10の場合)、16と10000000を作成しました。
このプロセスで生成された2つの数値の少なくとも1つを2つ以上の部分に均等に分割する場合、nを巧妙な数と定義します
この例では、160は10000000を正確に62500回除算するため、nは巧妙です。
結果の数値は2011と203自体であり、203は2回以上に均等に適合できないため、203は巧妙ではありません。
チャレンジ
(残りの問題については、b = 10 のみを考慮します。)
課題は、素数でもある最高の巧妙な数を見つけるプログラムを書くことです。
最初の7つの巧妙な素数(および私がこれまでに見つけたもの)は次のとおりです。
2
5
3449
6287
7589
9397
93557 <-- highest so far (I've searched to 100,000,000+)
それ以上存在するかどうかは正式には定かではありませんが、存在すると思います。有限であることを証明できる場合(またはそうでない場合)、+ 200のバウンティ担当者に差し上げます。
勝者は、最高に巧妙なプライムを提供できる人物です。ただし、彼らが検索に積極的であり、意図的に他人から栄光を奪っていないことが明らかです。
ルール
- あなたはあなたが望むどんな素晴しい発見ツールも使うかもしれません。
- 確率論的プライムテスターを使用できます。
- アトリビューションで他の人のコードを再利用できます。これは共同の努力です。凶暴な戦術は容認されません。
- プログラムは素数を積極的に検索する必要があります。最も知られている狡猾な素数から検索を開始することができます。
- プログラムは、Amazon EC2 t2.mediumインスタンスから4時間以内に既知のすべての巧妙な素数を計算できる必要があります(一度に4つ、または4時間に1つ、またはその中間)。私は実際にそれらでそれをテストするつもりはなく、あなたは確かにそうする必要はありません。これは単なるベンチマークです。
上記のテーブルの生成に使用したPython 3コードは次のとおりです(1、2秒で実行されます)。
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()