5日目 | Nim100日ドリル
~繰り返しその1~

今日の目標

今日は、同じ処理を何度も実行するための基本である for 文を学ぶ。
まず、for 文を使って「1回ずつ数を変えながら処理する」考え方を身につける。
次に、1..10 のような範囲演算子を使い、1から10まで表示したり、1から10までの合計を求めたりできるようにする。
最後に、九九の一段を出力する練習を通して、「決まった回数だけ同じ形の処理を繰り返す」感覚を固める。

今日の内容

5ー1 ~for 文は、同じ処理を繰り返すための書き方である~

プログラムでは、同じような処理を何度も書きたい場面が多い。
たとえば、1から10までの数字を画面に表示したいとき、echo 1echo 2echo 3 と10行書くこともできる。
しかし、この書き方は数が増えるほど面倒になり、変更にも弱くなる。
1から100まで表示したくなっただけで、100行分の echo を書く必要が出てしまう。

そこで使うのが for 文である。
for 文は、「ある範囲の中から値を1つずつ取り出して、そのたびに同じ処理を実行する」ための構文である。
Nimでは次のように書く。

                    
for i in 1..10:
  echo i
                    
                

このコードでは、i に1、2、3と順番に値が入り、最後に10が入る。
echo i はそのたびに実行されるため、結果として1から10までが順番に表示される。
ここでの i は、繰り返しの中で現在の値を受け取るための変数である。
数学でよく使う i という名前にしているだけで、numcount のような名前にしてもよい。

Nim特有の注意点として、for の行末にはコロン : が必要である。
また、繰り返したい処理は次の行にインデントして書く。
インデントとは、行の先頭に空白を入れて右にずらすことである。
Nimではインデントが文のまとまりを表すため、ここが崩れると正しく動かない。
初心者は for の次の行を左端に戻してしまいがちだが、繰り返したい処理は必ず for より内側に字下げする必要がある。

よくあるミスは、コロンを書き忘れること、インデントをそろえないこと、変数名を間違えることである。
たとえば for i in 1..10: と書いたのに、次の行で echo n と書くと、n という変数は存在しないため未宣言識別子のエラーになる。
for で受け取った名前と、処理の中で使う名前は一致させる必要がある。

5ー2 ~範囲演算子 .. は、最初から最後までの整数列を表す~

Nimでは、1..10 のように書くと、1から10までの範囲を表す。これを範囲演算子と呼ぶ。
たとえば for i in 1..10: と書くと、i には1から10までの整数が順番に入る。ここで重要なのは、Nimの .. は最後の数も含むという点である。
つまり、1..10 は1以上10以下であり、10も含まれる。

この考え方は、回数を決めて処理したいときにとても重要である。たとえば、九九では1から9までを順番に使う。
したがって、for i in 1..9: と書けば、1、2、3、4、5、6、7、8、9の9回分の処理を自然に表せる。

                    
var total = 0

for i in 1..10:
  total = total + i

echo total
                    
                

このコードの読み方として、まず var total = 0 は合計を入れるための変数を0で用意している。
次に、for i in 1..10: で1から10までの数を順番に取り出している。
そして、total = total + i で現在の合計に i を足し直している。
最後の echo total はインデントされていないため、繰り返しがすべて終わったあとに1回だけ実行される。

範囲演算子は、開始値と終了値の順番に注意が必要である。
基本的には小さい数から大きい数へ進む形で 1..10 のように書く。最初の段階では、10..1 のような逆向きの範囲は使わないほうがよい。
逆順の処理には別の書き方があるため、まずは「小さい数から大きい数へ順に回す」と覚えておけばよい。

範囲演算子は、整数だけでなく文字にも使える。
たとえば for c in 'a'..'z': と書くと、c にはアルファベットの小文字が順番に入る。
文字の範囲も最後の文字を含むため、'a'..'z' は a から z までの26文字を表す。

5ー3 ~合計や九九は、「変わる値」と「同じ処理」を分けて考える~

繰り返しを使うときは、「毎回変わる値」と「毎回同じ形で行う処理」を分けて考えると理解しやすい。
1から10まで表示する場合、毎回変わるのは i の値である。一方、毎回同じなのは echo i で表示するという処理である。

合計を求める場合も同じである。
1から10までの合計を求めるには、合計を入れておく変数を用意し、繰り返しのたびに現在の数を足していく。
Nimでは、あとから値を変える変数には var を使う。

                    
var total = 0
for i in 1..10:
  total = total + i
echo total
                    
                

