Windows PowerShellでProject Euler(2) 型と演算

Problem 1

さっそくProblem 1を解いていきましょう。
この問題を解く最も簡単な方法は、包除原理を使うことでしょう。すなわち、3の倍数の和と5の倍数の和を足して、15の倍数の和を引きます。

まず、1000を変数に代入します。

> $n = 1000

変数には頭に$をつけます。シェルスクリプトっぽいですね。大文字小文字は区別しません。

> $N
1000

これはMS-DOSからの文化ですね。

次に、各倍数の個数を調べます。

> ($n - 1) / 3
333
> ($n - 1) / 5
199.8
> ($n - 1) / 15
66.6

このようにPowerShellの除算はProject Eulerに使うには残念な仕様となっています。まあ、シェルスクリプトですからね。これを整数にするには.NETのライブラリを使います。

> [math]::floor(($n - 1) / 5)
199

System.Math.Floorメソッドを使っています。Truncateメソッドも似ていますが、

> [math]::truncate(-1.5)
-1

と0の方に丸められるのでfloorのほうが使うことが多いでしょう。
しかし、Floorメソッドはよくあるようにdoubleです。GetTypeメソッドを使うと型が分かります。

> $n5 = [math]::floor(($n - 1) / 5)
> $n5.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Double                                   System.ValueType

整数にするには次のように変数をintで変数を宣言して受けます。

> [int]$n5 = [math]::floor(($n - 1) / 5)
> $n5.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

ちなみに、割り切れるときは整数になります。

> $n = 6 / 3
> $n.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Int32                                    System.ValueType

Python3は残念なことに整数同士の割り算の結果はDoubleになってしまいましたが、割り切れてもDoubleです。こちらのほうが一貫性はあります。

余談はこれまでにして、やっとProblem 1が解けます。

$n = 1000
[int]$n3 = [math]::floor(($n - 1) / 3)
[int]$n5 = [math]::floor(($n - 1) / 5)
[int]$n15 = [math]::floor(($n - 1) / 15)
$s3 = $n3 * ($n3 + 1) / 2 * 3
$s5 = $n5 * ($n5 + 1) / 2 * 5
$s15 = $n15 * ($n15 + 1) / 2 * 15
$s3 + $s5 - $s15

最後の行、ここだけ代入ではなく評価になっていますが、こうすると値が標準出力されます。