• ベストアンサー

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)) )

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

  • ベストアンサー
回答No.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))))))

tou3s
質問者

お礼

ありがとうございます! なるほど、idouで数えるんじゃなくてhanoiの方でやっちゃうんですね。 ちゃんと動きました。

その他の回答 (4)

  • acacia7
  • ベストアンサー率26% (381/1447)
回答No.4

やはり、最初のhanoiの呼び出し前に x=0を入れるしかないのでは??・・

  • acacia7
  • ベストアンサー率26% (381/1447)
回答No.3

ごめんなさい。#1はおもいっきり勘違い。 基本的にidouが呼び出される度に手順が1こ増えるのだから、idou文内でカウントアップを入れれば大丈夫では?

tou3s
質問者

補足

いえいえ。こっちこそ改行とか分かり難くてごめんなさい。 (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を決めればいいのかなって。

回答No.2

>最初の行・・ >「もしn=1なら」ってなってません? >nに1以外を入れたら、何もせずに終了する予感。 1以外ならlet文を実行するので、何もせずに終了することは無いと思いますが...

tou3s
質問者

補足

はい。ちゃんとn=3とか4でもちゃんと動いてます。 idouの呼び出し回数を数えたいんだけど(Cだったらi=i+1でカウントしてくような)変数をどう入れれば良いかよくわかんなくて……。

  • acacia7
  • ベストアンサー率26% (381/1447)
回答No.1

最初の行・・ 「もしn=1なら」ってなってません? nに1以外を入れたら、何もせずに終了する予感。

関連するQ&A

専門家に質問してみよう