やりたいこと
基礎文法の比較復習。素数抽出のためのアルゴリズムは全て同じで、あんまり工夫もないです。
リストをだらだら出しても見ないので、トータル数だけを見て正解しているかをチェック。
言語はこれから追記で増えていくといいな(希望)。
正解チェック用対照表
最大数 | 素数の数 |
---|---|
1,000 | 168 |
10,000 | 1229 |
100,000 | 9592 |
1,000,000 | 78498 |
(参考:素数2357:素数の数)
シングルコア、メモリ4GBのノートPCでは、最大数10万くらいが(結果を待つ忍耐力の)限度です。
Python on jupyterが群を抜いて遅いですがこれは環境によって変わるかと。jupyterはCPUの25%までしか使えない制約でもあるんでしょうか。
この書き方・今回の環境で、最大数100万では、一番早いJavaでも5分くらいかかります。jupyterは試したくないです。
Python3 on jupyter notebook
import datetime
# 最大数
MAX=100000
# 開始時刻
start_time = datetime.datetime.now()
# 素数の数
count=0
# 1~3は計算なしで扱ってしまう
# print(2)
# print(3)
count+=2
# 4からスタート
for i in range(4, MAX):
# 偶数は除外
if (i%2 == 0):
continue
else:
is_prime = True
# 自分の1/2以下の数値で割り切れたら除外
for j in range(3, round(i/2)):
if i%j==0:
is_prime = False
break
if is_prime :
# print(i)
count+=1
# 終了時刻
end_time = datetime.datetime.now()
time_del = round((end_time - start_time).total_seconds(), 2)
# 結果
print("time : " + str(time_del) + " sec.")
print("total count : " + str(count))
実行結果
time : 48.58 sec.
total count : 9592
Java8 on eclipse 4.9.0
package local.dev;
import java.util.Date;
public class DetectPrimeNumber {
// 最大数
private static final int MAX = 100000;
public static void main(String[] args) {
int count = 0;
// 開始時刻
long startDT = (new Date()).getTime();
// 1~3は計算なしで扱ってしまう
// System.out.println(2);
// System.out.println(3);
count+=2;
// 4からスタート
for (int i=4; i<=MAX; i++) {
// 偶数は除外
if (i%2 == 0) {
continue;
// 自分の1/2以下の数値で割り切れたら除外
} else {
boolean isPrime = true;
for (int j=3; j<Math.floor(i/2); j++) {
if (i%j == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
// System.out.println(i);
count++;
}
}
}
// 終了時刻
long endDT = (new Date()).getTime();
// 時刻の差分(ミリ秒→秒に変換)
String timeDelta = String.format("%.2f", ((float)(endDT - startDT) / 1000));
// 結果
System.out.println("time : " + timeDelta + " sec.");
System.out.println("total count : " + Integer.toString(count));
}
}
実行結果
time : 4.50 sec.
total count : 9592
Ruby2.5 on eclipse 4.9.0 with Ruby Development Tools 5.10.0
# 最大数
MAX=100000
# 開始時刻
start_time = Time.now()
# 素数の数
count=0
# 1~3は計算なしで扱ってしまう
# puts 2
# puts 3
count+=2
# 4からスタート
for i in 4..MAX
# 偶数は除外
if i%2 == 0
next
else
is_prime = true
# 自分の1/2以下の数値で割り切れたら除外
for j in 3..(i/2).floor
if i%j==0
is_prime = false
break
end
end
if is_prime
# puts i
count+=1
end
end
end
# 終了時刻
end_time = Time.now()
time_del = format("%.2f", (end_time - start_time))
# 結果
puts ("time : " + time_del + " sec.")
puts ("total count : " + count.to_s)
実行結果
time : 16.32 sec.
total count : 9592
JavaScript on Codepen
// 最大数
const MAX=100000;
// 開始時刻
const StartTime = (new Date()).getTime();
// 素数の数
let Count=0;
// 1~3は計算なしで扱ってしまう
// console.log(2);
// console.log(3);
Count+=2
// 4からスタート
for (let i=4; i<=MAX; i++){
// 偶数は除外
if (i%2 == 0) {
continue;
} else {
let IsPrime = true;
// 自分の1/2以下の数値で割り切れたら除外
for (let j=3; j<=Math.floor(i/2);j++){
if (i%j == 0) {
IsPrime = false;
break;
}
}
if(IsPrime) {
// console.log(i)
Count+=1
}
}
}
// 終了時刻
const EndTime = (new Date()).getTime();
const TimeDel = (EndTime - StartTime)/1000;
// 結果
console.log("time : " + TimeDel + " sec.");
console.log("total count : " + Count);
実行結果(ループ多すぎってCodePenに怒られて中断したせいでカウントが…)
"[CodePen]: An infinite loop (or a loop taking too long) was detected, so we stopped its execution. Sorry!"
"time : 4.202 sec."
"total count : 9026"