- ベストアンサー
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)) )
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
このごろ、Lispを書いていないので、細かい文法を忘れてしまいましたが、こんなのでどうでしょう。 即興で書いたので、間違ってたらごめんなさい。 hanoiを移動回数を返す関数として定義しています。 (defun hanoi (n from to v) (cond ((= n 1) (idou 1 from to) 1) (t (let* ((n1 (1- n)) (c (hanoi n1 from v to))) (idou n from to) (+ c 1 (hanoi n1 v to from))))))
その他の回答 (4)
- acacia7
- ベストアンサー率26% (381/1447)
やはり、最初のhanoiの呼び出し前に x=0を入れるしかないのでは??・・
- acacia7
- ベストアンサー率26% (381/1447)
ごめんなさい。#1はおもいっきり勘違い。 基本的にidouが呼び出される度に手順が1こ増えるのだから、idou文内でカウントアップを入れれば大丈夫では?
補足
いえいえ。こっちこそ改行とか分かり難くてごめんなさい。 (setq x 0) (defun hanoi (n from to v) 中略 ) (defun idou (n from to) (setq x (+ x 1)) (print `(move ,n from , from to, to)) x) にしてみたら数えるのは出来たんですが、連続して実行するとxが前に実行した値を引き継いじゃうんです。 かと言ってhanoiやidouの中で(setq x 0)やると再帰呼出ししてるからxが1、2、1…になっちゃうんですよ。 どのタイミングでxを決めればいいのかなって。
- piyo-kichi
- ベストアンサー率47% (9/19)
>最初の行・・ >「もしn=1なら」ってなってません? >nに1以外を入れたら、何もせずに終了する予感。 1以外ならlet文を実行するので、何もせずに終了することは無いと思いますが...
補足
はい。ちゃんとn=3とか4でもちゃんと動いてます。 idouの呼び出し回数を数えたいんだけど(Cだったらi=i+1でカウントしてくような)変数をどう入れれば良いかよくわかんなくて……。
- acacia7
- ベストアンサー率26% (381/1447)
最初の行・・ 「もしn=1なら」ってなってません? nに1以外を入れたら、何もせずに終了する予感。
お礼
ありがとうございます! なるほど、idouで数えるんじゃなくてhanoiの方でやっちゃうんですね。 ちゃんと動きました。