第05回 繰り返し:while文

前回の復習

繰り返し:while文

繰り返しはプログラムに多大な表現力をもたらします。 繰り返しで覚えるべきことは極僅かです。 while文は繰り返し構文の一つです。 while文の読み下し文は以下の通りです。

表記 ふりがな
while ( [条件式] ) {
 [処理]
}
[条件式] が真である限り以下を繰り返せ
{
 [処理]
}

while文の実行順序に注意しましょう。 はじめに [条件式] が評価されます。 その次に [処理] が実行され、 [処理] が終わった後また [条件式] が評価されます。 [条件式] が真である間 [処理][条件式] の評価が交互に行われます。 [条件式] が真でなくなれば繰り返しを脱出します。

以下のプログラムで、while文の実行順序を確認しましょう。 プログラムの開始から終了までの間に(1)〜(5)の箇所を通る順に並べてみましょう。 同じ番号のところが複数回出現します。

int i = 0; /* (1) */
while (i < 3 /* (2) */) {
  println(i); /* (3) */
  i += 1; /* (4) */
}
println("finish"); /* (5) */

まず、プログラムを理解するために読み下し文を作成しましょう。 読み下し文は以下の通りになります。

整数型の変数iを作成し、整数0で初期化しろ
変数iの値が整数3より小さいの真偽が真である限り以下を繰り返せ
{
  変数iの値を表示しろ
  変数iの値に整数1を足した結果を変数iに代入しろ
}
文字列「finish」を表示しろ

プログラムの実行結果は以下の通りになります。

0
1
2
finish

プログラムの実行にあたって、処理の実行順序は以下の通りとなります。

(1)
(2)
(3)
(4)
(2)
(3)
(4)
(2)
(3)
(4)
(2)
(5)

正しく予想できましたか? 間違っていたら、何が違ったか復習しておきましょう。

while文の [処理] 中には、これまで学修してきた逐次処理や条件分岐、while文を書くことができます。 新しい文法が出てくることはありません。 これまでの学修内容を総動員して問題に取り組みましょう。

授業内課題05-1

以下のプログラムについて、1. 読み下し文を作成し、2. (1)〜(7)を実行順に書き出し、 3. 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。

int i = 0; /* (1) */
while (i < 5 /* (2) */) {
  if (i % 2 == 0 /* (3) */) {
    println(i + "は偶数です"); /* (4) */
  } else {
    println(i + "は奇数です"); /* (5) */
  }
  i += 1; /* (6) */
}
println("finish"); /* (7) */

授業内課題05-2

以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。

size(800, 400);
int x = 0;
int y = height / 2;
int w = 60;
while (x < width) {
  ellipse(x + w / 2, y, w, w);
  x += w;
}

授業内課題05-3

任意のサイズに初期化された画面に対して、直径dの円を敷き詰めるプログラムを作成せよ。 円の一部が画面内に映る場合は画面に描画すること。

fig01

授業内課題05-4

1回の判定毎に10%の確率で「当たり」、残り90%の確率で「外れ」と出力する処理を、「当たり」出力されるまで繰り返すプログラムを作成せよ。

授業内課題05-5

左端が画面の左端と接する直径10の円から始まり、ある円の右側の円は左側の円よりも倍の直径を持ち、かつ、円同士は画面の高さの半分のy座標で接する下図のような図形を描画するプログラムを作成せよ。

fig02

まとめ

  • while文による繰り返し(ループ)処理
  • これまでの内容との組み合わせが重要なので、復習もしっかりしておきましょう
  • 繰り返しが入ると処理の流れが複雑になるので、一つ一つ処理をトレース(追跡)できるようになりましょう

解答例

授業内課題05-1

以下のプログラムについて、1. 読み下し文を作成し、2. (1)〜(7)を実行順に書き出し、 3. 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。

int i = 0; /* (1) */
while (i < 5 /* (2) */) {
  if (i % 2 == 0 /* (3) */) {
    println(i + "は偶数です"); /* (4) */
  } else {
    println(i + "は奇数です"); /* (5) */
  }
  i += 1; /* (6) */
}
println("finish"); /* (7) */

読み下し文

整数型の変数iを作成し、整数0で初期化しろ
変数iの値が整数5より小さいの真偽が真である限り以下を繰り返せ
{
  もし変数iの値を整数2で割った余りが整数0と等しいの真偽が真ならば以下を実行しろ
  {
    変数iの値に文字列「は偶数です」を足した結果を表示しろ
  }
  そうでなければ以下を実行しろ
  {
    変数iの値に文字列「は奇数です」を足した結果を表示しろ
  }
  変数iの値に整数1を足した結果を変数iに代入しろ
}
文字列「finish」を表示しろ

実行順序

(1)
(2)
(3)
(4)
(6)
(2)
(3)
(5)
(6)
(2)
(3)
(4)
(6)
(2)
(3)
(5)
(6)
(2)
(3)
(4)
(6)
(2)
(7)

実行結果

0は偶数です
1は奇数です
2は偶数です
3は奇数です
4は偶数です
finish

授業内課題05-2

以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。

