LoginSignup
0
0

More than 5 years have passed since last update.

素数抽出で各プログラム言語の文法復習

Last updated at Posted at 2018-11-30

やりたいこと

基礎文法の比較復習。素数抽出のためのアルゴリズムは全て同じで、あんまり工夫もないです。
リストをだらだら出しても見ないので、トータル数だけを見て正解しているかをチェック。
言語はこれから追記で増えていくといいな(希望)。

正解チェック用対照表

最大数 素数の数
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"
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0