オラ工程第37題:Truncatable primes
タイトルリンク:https://projecteuler.net/problem=37
11個の二重せん断質量数の和を求める
例えばhe number 3797 has an interesting property.Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
考え方:1.ブール型素数配列2.この数が素数であれば、左剪断数が素数であるか否かを判断する.もし、右剪断数が素数であるか否かを判断する.もし、和を求めるなら
Javaコード:
結果:
11個の数は;
結果から最大の上界は739397で、私が設定した上界は1000000で、人為的に上界を見つけることが重要です.
Pythonコード:
結果:
748317 time is 22.3920001984
このPythonはよく書けていて、私が問題解の中で見つけたので、少し直しました.
4つの関数が定義されています:1.素数2であるか否かを判定する.この文字列を反転します.左に切って、左に切った数を判断して、質数ではありませんか、意外にも再帰的に書いたのです.右に切る
11個の二重せん断質量数の和を求める
例えばhe number 3797 has an interesting property.Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
考え方:1.ブール型素数配列2.この数が素数であれば、左剪断数が素数であるか否かを判断する.もし、右剪断数が素数であるか否かを判断する.もし、和を求めるなら
Javaコード:
package projecteuler31to40;
import java.util.Date;
class level37{
void solve(){
int Max_Value=1000000;
int sum=0;
boolean[] primes=PrimeArray(Max_Value);
for(int i=10;i<Max_Value;i++){
int num=i;
boolean flag=true;
if(primes[i]){
while(num>10){
num=LeftToRight(num);
if(primes[num]==false){
flag=false;
break;
}
}
if(primes[num]==true && flag==true){
num=i;
while(num>10){
num=RightToLeft(num);
if(primes[num]==false){
flag=false;
break;
}
}
if(primes[num]==true && flag==true){
sum+=i;
// System.out.println(i);
}
}
}
}
System.out.println(sum);
}
int RightToLeft(int num){
if(num<10)
return num;
return num/10;
}
int LeftToRight(int num){
String str=String.valueOf(num);
return Integer.parseInt(str.substring(1));
}
boolean[] PrimeArray(int num){
boolean[] primes=new boolean[num+1];
primes[2]=true;
for(int i=3;i<num+1;++i)
primes[i]=isPrime(i);
return primes;
}
boolean isPrime(int num){
for(int i=2;i<=Math.sqrt(num);i++){
if(num%i==0)
return false;
}
return true;
}
}
public class Problem37 {
public static void main(String[] args){
Date beginTime=new Date();
new level37().solve();//
Date endTime=new Date();
long Time=endTime.getTime()-beginTime.getTime();
System.out.println("Time:"+Time/1000+"s"+Time%1000+"ms");
}
}
結果:
748317
Time:0s493ms
11個の数は;
23
37
53
73
313
317
373
797
3137
3797
739397
結果から最大の上界は739397で、私が設定した上界は1000000で、人為的に上界を見つけることが重要です.
Pythonコード:
from time import time
def is_prime(x):
if x in (1,4):
return False
if x in (2,3):
return True
last_value=int(x**0.5)+1
for n in range(2,last_value):
if x%n==0:
return False
return True
def trim(n,direction):
if direction=='left':
return(n[1:])
else:
return(n[:-1])
def check_left(n):
if len(n)==1 and is_prime(int(n)):
return True
if is_prime(int(n)):
return check_left(trim(n,'left'))
else:
return False
def check_right(n):
if len(n)==1 and is_prime(int(n)):
return True
if is_prime(int(n)):
return check_right(trim(n,'right'))
else:
return False
t=time()
sum=0
for num in range(11,10**6):
p=str(num)
if check_left(p)==True and check_right(p)==True:
sum=sum+num
print sum
print("time is {0}".format(time() - t))
結果:
748317 time is 22.3920001984
このPythonはよく書けていて、私が問題解の中で見つけたので、少し直しました.
4つの関数が定義されています:1.素数2であるか否かを判定する.この文字列を反転します.左に切って、左に切った数を判断して、質数ではありませんか、意外にも再帰的に書いたのです.右に切る