Scalaの勉強はじめました 1 〜基本的な文法と素因数分解〜


はじめに

N予備校のプログラミング入門コースでNode.jsを学び、その勢いのままScalaの勉強を同じくN予備校で受講し始めました。

用語

JVM

Javaを動かすための、Java Virtual Machine (JVM)という仮想マシン

sbt

Scalaで書いたコードをコンパイルしてビルドしてくれるツール

sbt console

ScalaREPLが表示される。

sbt run

REPLに入らずにプログラムの実行と終了を行う。

文法

Main.scala
object Main extends App {
  println("Hello Scala")
}

Mainというオブジェクトを宣言。
Appというトレイト(振る舞い)をミックスイン(振る舞いをオブジェクトに対して追加)する。

名前からするに、機能の継承というか拡張という感じ。
Appというのは基底クラスに当たるんだろうか。

println: プリントライン
コンソールに出力して、「改行」する。

変数

val cat = "猫"

valは定数の宣言。
varもあるけれど、JSのletみたいなものはなさそう。

関数

def cat(name: String): String = {}

defで宣言して、String型を返す。
C#のvoidや.NETのSubプロシージャにあたるものがUnitかなと。

素因数分解するプログラム

import scala.math.sqrt

object Factorization extends App {
  // 素因数分解する値
  val target = 510510
  // 割る数の最大値は 対象となる値の平方根
  val maxDivisor = sqrt(target).toInt

  def factorizationRec(num: Int, divisor: Int, acc: Map[Int,Int]): Map[Int, Int] = {
    // 最大値を超えたら
    if (divisor > maxDivisor) {
      // 限界まで(1まで)割れたらその結果を返す
      // 限界まで割れなかった場合、配列に (現在の値, 1) を追加する
      if (num == 1) acc else acc + (num -> 1)
    } else if (num % divisor == 0) {
      // 現在の配列に (現在の割る数, 次に割る数)を追加する
      // 現在の割る数が、現在の配列になかった場合、次に割る数を1として配列に追加する      
      val nextAcc = acc + (divisor -> (acc.getOrElse(divisor, 0) + 1))
      factorizationRec(num / divisor, divisor, nextAcc)
    } else {
      factorizationRec(num, divisor + 1, acc)
    }
  }

  println(factorizationRec(target, 2, Map()))
}

実際にどうなるかを書き出してやっと理解できた。
とにかく2で割って、割り切れなくなったら3で割って・・・を繰り返す処理。最終的には何で何回割ったかを配列で返す。

再帰呼び出しは理解に時間がかかります。
その分理解できるとスッキリするけれど。

まとめ

新しく言語を勉強すると、まず文法に慣れるところから始まります。
すでに基礎編は半分終わってるんですが、少しずつまとめていきたいと思います。