(WIP)APG4b Nim版
前提
Nim言語からプログラミングに入る人はマジでいないと思うので、ある程度(本家APG4bが全部ACできるくらい)他の言語が書けるものとします。
Nimのバージョンは1.6.14とします。
1.00.はじめに
Nimを使うメリット
本家APG4bPythonでは「はじめに」において言語のメリットを紹介していたので、ここでもNim言語を用いることのメリットを記述しようと思います。
Python likeである文法
インデントに基づくシンタックスは、Pythonと非常によく似ています。Pythonをメインで使っている人にとって、これは移行のコストが低く済むというメリットになります。
実行速度
Nim言語はC++にトランスコンパイルを行うコンパイル言語であるため、PyPyなどのインタプリタ言語と比較してかなり高速です。
少なくとも、AtCoderのRatedの問題において想定解が通らないことはない程度の速度がしっかりと出ます。
スコープが直感的
ifやforなどでスコープが分かれるため、Pythonのようにいつまでもforで定義された変数が残り続けることはありません。
簡潔に記述可能
強力なマクロや豊富な標準ライブラリ、UFCSによるメソッドチェーンなどによって簡潔にプログラムを記述可能です。
Nimを使うデメリット
人口の少なさ
Nim言語は現時点(2024/7/18)において、非常に人口の少ない言語です。インターネット上に日本語情報が少なく、機能を探すのが大変であったり、エディタの補完機能が弱かったりといった問題があります。
また、Nim言語は多くのジャッジにおいて搭載されていないことが多く、特に海外のジャッジではほとんど使えません。
多倍長整数
現時点(2024/7/18)において、AtCoder上のNimでは多倍長整数ライブラリであるbignumが正常に動作しません。
問題
ジャッジを試すために、Hello Worldを提出してみる問題です。
nimでHello Worldをするためには以下のようにします。
code:nim
echo "Hello, world!"
1.01.出力とコメント
キーポイント
出力にはechoを用いる
echoは文字列や数値を出力できる
コメントを書くときは、#や#[ ]#を用いる
プログラムの基本形
Nimはmain関数を必要としません。Pythonと同様に一行目から書き始めることができます。
出力
Nimで出力をするのにはecho関数が用いられます。そのほかにもstdout.writeLine()という関数も存在しますが、ここでは扱いません。(詳しくは:Nimの標準出力) Nimで文字列を扱うときは、" "で囲います。""" """で囲うこともでき、こちらでは文字中で改行することができます。
code:nim
echo "Hello, world!"
code:result
Hello, world!
pythonのprintのように、()を付けても良いです。
code:nim
echo("Hello, world!")
セミコロン
セミコロンは必要ありません。セミコロンを用いることもでき、一行に複数のコードを書くことができます。
code:nim
echo "hello";echo "world"
code:result
hello
world
別の文字列の出力
別の文字列を出力したいときは、" "の中身を変えます。
code:nim
echo "こんにちは世界"
code:result
こんにちは世界
ただし、文字列型でUnicode文字を扱うときは、注意が必要です。たとえば、"こんにちは世界"の3番目を取ろうとすると、
code:nim
code:result
�
という結果になってしまいました。unicode文字を正しく扱いたいときはstd/unicodeを用いる必要があります。 複数の出力
code:nim
echo "a"
echo "b"
echo "c","d"
code:result
a
b
cd
カンマで区切っても、スペースは挿入されません。pythonのprintの感覚で用いると、少し困惑するかもしれません。
数値の出力
数値を出力するときは、" "を用いずに直接書くことができます。
code:nim
echo 2525
code:result
2525
少し発展的な内容を話すと、$を用いて文字列に変換可能である型はすべてechoに直接記述が可能です。簡単に言うならば、文字列に変換可能である型は基本的にechoに直接記述できます。
コメント
nimではコメントに#を用います。(Pythonと一緒ですね)
また、複数行のコメント用に#[ ]#が用意されています。
code:nim
echo "Hello, world!" #Hello, worldと表示 コメント ]#
EX1 - コードテストと出力の練習
C - 1.02.プログラムの書き方とエラー
キーポイント
Nimでコードを書く際は、行の書き出し位置・改行などのルールに従う必要があります。
Pythonといっしょですね
コンパイルエラーは文法のエラーで、プログラムは実行されません。
実行時エラーはプログラムの処理中に発生したエラーで、プログラムが強制的に終了します。
プログラムの書き方
NimではPythonと同じくインデントによるシンタックスを採用しています。
インデントにはスペースを用いる。タブ文字は用いることができません。(コンパイルエラーになります)
タブ幅はスペース2つが推奨されていますが、他の幅を使ってもエラーは生じません。
code:nim
# 何もない行は左詰め
echo "hoge"
proc function():int=
# 関数定義のイコールの後、インデントする
# 複数行記述する場合、ずっとインデントしたまま
echo "foo"
return 0
for i in 0..<10:
# for 文のコロンの後、インデントする
echo "bar"
for j in 0..<10:
# 二重 (以上) にインデントすることもある
echo "baz"
改行について
前述したとおり、Nimではセミコロンを用いて複数の処理を一行に書くことができます。
code:nim
echo "hello";echo "world"
変数の宣言は複数行にすることができます。
code:nim
var res = 1 + 2 + 3 + 4 +
5 + 6 + 7 + 8
echo res
code:result
36
関数の引数や配列の宣言も複数行で記述可能です。
code:nim
echo 123,
456,
789
code:result
123456789
code:nim
var list = @[
123,
456,
789
]
echo list
code:result
問題
A薫は次の出力をするプログラムを作ろうとしました。
code:実行結果
いつも2525
AtCoderくん
しかし、書いたプログラムを実行してみるとエラーが発生しました。
A薫が書いたプログラムのエラーを修正し、正しく動作するようにしてください。
code:nim
echo "いつも2525'
echo AtCoderくん
1.03.四則演算と優先順位
キーポイント
table:演算子
演算子 計算内容
+ 足し算
- 引き算
* 掛け算
/ 割り算(実数(float))
div 割り算(整数)
mod 割った余り
^ べき乗(mathのimportが必要)
足し算・割り算・掛け算
code:nim
echo 7 + 2
echo 7 - 2
echo 7 * 2
code:result
9
5
14
演算子周りのスペースは統一する必要があります。
code:nim
echo 7+2 # ok
echo 7 + 2 # ok
echo 7+ 2 # Warning
echo 7 -2 # Compile Error!
割り算
割り算には実数用の/と、整数用のdivがあります。
code:nim
echo 7 div 2
echo 7 / 2
code:result
3
3.5
切り捨て除算の丸め方向はC++といっしょで、Pythonと異なることに注意してください。
code:nim
echo -7 div 2
echo -7 / 2
code:result
-3
-3.5
少し発展的な内容になりますが、mathモジュールにあるeuclDivを用いると、Pythonと同様の動作をする割り算を用いることができます。
code:nim
import math
echo euclDiv(-7,2)
code:result
-4
べき乗
べき乗の計算には^を用います。mathモジュールをimportする必要があります。
code:nim
import math
echo 7 ^ 2
code:result
49
剰余演算
余りはmodで計算ができます。
code:nim
echo 7 mod 2
code:result
1
modについても、divと同様にPythonとは仕様が異なることに注意してください。
code:nim
echo -11 div 5
echo -11 mod 5
code:result
-2
-1
divと同様に、Pythonと同じ振る舞いをする剰余演算がeuclModとして実装されています。
code:nim
import math
echo euclDiv(-11,5)
echo euclMod(-11,5)
code:result
-3
4
演算子の優先順序
Nimの演算子の優先順序は、以下の通りです。
table:優先順序
優先順位 演算子 最初の文字
10 $ ^
9 * / div mod shl shr % * % \ /
8 + - + - ~ |
7 & &
6 .. .
5 == <= < >= > != in notin is isnot not of as from = < > !
4 and
3 or xor
2 @ : ?
1 代入演算子(+=や*=)
0 アロー演算子(->や=>など)