このコードでは、最初に total を0にしておく。
そのあと、i が1のときに total に1を足し、i が2のときに2を足し、という処理を10まで繰り返す。
最後に echo total で合計を表示する。

ここでよくあるミスは、totallet で作ってしまうことである。
let は一度決めた値を変えないときに使う。
合計のように何度も値を更新する変数には var を使う必要がある。
また、total = total + i の行をインデントし忘れると、繰り返しの中で実行されなくなる。
Nimではインデントが処理の範囲を決めるため、合計を足す行は必ず for の内側に置く。

九九も同じ考え方で作れる。
たとえば3の段なら、段の数である3は固定で、かける数である1から9が変わる。
つまり、固定値と変化する値を組み合わせて、同じ形の出力を9回行えばよい。

                    
let dan = 3

for i in 1..9:
  echo dan, " x ", i, " = ", dan * i
                    
                

このコードの読み方として、まず let dan = 3 は、今回は3の段を出すという固定値を用意している。
次に、for i in 1..9: は、かける数を1から9まで変化させている。
そして、echo dan, " x ", i, " = ", dan * i は、式の形と計算結果を一緒に表示している。
Nimの echo はカンマで複数の値を並べられるため、整数と文字列を無理に & で結合しなくてもよい。
初心者のうちは、この書き方のほうが型変換で詰まりにくい。

課題1

この問題では、for 文を使って1から5までの数字を順番に表示する。穴埋め箇所 ____ に入る範囲を書き、標準出力が期待どおりになるようにする。
ファイル名は day5.nim とし、実行コマンドは nim r day5.nim を使う。

                    
for i in ____:
  echo i
                    
                

期待される出力は次のとおりである。

                    
1
2
3
4
5
                    
                

ヒントとして、Nimで1から5までの範囲を表すには、開始の数と終了の数を .. でつなぐ。
1..5 は1から5までを意味し、5も含まれる。1...5 のように点を3つにしたり、1-5 のようにハイフンを使ったりしないこと。

課題2

次の問題では、出発コードを改造して、1から20までの合計を表示するプログラムにする。
現在のコードは1から10までの合計を求めるようになっているため、必要な部分だけを変更する。

                    
var total = 0

for i in 1..10:
  total = total + i

echo total
                    
                

期待される出力は次のとおりである。

                    
210
                    
                

ヒントとして、合計の入れ物である total の考え方はそのままでよい。
変更すべきなのは、for 文で回す範囲である。1から20まで足したいなら、i が1から20まで変化するように範囲を直す必要がある。
echo total は繰り返しの外に置く。
ここを for の内側に入れてしまうと、途中経過が何行も表示されてしまい、自動採点では不合格になりやすい。

課題3

この問題では、九九の7の段を出力するプログラムを作る。
入力は、ソースコード内で dan に7を入れることとする。
処理では、1から9までの数を順番に取り出し、7 x 1 = 7 のような形で計算結果を作る。
出力では、7の段を1行ずつ、合計9行で表示する。

                    
let dan = ____

for i in ____:
  echo dan, " x ", i, " = ", ____
                    
                

期待される出力は次のとおりである。

                    
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
                    
                

よくあるエラーの一つは、文字列結合で整数をそのままつなごうとすることである。
たとえば、次のように書くと、文字列と整数の型が合わずにエラーになることがある。

                    
echo dan & " x " & i
                    
                

この場合、dani は整数であり、" x " は文字列である。
Nimでは型を勝手に混ぜて文字列結合できない。
今回のような表示では、echo dan, " x ", i のようにカンマで分けて書くのが簡単である。
どうしても文字列として結合したい場合は $dan$i のように文字列へ変換する必要があるが、Day5ではまだカンマ区切りの echo を使えば十分である。

もう一つのよくあるミスは、for i in 1..9: の下の echo をインデントし忘れることである。
echofor の内側にないと、繰り返しの処理として扱われない。
Nimではインデントが処理のまとまりを決めるため、for の中で実行したい行は必ず右にずらす。

今日のまとめ

今日は、for 文を使って同じ処理を繰り返す方法を学んだ。
for i in 1..10: と書くと、i に1から10までの数が順番に入り、そのたびに内側の処理が実行される。
Nimの範囲演算子 .. は最後の数も含むため、1..10 は10まで到達する。
合計を求めるときは、var total = 0 のように更新できる変数を用意し、繰り返しの中で total = total + i と足していく。
九九を出すときは、段の数を固定し、かける数だけを for 文で変化させればよい。





4日目へ

6日目へ

トップへ戻る


お問い合わせ