[問題]
チェス盤上に、1 から n までの番号が割り振られた n 匹のアリがいるとする(画像参照→ チェス盤には横に w 個、縦に h 個のマスがあり、左上隅を白として、白黒のマス目が交互に並んでいる。
初期状態では、どのアリも盤上のいずれかのマスの中にいて、右または下を向いており、一マスの中に複数のアリは居なかったものとする。 (図の例だと、チェス盤のサイズが横 5、縦 4 であり、3 匹のアリが (4,1), (1,4), (5,3) にいる。)
時間が1ステップ進むごとに、すべてのアリはその向いている方向に1マス移動する。移動先がチェス盤の外に出たら、アリは姿を消すとする。
盤上で2匹のアリが同じマスに入った時、アリは以下のような行動をとる。
2匹のアリがいるマスの色が白なら、右を向いていたアリは下向きに、下を向いていたアリは右向きに方向を変える。
2匹のアリがいるマスの色が黒なら、アリの向きは変わらない。
チェス盤のサイズと初期状態のアリの位置・方向の情報がファイル(名前はコマンドライン引数で指定)から与えられた時、時間とともにアリがどう動くかをシミュレーションして、何ステップ目にどのアリが盤の外に出るか表示するプログラムを作成しなさい。
なおプログラムでは、下記のリスト1のように、アリの情報を保持しておくための構造体として AntPos型を定義して、これを使用する。 アリの数の上限は決まっていないので、ファイルで指定されたアリの数に合わせて動的にメモリを確保して情報を格納すること。 使用する変数はリストに示した物で十分なはずだが、追加しても構わない。
入力ファイルは、1 行目に横のマス目の数 w、縦のマス目の数 h、アリの数 n が書かれており、2 行目から n+1 行目にアリの横方向の位置 x、縦方向の位置 y、アリの向き(右なら 'R'、下なら 'D')が与えられている。なお左上隅のマスを (x, y) = (1, 1) とし、右に向かって x が増加、下に向かって y が増加すると考える。
[テスト用入力ファイル] Antdata.txt
3 3 3
2 1 D
1 2 R
2 2 R
[実行例]
% ./a.out Antdata.txt
2 1 D
1 2 R
2 2 R
Time = 2: Ant 3 has gone out to (4,2). ←2ステップでアリNo.3が盤の外へ
Time = 3: Ant 1 has gone out to (4,2). ←3ステップでアリNo.1が盤の外へ
Time = 3: Ant 2 has gone out to (2,4). ←アリNo.2も盤の外へ[プログラム]
[回答プログラム]
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x; /* アリの位置(横) */
int y; /* アリの位置(縦) */
char dir; /* 'R'右向きか 'D'左向きか */
int in; /* 1:アリは盤上にいる 0:既に盤外に出ている */
}AntPos;
int main(int argc, char *argv[])
{
int w, h, n; /* 幅、高さ、初期状態でのアリの数 */
int t=0; /* 時間ステップのカウンタ */
int i, j, num;
AntPos *ant;
FILE *ifile;
if (argc < 2) {
printf( "error: input file name is required!\n");
exit(1);
}
/* ファイルオープン */
if ((ifile=fopen(argv[1],"r")) == NULL){
fprintf( stderr, "Cannot open data file !\n" );
exit(2);
}
/* ファイルの1行目から盤の幅w、高さh、アリの数nを読み込む */
/* アリの情報を収めておく構造体配列を動的に確保 */
/* ファイルから各アリの位置と向きを読み込む。なお、文字型を読む時は
" %c"のように%c手前にスペースを入れると、R/D手前のスペースを読み飛ばせる。
読み込めたら、確認のため読んだ情報を標準出力に出力 */
/* 1ステップごとのループ。盤上にいるアリの数が0になったら終了 */
/* 時間の更新、アリの座標の更新、アリが盤の外に出たかどうかのチェックと表示、
2匹のアリが同じマスにいるかどうかのチェックと(必要なら)向きの更新 */
.....
return 0;
}