2000年9月8日更新(新規作成)
  関谷トップページへ アプリケーション演習トップページへ   アプリケーション演習No.14 C言語プログラミング ページへ  

ハノイの塔(中津山-Cプログラミング入門、p.66-68)改造版

/* p4_7.c, 2000.9.8, KPC sekiya, 中津山-Cプログラミング入門、p.66-68 */
/* ハノイの塔(中津山-Cプログラミング入門、p.66-68)改造版 */

/* 考察
制御構造を単純にした。メッセージに呼ばれた時・移した後・戻る時などを追加した。
*/

/* プログラム仕様
・入力:円盤の枚数。
・処理:再帰処理(文字列を使って表示する)
・出力:円盤の状態
*/

#include <stdio.h>

void movet(int level, int n, char s[], char t[], char w[]);

main()
{
	int i, n, level = 0;
	char s[11], t[11], w[11];
	char str[30];
			
	printf("p4_7.c, 2000.9.7, KPC sekiya\n");
	printf(" ハノイの塔(再帰での棒の引数の順序は、移動元、移動先、作業用)\n");
	printf(" 円盤の枚数を入力->");

	scanf("%d", &n);
	for(i = 0;i <= n; ++i)
		s[i] = '1' + i - 1;
	t[1] = w[1] = s[i] = '\0';	// end of strings
	s[0] = 's';
	w[0] = 'w';
	t[0] = 't';
	printf("\n開始時:%s\n", s);
	movet(level, n, s, t, w);
	printf("\n完了時:%s\n", t);
}

void movet(int level, int n, char s[], char t[], char w[])
{
	int gs,gt,gw,c,i;
	
	if( n > 0) {
		++level;
		for (i = 1; i < level; i++)
			printf("    ");
		printf("level:%d 呼ばれた時 %s %s %s\n", level, s, t, w);

		gs = strlen(s);
		c = s[--gs];
		s[gs] = '\0';
		movet(level, n-1, s, w, t);
			/* n-1 枚をsからwへ移す */

		gt = strlen(t);
		for(i = gt; i>0; i--)
			t[i+1] = t[i];
		t[1] = c;
		for (i = 1; i < level; i++)
			printf("    ");
		printf("level:%d, 移した後 %s %s %s", level, s, t, w);
		printf(",  %d番目を%cから%cへ。\n", n, s[0], t[0]);	
			
		movet(level, n-1, w, t, s);
		
		for (i = 1; i < level; i++)
			printf("    ");
		printf("level:%d 元に戻る時  %s %s %s\n", level, s, t, w);
		level--;
	}
}
/* 実行結果

p4_7.c, 2000.9.7, KPC sekiya
 ハノイの塔(再帰での棒の引数の順序は、移動元、移動先、作業用)
 円盤の枚数を入力->
開始時:s123
level:1 呼ばれた時 s123 t w
    level:2 呼ばれた時 s12 w t
        level:3 呼ばれた時 s1 t w
        level:3, 移した後 s t1 w,  1番目をsからtへ。
        level:3 元に戻る時  s t1 w
    level:2, 移した後 s w2 t1,  2番目をsからwへ。
        level:3 呼ばれた時 t1 w2 s
        level:3, 移した後 t w12 s,  1番目をtからwへ。
        level:3 元に戻る時  t w12 s
    level:2 元に戻る時  s w12 t
level:1, 移した後 s t3 w12,  3番目をsからtへ。
    level:2 呼ばれた時 w12 t3 s
        level:3 呼ばれた時 w1 s t3
        level:3, 移した後 w s1 t3,  1番目をwからsへ。
        level:3 元に戻る時  w s1 t3
    level:2, 移した後 w t23 s1,  2番目をwからtへ。
        level:3 呼ばれた時 s1 t23 w
        level:3, 移した後 s t123 w,  1番目をsからtへ。
        level:3 元に戻る時  s t123 w
    level:2 元に戻る時  w t123 s
level:1 元に戻る時  s t123 w

完了時:t123
*/