Powered by SmartDoc

ソフトウェア概論A/B (2020/06/05)
Ver. 1.0

2020年6月5日
栗野 俊一
kurino@math.cst.nihon-u.ac.jp
http://edu-gw2.math.cst.nihon-u.ac.jp/~kurino/2020/soft/soft.html
ソフトウェア概論 A/B2020年6月5日 の資料

目次

講義資料

当日の OHP 資料

講議中に作成したプログラム

本日の課題

課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。

課題 CNAME-01 : 「Hanoi の塔」を解くプログラム

Download : 20200605-01.c

20200605-01.c
/*
 * 20200605-01-QQQQ.c
 *	「Hanoi の塔」を解くプログラム
 */

#include <stdio.h>
#include <string.h>

/*
 * one_to_ten ( char *n );
 *  n が、一進数 "1" 〜 "111111111" の時、十進数の 1 〜 9 に変換する
 */

void one_to_ten ( char *n ) {

	if ( !strcmp ( n, "" ) ) {
	 	printf ( "0" );
	} else if ( !strcmp ( n, "1" ) ) {
	 	printf ( "1" );
	} else if ( !strcmp ( n, "11" ) ) {
	 	printf ( "2" );
	} else if ( !strcmp ( n, "111" ) ) {
	 	printf ( "3" );
	} else if ( !strcmp ( n, "1111" ) ) {
	 	printf ( "4" );
	} else if ( !strcmp ( n, "11111" ) ) {
	 	printf ( "5" );
	} else if ( !strcmp ( n, "111111" ) ) {
	 	printf ( "6" );
	} else if ( !strcmp ( n, "1111111" ) ) {
	 	printf ( "7" );
	} else if ( !strcmp ( n, "11111111" ) ) {
	 	printf ( "8" );
	} else if ( !strcmp ( n, "111111111" ) ) {
	 	printf ( "9" );
	} else {
	 	printf ( "?" );
	}

}


/*
 * move ( char *n, char *f, char *t )
 *	幅 n の円盤を、f から t に移動する
 */

void move ( char *n, char *f, char *t ) {

	/* 画面に 「棒 f から、円盤 (n) を、棒 t に移動 」と出力する */

	printf ( f );
	printf ( " から、" );
	printf ( "円盤 (" );
	one_to_ten ( n );
	printf ( ")" );

	/*
	**	 この部分を完成させなさい
	*/

	printf ( " に移動\n" );

}

/*
 * hanoi ( char *n, char *f, char *t, char *w )
 *   高さ n の塔を f から t へ w を利用して、移動する
 */

void hanoi ( char *n, char *f, char *t, char *w ) {

	if ( !strcmp ( n, "" ) ) {		/* 高さ 0 の塔 */
		/* 何もしなくて良い (動かすものはない) */
	} else {
		/* f にある n-1 の塔 を、一旦 w に移動する (この時、t を作業場として利用可能) */
		hanoi ( n + 1, f, w, t );
		/* f に、長さ n の円盤があるので、これを t に移動 */
		move ( n, f, t );
		/* w にある n-1 の塔 を、t に移動する (この時、f を作業場として利用可能) */

	/*
	**	 この部分を完成させなさい
	*/

	}

}

/*
 * main
 */

int main ( void ) {

	printf ( "高さ 3 の「Hanoi の塔」\n" );
	hanoi ( "111", "棒 1", "棒 2", "棒 3" );

	printf ( "------\n" );
	printf ( "高さ 5 の「Hanoi の塔」\n" );

	/*
	**	 この部分を完成させなさい
	*/


	return 0;
}
20200605-01.c の実行結果
$ ./20200605-01-QQQQ.exe
高さ 3 の「Hanoi の塔」
棒 1 から、円盤 (1) を、棒 2 に移動
棒 1 から、円盤 (2) を、棒 3 に移動
棒 2 から、円盤 (1) を、棒 3 に移動
棒 1 から、円盤 (3) を、棒 2 に移動
棒 3 から、円盤 (1) を、棒 1 に移動
棒 3 から、円盤 (2) を、棒 2 に移動
棒 1 から、円盤 (1) を、棒 2 に移動
------
高さ 5 の「Hanoi の塔」
棒 1 から、円盤 (1) を、棒 2 に移動
棒 1 から、円盤 (2) を、棒 3 に移動
棒 2 から、円盤 (1) を、棒 3 に移動
棒 1 から、円盤 (3) を、棒 2 に移動
棒 3 から、円盤 (1) を、棒 1 に移動
棒 3 から、円盤 (2) を、棒 2 に移動
棒 1 から、円盤 (1) を、棒 2 に移動
棒 1 から、円盤 (4) を、棒 3 に移動
棒 2 から、円盤 (1) を、棒 3 に移動
棒 2 から、円盤 (2) を、棒 1 に移動
棒 3 から、円盤 (1) を、棒 1 に移動
棒 2 から、円盤 (3) を、棒 3 に移動
棒 1 から、円盤 (1) を、棒 2 に移動
棒 1 から、円盤 (2) を、棒 3 に移動
棒 2 から、円盤 (1) を、棒 3 に移動
棒 1 から、円盤 (5) を、棒 2 に移動
棒 3 から、円盤 (1) を、棒 1 に移動
棒 3 から、円盤 (2) を、棒 2 に移動
棒 1 から、円盤 (1) を、棒 2 に移動
棒 3 から、円盤 (3) を、棒 1 に移動
棒 2 から、円盤 (1) を、棒 3 に移動
棒 2 から、円盤 (2) を、棒 1 に移動
棒 3 から、円盤 (1) を、棒 1 に移動
棒 3 から、円盤 (4) を、棒 2 に移動
棒 1 から、円盤 (1) を、棒 2 に移動
棒 1 から、円盤 (2) を、棒 3 に移動
棒 2 から、円盤 (1) を、棒 3 に移動
棒 1 から、円盤 (3) を、棒 2 に移動
棒 3 から、円盤 (1) を、棒 1 に移動
棒 3 から、円盤 (2) を、棒 2 に移動
棒 1 から、円盤 (1) を、棒 2 に移動
$ 

