倭算数理研究所

科学・数学・学習関連の記事を、「倭マン日記」とは別に書いていくのだ!

2.4 True BASIC のプログラム series

今回は反復シミュレーションに大切な繰り返し処理。 Groops ではシミュレーションの繰り返し処理は型にはめて設定するようにしますが、Groovy でどのように繰り返しを行うかも知っておく方がよいでしょう。

True BASIC

まずは True BASIC でのコード:

PROGRAM series
! 簡単な級数の初めの 100 項の和
! True BASIC は変数を自動的に 0 に初期化するが、
! 他の言語では必ずしもそうなっていない
LET sum = 0
FOR n = 1 to 100
    LET sum = sum + 1/(n*n)
    PRINT n, sum
NEXT n
END

「to」や「NEXT」などのキーワードがありますが、特にどうってことないですね。

Groovy

では、Groovy でのコードを見ていきましょう。

for 文
Groovy は大抵の Java 構文をそのまま書けるので、C 系の

for(int i = 0; i < n; i++){ ... }

という形式でも繰り返し処理を書けますが、実際にはもっとコンパクトな形式で書くことの方が多いと思います。 その際に知っておく必要があるのは範囲 (Range) という概念です。

Groovy では、Java の List や Map と同レベルに Range というコレクションがサポートされていて、

def range1 = 1..10
def range2 = 1..<10

のように「..」や「..<」という演算子(?)を使って簡単にオブジェクトを生成することができます*1 *2。 「..」は最後の値(ここでは10)を含む範囲を、「..<」は最後の値を含まない範囲を生成します。

Groovy ではこの範囲を使って、上記の True BASIC コードを以下のように書くことが出来ます:

double sum = 0d
for(n in 1..100){
    sum += 1d/(n*n)
    println "$n, $sum"
}

for の後の () 内にある「in」はキーワードです。 「in」の代わりに、Java っぽく「:」を使うこともできますが、for 文の中に型宣言を書く必要があります:

double sum = 0d
for(int n : 1..100){
    sum += 1d/(n*n)
    println "$n, $sum"
}

コレクション × クロージャ
Groovy では、for 文を使わずに繰り返し処理を行うこともできます。 その1つは、コレクションに定義されている、クロージャをとるメソッドを使用するものです。 例えば、範囲オブジェクトに対して each() メソッド*3を呼び出して繰り返し処理を行うには以下のようにします:

(1..100).each{ int n ->
    sum += 1d/(n*n)
    println "$n, $sum"
}

単純に足し算をするだけなら、以下のように sum() メソッドを使うと簡潔です:

def sum = (1..100).sum{ 1/(it*it) }
//def sum = (1..100).sum{ int n -> 1/(n*n) } と同じ。
println sum

Integer × クロージャ
他にもよく使われる Groovy の繰り返し処理は、Groovy が Integer クラスに追加したメソッドを使用する方法です。 Integer オブジェクト「1」に対して upto() メソッドを呼び出して

1.upto(100){ int n ->
    sum += 1d/(n*n)
    println "$n, $sum"
}
//1行目を
//    1.upto 100, { int n ->
// としてもOK

とします。 この upto() メソッドは int とクロージャを引数にとるメソッドですが、第2引数のクロージャは「)」の後に書かれています。 もう一つ、times() メソッドを使ったものもよく使われると思います:

100.times { int n ->
    sum += 1d/(n*n)
    println "$n, $sum"
}

とまぁこういう風に、Groovy では Java に比べてかなり簡潔に書けてるようになってます。 見慣れてないと何をやっているのか分かりにくいかも知れませんが:-P

プログラミングGROOVY

プログラミングGROOVY

計算物理学入門

計算物理学入門

  • 作者: ハーベイゴールド,ジャントボチニク,Harvey Gould,Jan Tobochnik,鈴木増雄,石川正勝,溜渕継博,宮島佐介
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/12
  • メディア: 単行本
  • 購入: 1人 クリック: 28回
  • この商品を含むブログ (45件) を見る

*1:ちなみに、List は [1, 2, 3]、Map は [a:1, b:2, c:3] のようにしてオブジェクトを生成できます。

*2:ここで生成されているオブジェクトは、Range ではなく IntRange クラスかと思いますが、細かいことは気にしないで下さい。

*3:正確には、each() メソッドは Groovy が Object クラスに追加したメソッドですが。