2016年 春期 応用情報技術者試験 問3

ライフゲーム

ライフゲームとは,数学者コンウェイが考案した,生命の誕生,生存,死滅などを再現したシミュレーションゲームである。マス目状の盤上の各マスに生命が存在でき,そのマス自身及び隣接するマスの状態によって次世代の誕生,生存,死滅が決まる。その条件を表1に示す。

なお,隣接するマスには,斜め方向のマスも含む。また,生命が存在するマスを"生のマス",生命が存在しないマスを"死のマス"と呼ぶ。

表1 誕生,生存,死滅の条件
条件名条件
誕生死のマスに隣接する生のマスが三つならば,死のマスは次の世代では生のマスとなる。
(死のマスに隣接する生のマスが三つ以下又は四つ以上ならば,死のマスは次の世代でも死のマスである。)
生存生のマスに隣接する生のマスが二つ又は三つならば,生のマスは次の世代でも生のマスである。
過疎生のマスに隣接する生のマスが一つ以下ならば,生のマスは過疎によって次の世代では死のマスとなる。
過密生のマスに隣接する生のマスが四つ以上ならば,生のマスは過密によって次の世代では死のマスとなる。

【4×4マスのシミュレーション】

4×4マスの盤上における第3世代までのシミュレーションを図1に示す。

<figure>
  <div style="display: flex; justify-content: space-between; align-items: center;">
    <div style="text-align: center;">
      <div style="border: 1px solid black; display: inline-block;">
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
      </div>
      <p>第1世代</p>
    </div>

    <div style="font-size: 24px;">→</div>

    <div style="text-align: center;">
      <div style="border: 1px solid black; display: inline-block;">
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
      </div>
      <p>第2世代</p>
    </div>

    <div style="font-size: 24px;">→</div>

    <div style="text-align: center;">
      <div style="border: 1px solid black; display: inline-block;">
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">ア</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">イ</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">ウ</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
        <div style="display: flex;">
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">○</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">エ</span>
          <span style="border: 1px solid black; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;">×</span>
        </div>
      </div>
      <p>第3世代</p>
    </div>
  </div>
  <div style="margin-top: 10px;">
    <p><strong>凡例</strong></p>
    <p>○…生のマス</p>
    <p>×…死のマス</p>
  </div>
  <figcaption>図1 4×4マスの盤上における第3世代までのシミュレーション</figcaption>
</figure>

第1世代は,初期値として設定されたものである。例として,第1世代の2行目1列目のマスを考える。現在,このマスは死のマスである。このマスに隣接するマスを網掛けで示す。これら五つのマスの中に生のマスが三つある。これは表1の"誕生"の条件に該当するので,第2世代の2行目1列目のマスは生のマスになる。同様に,第1世代の各マスについて,そのマス自身及び隣接するマスの状態を確認することで第2世代が決まる。次の世代への状態の更新は,全てのマスについて同時に行われる。

【盤上のマスのデータ構造】

N×Nマスの盤上の状態を表現するデータ構造を考える。多次元配列が利用できないプログラム言語を考慮し,盤上の各マスの生死状態を管理するデータ構造として1次元配列mを用いる。配列mのデータ構造のイメージを図2に示す。

<figure>
  <div style="text-align: center;">
    <div style="border: 1px solid black; display: inline-block;">
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">列</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">1</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">2</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">j</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">N</div>
      </div>
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">1</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">m[1]</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">m[2]</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">m[N]</div>
      </div>
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">2</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">m[N+1]</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">m[2×N]</div>
      </div>
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">⋮</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">...</div>
      </div>
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">行</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">m[<span class="blank-box">オ</span>]</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">...</div>
      </div>
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">k</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">...</div>
      </div>
      <div style="display: flex; border-bottom: 1px solid black;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">⋮</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">...</div>
      </div>
      <div style="display: flex;">
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">N</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center; border-right: 1px solid black;">...</div>
        <div style="width: 40px; text-align: center;">m[N×N]</div>
      </div>
    </div>
  </div>
  <figcaption>図2 配列mのデータ構造のイメージ</figcaption>
</figure>

【配列mを次世代に更新するプログラム】

使用する定数,配列及び関数を表2に,配列mを次世代に更新する関数updateを図3に示す。

なお,関数に配列を引数として渡すときの方式は参照渡しである。

表2 使用する定数,配列及び関数
名称種類説明
N定数盤の一辺の大きさ。3以上の整数が入る。
m配列N×Nマスの生死状態を管理する1次元配列。生の場合は1が,死の場合は0が入る。
temp配列配列mと同じ大きさの1次元配列。
copy(array1, array2)関数配列array1の全ての要素を配列array2にコピーする。
clear(array)関数配列arrayの全ての要素の値を0にする。
function update(m)
    copy(m, temp)      // 配列mを配列tempにコピーして退避する
    clear(m)           // 配列mの全ての要素の値を0にする
    for( iを1からN×Nまで1ずつ増やす )
    
        if( i-1がNで割り切れる )    ┐
            a ← 0                   │
            b ← 1                   │
        elseif( iが1がNで割り切れる ) ├ α
            a ← -1                  │
            b ← 0                   │
        else                        │
            a ← -1                  │
            b ← 1                   │
        endif                       ┘
        
        e ← 0
        for( yを-1から1まで1ずつ増やす )
            for( xをaからbまで1ずつ増やす )
                if( (yと0が等しくない) or (xと0が等しくない) )
                    c ← i + y×N + x
                    if( (cが1以上) and (cがN×N以下) )
                        if(  )
                            e ← e+1
                        endif
                    endif
                endif
            endfor
        endfor
        
        // 生死を判定する
        if(  )
            m[i] ← 1
        elseif(  )
            
        endif
        
    endfor
endfunction
図3 関数updateのプログラム

【テストプログラム】

図3のプログラムをテストするために,配列mに第1世代が与えられたときの第p世代が,机上で作成した正しい結果である配列rと等しいことを確認するプログラムを作成した。作成した関数shouldBeを図4に示す。ここで,pには2以上の整数が入る。

1: function shouldBe( m, p, r )
2:     for( iを1からpまで1ずつ増やす )
3:         update(m)
4:     endfor
5:     for( iを1からN×Nまで1ずつ増やす )
6:         if( m[i]とr[i]が等しくない )
7:             return false    // テスト失敗
8:         endif
9:     endfor
10:    return true           // テスト成功
11: endfunction
図4 関数shouldBeのプログラム

図3のプログラムが正しく動作する状態で図4のプログラムを実行したところ,テストが失敗した。原因を調査した結果,図4の行目に問題があることが判明したので,①プログラムを修正してテストを成功させることができた。

設問1 図1中のに入れる適切な生死状態を,図1の凡例に倣い答えよ。

設問2 図2中のに入れる適切な字句を答えよ。

設問3 図3中のに入れる適切な字句を答えよ。

設問4 図3中のαの二つの条件のいずれかを満たすのはどのような場合か。単語"盤"及び"マス"を用いて30字以内で述べよ。

設問5 【テストプログラム】について,(1),(2)に答えよ。

(1) 本文中のに入れる適切な数値を答えよ。

(2) 本文中のの修正後の行目のプログラムを答えよ。

出典:平成28年度 春期 応用情報技術者試験 午後問題