msawady’s engineering-note

なにも分からないエンジニアです。

【Scala】Scala 入門 - 素数探索

Scala 入門

  • 関数型プログラミングというものをしてみたく、Scalaに挑戦してみる。

    • 普段、仕事で使うのはメインでJava(Spring), 次点でTypeScriptを使ったフロントエンドくらいなので、関数型は初挑戦。
  • Scala のバージョンは2.12.2

  • 手始めに素数探索を。コレクション、for文、if文あたりを一通り舐めてみる。

コード

import java.lang.Math.sqrt

object PrimeNum {
  def main(args: Array[String]): Unit = {
    var primes: List[Int] = List[Int](2) // 2が素数であることは自明とする
    printExecutionTime {
      for (i <- 3 to 10000 by 2) { // 奇数だけチェック
        if (isPrime(primes, i)) {
          primes = i :: primes  // 先頭に要素を追加していく
        }
      }
      println(primes.reverse) // 最後に reverse
    }
  }

  def isPrime(primes: List[Int], target: Int): Boolean = {
    val max: Int = sqrt(target).toInt // チェックする必要があるのは平方数までだけ。
    !primes.filter(p => p <= max).exists(p => target % p == 0)
  }

  def printExecutionTime(proc: => Unit) = {
    val start = System.currentTimeMillis
    proc
    println((System.currentTimeMillis - start) + "msec")
  }

}

実行結果

List(2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ..(略).., 9931, 9941, 9949, 9967, 9973)
95msec

感想とか改善点とか

  • あんまり、こう、関数型!って感じにはならなかったかな…? 素数のリストprimesを使いまわすと普通にJavaっぽくなる。

  • Math.sqrtJava から Import するんですね。

  • List には逆順に入れていって最後に reverse を使うほうが実行効率が良いとのこと。

  • ググっていたら実行時間を調べるために関数を用意する記事が有ったので使ってみた。
    これはカッコいい!! Scala勉強しようというモチベーションが上がりました。

def printExecutionTime(proc: => Unit) = {
    val start = System.currentTimeMillis
    proc
    println((System.currentTimeMillis - start) + "msec")
  }

参考ページ