• ベストアンサー

ハノイの塔

次のc言語で書かれたハノイの塔のプログラムをZ80で動作させたいのですが、アセンブルするとどうなるのでしょうか??教えてください。 void move(char n,char a,char b){ if(n>1)move(n-1,a,6-a-b); if(n>1)move(n-1,6-a-b,b); } int main(){ char n=5; move(n,1,2); }

質問者が選んだベストアンサー

  • ベストアンサー
noname#30727
noname#30727
回答No.2

まず、このmove関数は、事実上何もしない関数ですが、それでいいのですか? つまりmoveを呼び出す以外は何もしていないので、実行してもただ終了するだけになります。 if(n>1)は1つで十分なので、以下のように書き換えたものとします。 if (n > 1) { move(n-1, a, 6-a-b); move(n-1, 6-a-b, b); } charをunsignedとして、変数n, a, bをレジスタC, B, Eに割り当てるものとします。 ORGとか、SPの初期化、MAINの呼び出しは別途記述してください。 Z80は何年も使ってないので、間違いは簡便してください(笑 MOVE: LD A,C CP 2 JR C,MOVE_1 LD A,6 SUB B SUB E LD D,A ; Dに6-a-bを保存しておく PUSH BC PUSH DE DEC C LD E,D CALL MOVE POP DE POP BC PUSH BC PUSH DE DEC C LD B,D CALL MOVE POP DE POP BC MOVE_1: RET MAIN: LD C,5 LD B,1 LD E,2 JP MOVE

aho-3-aho
質問者

お礼

親切にありがとうございます。自分でいろいろいじってみます。

その他の回答 (1)

noname#30727
noname#30727
回答No.1

質問の意味がよくわかりません。 再帰関数moveをアセンブリで書く例が欲しいという事ですか?

aho-3-aho
質問者

補足

分かりにくてすみません。Z80で動作させたいのでアセンブリでの例が知りたいのです。

関連するQ&A

  • C言語 ハノイの塔

    #include<stdio.h> void hanoi(int n,char a,char b,char c); int main(void) { int n=3; printf("円板の枚数 ⇒ " ); hanoi(n,'a','b','c'); return 0; } void hanoi(int n,char a,char b,char c) { if(n > 0){ hanoi(n - 1,a,c,b); printf("%d番の板を %c から %c に移動\n",n,a,b); hanoi(n - 1,c,b,a); } } このときの再帰の処理がわかりません。。 再帰の間にprintfがあるのでどこがつながっているのか順番がわかりません。 具体的な数値の手順を教えてください。

  • javaハノイの塔について

    public class hanoinotou { static void move(int n,int a,int b , int c) { if(n>1) move(n-1,a,c,b); System.out.println("円盤"+n+":"+a+"→"+c); if(n>1) move(n-1,b,a,c);} public static void main(String args[]){ move(3,1,2,3); } } ↑このプログラムの動き方を教えてください よろしくお願いします

  • ハノイの塔

    ★自分が理解している事 「(n-1)ハノイが解けると仮定するとnハノイも解けること」 は理解できます。 そして数学的帰納法によりすべての自然数についてハノイは「解ける」 ここまではわかります。 ★わからないのは、その「解き方」です。 「解ける」ことはわかるのですが「解き方」がわからないのです。 何故このプログラムで正解が表示されるのかが理解できないのです。 確かに、紙と鉛筆でプログラムの流れを追っていくと解けています。 しかし、何でこのプログラムで解けるのかがわからないのです。 棒xは出発点 棒yは目的地 棒zは作業棒 です。 (n-1)ハノイをひとかたまりと考え、作業棒Zに移す。 nハノイを目的地Yに移す。 (n-1)ハノイをひとかたまりと考え、目的地Yに移す。 そんな説明で確かに納得した気になりはします。 しかしこのプログラムでは(n-2)以下の場合についてはいっさい語っていません。 何かだまされてる気がします。 このプログラムでは(n-1)について語っていますが (n-2)以下については全く語っていません。 数学的帰納法により「解ける」ことは証明済みですが、 「その解き方」がこのプログラムでよいという「証明」はありますでしょうか? 理解のコツはありますでしょうか? よろしくお願いいたします。 #include<stdio.h> #include<stdlib.h> void hanoi(int n, char x, char y, char z) { if(n==0) {/* 何もしない */} else { hanoi(n-1,x,z,y); printf("%c->%c,",x,y); hanoi(n-1,z,y,x); } } int main(void) { int num; scanf("%d",&num); hanoi(num,'A','B','C'); return 0; }

  • Java比較演算子はどちらのほうが早いですか。

    「より大きい(>)」と「以上(>=)」はどちらのほうが早いですか。 ハノイの塔の再帰を使って実験してみたところ「より大きい」が遅いという結果になりました。 より大きいは再帰が苦手?ソースが間違ってる?... などと気になったので投稿しました。 プログラミング初心者なのでお手柔らかにお願いします。 以下が使ったソースです。 public class Main{ public static void hanoi(int n, char a, char b, char c){ if(n > 0){ hanoi(n -1, a, c, b); //System.out.println(a + "から" + b + "へ"); hanoi(n -1, c, b, a); } } public static void hanoi2(int n, char a, char b, char c){ if(n >= 1 ){ hanoi(n -1, a, c, b); //System.out.println(a + "から" + b + "へ"); hanoi(n -1, c, b, a); } } public static void main(String[] args){ int count = 0; int count2 = 0; long ns = 0; long n1 = 0; long n2 = 0; while(count2 < 5){ count++; long start = System.nanoTime(); hanoi(3, 'A', 'B', 'C'); long end = System.nanoTime(); long start2 = System.nanoTime(); hanoi2(3, 'A', 'B', 'C'); long end2 = System.nanoTime(); n1 += (end -start); n2 += (end2 -start2); ns = n1 -n2; if(ns > 0) count2++; } System.out.println("「> 」平均:" +(n1 /count)+"ns"); System.out.println("「>=」平均:" +(n2 /count)+"ns"); } }

  • ハノイの塔のチェック関数

    ユニックス等のシステムコールを使ったハノイの塔を検査するプログラムです。質問したいのは円盤数、つまり塔の枚数が30枚で実行すると、チェックします。チェックされていいのですが20枚の時はされません。 なぜされるのかをおしえてください。 チェックされる条件は円盤番号が2回以上現れる。 0以外の番号の間には0がくるです。 チェック関数を抜き出すと void *Check(void *arg){ int i,nchecks=0; while(sw) { sleep(1); nchecks++; for(i=0;i<ndisks;i++) Z[i]=0; for(i=0;i<ndisks;i++){ if (A[i]!=0) { if (Z[A[i]-1]!=0) { fprintf(stderr,"Inconsistent(1)!!! (Tower-A Tries=%d)(i=%d)\n",nchecks,i); break;} Z[A[i]-1]=1; } if (B[i]!=0) { if (Z[B[i]-1]!=0) { fprintf(stderr,"Inconsistent(2)!!! (Tower-B Tries=%d)(i=%d)\n",nchecks,i); break;} Z[B[i]-1]=1; } if (C[i]!=0) { if (Z[C[i]-1]!=0) { fprintf(stderr,"Inconsistent(3)!!! (Tower-C Tries=%d)(i=%d)\n",nchecks,i); break;} Z[C[i]-1]=1; } } for(i=0;i<ndisks;i++) { if (Z[i]==0) { fprintf(stderr,"Inconsistent(4)!!! (Final Tries=%d)(i=%d)\n",nchecks,i); break;} } } }

  • ハノイの塔の問題で困っております。

    LISPの問題ですが、ハノイのプログラムはここまでできております。 > (defun hanoi (n a b c) (cond ((= n 1) (print (list "move" n "from" a "to" c))) ((> n 1) (hanoi (1- n) a c b) (print (list "move" n "from" a "to" c)) (hanoi (1- n) b a c)))) 実行結果を出すには、どんなプログラムが入力すればよいのでしょうか。 すみませんが、力を貸してください。

  • perl ハノイの塔の解に順番付けする方法

    プログラミング初心者です。 サブルーチンを用いて、ハノイの塔の解を求める課題で詰まっています。 解自体は求めることができたのですが、それぞれの解の順番(輪を移動させる順番)を一緒に表示させよという指示が出ており、この方法がわかりません。 表示順に上から番号を振るという考え方でよろしいのでしょうか。 まず考え方自体が違うようであれば、そこから指摘して頂きたいと思います。 よろしくお願いします。 ちなみに現状ではこのようになっております。 #!/usr/bin/perl sub hanoi { my ($no , $x , $y , $z) = @_; if( $no = $no){ hanoi ($no-1,$x,$z,$y); print "Move", $no ,"from" , "$x" , "to" , "$z" , "\n"; hanoi ($no-1,$y,$x,$z); } } print"入力された枚数のハノイの塔の解(順番付き)\n"; $data=<>*1; hanoi($data , "A" , "B" , "C");

  • ハノイの塔 関数内の進み方

    ■プログラムは後半に書いてます。よろしくお願いします。      no x y ――――――― 10行目 3 1 3 10行目 2 1 2 10行目 1 1 3 printf ■この後の5回(できれば10回)の進み方を教え貰えると嬉しいです。 ■わからない理由 printfのとき、(no, x, y) = (1, 1, 3)でno = 1。 そのため13行目は行われない。 しかし、returnもbreakもないためまた6行目に戻るのでしょうか?(答えを見ると6行目に行きそうです。) (no, x, y) はどのような値で関数が始まるのでしょうか? 9行目があるのにno=2or3で表示される理由がわからないです。 01|#include <stdio.h> 02|#include <conio.h> 03| 04|#define N 3 05| 06|void move(int no,int x,int y) 07|{ 08| static int i=1; 09| if(no>1) 10| move(no-1,x,6-x-y); 11| printf("%dを%d軸から%d軸へ移動 : %d\n",no,x,y,i++); 12| if(no>1) 13| move(no-1,6-x-y,y); 14|} 15| 16|int main(void) 17|{ 18| move(N,1,3); 19| 20| _getch(); 21| return(0); 22|}

  • CommonLispでハノイの塔の円盤の移動回数を数える。

    はじめまして。東吾と言います。 Lispを最近初めて、色々見ながらハノイの塔のプログラムを作ってみました。 それだけじゃ芸が無いから移動の回数を数えてみようとおもったんだけど、行き詰まってしまいました。 idouの出てきた回数を数えれば良いのは分かるんだけどうまく組みこめないんです。 よろしくお願いします。 とりあえず作ってみたハノイの塔のプログラムです。 (defun hanoi (n from to v) (if (= n 1) (idou 1 from to) (let ((n1 (1- n))) (hanoi n1 from v to) (idou n from to) (hanoi n1 v to from)))) (defun idou (n from to) (print `(move ,n from , from to, to)) )

  • C言語によるハノイの塔のプログラムの実行の流れ

    解きながら学ぶC言語の問題8-9のハノイの塔のプログラムについです。ソースコードは #include<stdio.h> #define N 3 void move(int no,int x,int y) { if(no>1) move(no-1,x,6-x-y); printf("%dを%d軸から%d軸へ移動\n",no,x,y); if(no>1) move(no-1,6-x-y,y); } int main(void) { move(N,1,3); return 0; } ============================== 実行結果 1を1軸から3軸へ移動 2を1軸から2軸へ移動 1を3軸から2軸へ移動 3を1軸から3軸へ移動 1を2軸から1軸へ移動 2を2軸から3軸へ移動 1を1軸から3軸へ移動 ============================== 最近大学の講義でこのプログラムの実行の流れを習ったのですが、どうにもよく理解することができません。 まず、move(no,x,y)にはそれぞれno=3,x=1,y=3の数が入っていますよね。 そして、no>1なので、move(no-1,6-x-y,y)の式に代入してmove(3-1,1,6-1-3)となるとno=2,x=1,y=2となるのでmove(2-1,1,6-1-2)となるのでこのときno=1,x=1,y=3。 この時点でno>1ではなくなりprintf関数によって、1を1軸から3軸へ移動、2を1軸から2軸へ移動と表示されると言うことだと思っているのですが。 ここから先がさっぱりです、なぜ1を3軸から2軸へ移動となるのでしょうか? 一つもどってno=2,x=1,y=2のときmove(no-1,6-x-y,y)の式に代入されるということなのでしょうか? どうして急にmove(no-1,x,6-x-y)の式で計算していたものがmove(no-1,6-x-y,y)の式で計算するようになるのか、がわかりません。 どちらも条件分岐はif(no>1)ですし、このif文が何のためにあるのかもよくわからないのです。 自分でも書いていて要点がはっきりしませんが、どなたかお願いいたします。

専門家に質問してみよう