課題 CNAME-02 : 「砂漠の旅行」を解くプログラム

Download : 20200605-02.c

20200605-02.c
/*
 * 20200605-02-QQQQ.c
 *	「砂漠の旅行」を解くプログラム
 */

#include <stdio.h>
#include <string.h>

/*
 * step()
 *	手持ちが 3 の時、一つ進んで、食料を置き、戻って来る
 */

void step ( void ) {

	printf ( "一つ進む\n" );
	printf ( "一つ置く\n" );
	printf ( "一つ戻る\n" );
}

/*
 * forward ( char *n )
 *	n だけ、道に置かれている食料を消費しながら進む
 */

void forward ( char *n ) {

	 if ( !strcmp ( n, "" ) ) {
		/* 最初に三つ拾う */
	 	printf ( "三つ拾う\n" );
	 } else {
		/* n - 1 だけ進み */

	/*
	**	 この部分を完成させなさい
	*/


		/* 最後の一歩 */
		printf ( "一つ進む\n" );
	 	printf ( "一つ拾う\n" );
	 }
}

/*
 * back ( char *n )
 *	n だけ、道に置かれている食料を消費しながら戻る
 */

void back ( char *n ) {

	 if ( !strcmp ( n, "" ) ) {
	 	/* なにもしない */
	 } else {
		/* 最初の一歩 */

	/*
	**	 この部分を完成させなさい
	*/


		/* n - 1 だけ戻る */
		back ( n + 1 );
	 }
}


/*
 * stocks ( char *n )
 *   1 〜 n の場所に食料を置く
 */

void stocks ( char *n ) {

	if ( !strcmp ( n, "" ) ) {
		/* 何もしなくてよい */
	} else {
		/* n の場所に食料を置く */
		stock ( n );
		/* 1 〜 n - 1 の場所に食料を置く */

	/*
	**	 この部分を完成させなさい
	*/

	}
}

/*
 * stock ( char *n )
 *   n の場所に食料を置く
 */

void stock ( char *n ) {

	if ( !strcmp ( n, "1" ) ) {
	 	printf ( "三つ拾う\n" );
		step();
	} else {
		/* 行って帰るために、1 〜 n - 1 までに二つずつ食料を置く */
		stocks ( n + 1 );
		stocks ( n + 1 );

		/* 食べながら、n - 1 まで進む */

	/*
	**	 この部分を完成させなさい
	*/

		/* n に食料を置く */
		step();
		/* 食べながら、n - 1 から戻る */
		back ( n + 1 );
	}

}

/*
 * walk ( char *g )
 *   g の場所に旅をしたい
 */

void walk ( char *g ) {

	/* g は 4 以上を想定している */

	/* g - 3 まで、片道を作る */
	stocks ( g + 3 );

	/* g - 3 まで、食料を拾いながら進む */
	forward ( g + 3 );

	/* 最後の 3 ステップは、手持ちを消費しつつ進む */
	printf ( "一つ進む\n" );
	printf ( "一つ進む\n" );
	printf ( "一つ進む\n" );

}

/*
 * main
 */

int main ( void ) {

	printf ( "4 まで行く\n" );
	walk ( "1111" );

	printf ( "6 まで行く\n" );
	walk ( "111111" );

	return 0;
}
20200605-02.c の実行結果
$ ./20200605-02-QQQQ.exe
4 まで行く
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ拾う
一つ進む
一つ進む
一つ進む
6 まで行く
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ拾う
一つ進む
一つ置く
一つ戻る
一つ戻る
一つ拾う
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ拾う
一つ進む
一つ置く
一つ戻る
一つ戻る
一つ拾う
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ拾う
一つ進む
一つ拾う
一つ進む
一つ置く
一つ戻る
一つ戻る
一つ拾う
一つ戻る
一つ拾う
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ拾う
一つ進む
一つ置く
一つ戻る
一つ戻る
一つ拾う
三つ拾う
一つ進む
一つ置く
一つ戻る
三つ拾う
一つ進む
一つ拾う
一つ進む
一つ拾う
一つ進む
一つ拾う
一つ進む
一つ進む
一つ進む
$