size(800, 400);
int x = 0;
int y = height / 2;
int w = 60;
while (x < width) {
  ellipse(x + w / 2, y, w, w);
  x += w;
}

読み下し文

画面の幅を 整数800 に、高さを 整数400 に設定しろ
整数型の変数xを作成して、整数0で初期化しろ
整数型の変数yを作成して、Windowの高さを整数2で割った結果で初期化しろ
整数型の変数wを作成して、整数60で初期化しろ
変数xの値がWindowの幅より小さいの真偽が真である限り以下を繰り返せ
{
  中心の座標を( 変数xの値に変数wの値を整数2で割った結果を足した結果 , 変数yの値 )とした幅変数wの値 、高さ 変数wの値 の楕円を描画しろ
  変数xの値に変数wの値を足した結果を変数xに代入しろ
}

実行結果

fig03

授業内課題05-3

任意のサイズに初期化された画面に対して、直径dの円を敷き詰めるプログラムを作成せよ。 円の一部が画面内に映る場合は画面に描画すること。

fig01

解答例

size(400, 400);
int y = 0;
int d = 60;
while (y < height) {
  int x = 0;
  while (x < width) {
    ellipse(x + d / 2, y + d / 2, d, d);
    x += d;
  }
  y += d;
}

授業内課題05-4

1回の判定毎に10%の確率で「当たり」、残り90%の確率で「外れ」と出力する処理を、「当たり」出力されるまで繰り返すプログラムを作成せよ。

解答例

boolean hit = false;
while (!hit) {
  if (random(1) < 0.1) {
    println("当たり");
    hit = true;
  } else {
    println("外れ");
  }
}

別解

float p = random(1);
while (p >= 0.1) {
  println("外れ");
  p = random(1);
}
println("当たり");

授業内課題05-5

左端が画面の左端と接する直径10の円から始まり、ある円の右側の円は左側の円よりも倍の直径を持ち、かつ、円同士は画面の高さの半分のy座標で接する下図のような図形を描画するプログラムを作成せよ。

fig02

解答例

size(800, 400);
int x = 0;
int w = 10;
while (x < width) {
  ellipse(x + w / 2, height / 2, w, w);
  x += w;
  w *= 2;
}

授業外課題

授業外課題05-1

寿司打( http://neutral.x0.com/home/sushida/play2.html )「5000円コース」をプレイし、以下のスコアを報告せよ(スピードは任意)

  • 成績(xxx円分得 or 損した)
  • 正しく打ったキーの数
  • 平均キータイプ数(回 / 秒)
  • ミスタイプ数

授業外課題05-2

以下のプログラムについて、(1) 読み下し文を書き、(2) 実行結果を予測せよ。 プログラムを実行し予測と合っていたか確かめよ。

float total = 0;
int count = 0;
while (total < 1) {
  total += random(1);
  count += 1;
}
println(count);

授業外課題05-3

預金100万円からスタートし、毎年10万円を預金に加える。 預金の0.1%が利子として毎年預金に加えられる。 目標金額を500万円とした時に、目標金額に達するまで何年経過した時点でいくらの預金があるか表示する以下のプログラムを完成させよ。 また、完成したプログラムの読み下し文を書け

int money = 1000000;
int transfer = 100000;
float interest = 1.001;
int goal = money * 5;

正しい出力結果は以下の通りである。

1 1101100
2 1202301
3 1303603
4 1405006
5 1506511
6 1608117
7 1709825
8 1811634
9 1913545
10 2015558
11 2117673
12 2219890
13 2322210
14 2424632
15 2527156
16 2629783
17 2732513
18 2835345
19 2938280
20 3041318
21 3144459
22 3247703
23 3351050
24 3454501
25 3558055
26 3661713
27 3765475
28 3869340
29 3973309
30 4077382
31 4181559
32 4285841
33 4390227
34 4494717
35 4599312
36 4704011
37 4808815
38 4913724
39 5018738

授業外課題05-4

任意の正の整数nに対して、以下の操作を繰り返すと必ず1に到達することが予測されている。(コラッツの予想)

  • nが偶数の場合、nを2で割る
  • nが奇数の場合、nに3を掛けて1を足す

プログラムの先頭で整数型の変数nを宣言・初期化し、上記の操作を適用して得られる数列をnが1になるまで出力するプログラムを作成せよ。 また、完成したプログラムの読み下し文を書け。

n=100の時の出力結果は以下の通りである。

50
25
76
38
19
58
29
88
44
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1

授業外課題05-5

画面を任意のサイズに初期化し、画面中を同じサイズの正方形で左上から順に敷き詰めるプログラムを作成せよ。 正方形が一部でも画面内に入る場合は描画すること。 また、正方形の左上の座標が、画面の左下と右上を結ぶ対角線より下側(線上も含む)にある正方形は赤色、そうでなければ白色で塗ること。 画面のサイズと正方形のサイズを変更しても正しく動作するようにせよ。

画面の幅400、高さ400、正方形のサイズ40の時の実行結果

fig04

画面の幅400、高さ800、正方形のサイズ40の時の実行結果

fig05

画面の幅400、高さ400、正方形のサイズ30の時の実行結果

fig06

results matching ""

    No results matching ""