1

diskcの移動回数を数えたい。しかし代わりに、結果として私は何か他のものを手に入れます。

(setq x 0)

(defun towersOfHanoi (n from to help)
  (if (> n 0)
   ;progn evaluates multiple forms and returns the result from the last one.*/
   (progn
     (towersOfHanoi (- n 1) from help to)
     (format t "~d ----> ~d~%" from to)
     (towersOfHanoi (- n 1) help to from)
     (+ 1 x)
     )  

    ))



;(towersOfHanoi 3 'A 'B 'C)

私がそれを実行すると、私は得ます

(towersOfHanoi 3 'A 'B 'C)
A ----> B
A ----> C
B ----> C
A ----> B
C ----> A
C ----> B
A ----> B
1

なぜそれが7ではなく1であるのか、再帰呼び出しごとにxの値が0にリセットされていると思いますが、ディスクの移動数を取得するにはどうすればよいですか。ありがとう。

4

1 に答える 1

4

lispifでは最大で3つの引数を取ります。条件、条件が真の場合に評価するフォーム、および条件が偽の場合に評価するフォーム。

詳細については、 http://www.lispworks.com/documentation/HyperSpec/Body/s_if.htmを参照してください。

ブランチ内の複数のフォームを評価するためprognに、複数のフォームを評価し、最後のフォームからの結果を返すを使用できます。

また、princ1つの引数だけが出力されることを期待します。一度に複数のものを印刷するために、あなたは使用するかもしれませんformat

あなたの場合(括弧の配置にも注意してください):

(defun towersOfHanoi (n from to help)
 (if (> n 0)
   (progn
     (towersOfHanoi (1- n) from to help)
     (format t "~d ----> ~d~%" from to)
     (towersOfHanoi (1- n) help to from))))

誤った分岐がないためwhen、複数の形式を評価できるものを使用することもできます。

(defun towersOfHanoi (n from to help)
  (when (> n 0)
    (towersOfHanoi (1- n) from to help)
    (format t "~d ----> ~d~%" from to)
    (towersOfHanoi (1- n) help to from)))

動きをカウントするために、ローカルカウント変数(で導入)と、この変数を更新letする内部作業関数(で導入)を使用できます。labels

(defun towers-of-hanoi (n &optional (from 1) (to 2) (help 3))
  (let ((counter 0))                                          ; local variable
    (labels ((towers-of-hanoi-core (n from to help)           ; local function
               (when (> n 0)
                 (towers-of-hanoi-core (1- n) from to help)
                 (incf counter)                        
                 (format t "~d ----> ~d~%" from to)
                 (towers-of-hanoi-core (1- n) help to from))))
      (towers-of-hanoi-core n from to help))                  ; leave work to inner function
    (format t "Moves: ~d ~%" counter)))

ここで、from、to、およびhelpもオプションになり、デフォルトで1、2、および3になります。

繰り返しますが、詳細はHyperspecにあります:http ://www.lispworks.com/documentation/HyperSpec/Front/

于 2013-01-20T10:34:46.777 に答える