Lispにおける最大値関数

このQ&Aのポイント
  • Lispで括弧の入れ子の中身も含めた最大値を求める関数を自分なりに作ったのですが、条件によってはうまくいきません。
  • 自作の最大値関数がうまく動作しない理由がわかりません。
  • Lispの条件分岐を使った自作の最大値関数が正しく動作しない問題について教えてください。
回答を見る
  • ベストアンサー

Lispにおける最大値関数

Lispで括弧の入れ子の中身も含めた最大値を求める関数を自分なりに作ったのですが、条件によってはうまくいきません。 なぜだか教えていただけないでしょうか? (defun max1 (n) (cond ((atom n) n) (t (if (null (cdr n)) (max1 (car n)) (progn (let ((local_max (max1 (cdr n)))) (if (> (car n) local_max) (car n) local_max))))))) > (max1 '(1 2 6 (3 4))) 6 > (max1 '(1 2 (6) ((3 4)))) >: (6) is not a REAL

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

とりあえず理由がわかればいいのですか? >: (6) is not a REAL このメッセージを見てわかる通り、 (> (car n) local_max) この比較をしているところの (car n)が、 エラーになるパターンだと (6) になってしまい、> (6) 4 という比較をしようとして エラーになっています。 ((a) b) の car は a じゃなくて (a)なので、 どうにかしてもう1枚皮をむきましょう。 てなヒントでよろしいでしょうか? ところで cond と if を混ぜて使うのは珍しいというか あまり見ないスタイルですね。 できればどっちかにした方が良いと思います。 今回の場合は cond が二分岐ですし。 ところで使っているLispの処理系はなんなのでしょうか?

関連するQ&A

  • emacsでcmmon lispのプログラムを作成します。

    emacsでcmmon lispのプログラムを作成します。 my-equal(A, B)= if A is an atom then if B is an atom then (eq A B) else if B is an atom then nil else if (car A)=(car B) then (cdr A)=(cdr B) else nil というのです。自分が考えたのは、 defun my-equal(x, y)= (cond ((atom x) (atom y)) (eq x, y) (atom) (t, nil) ((car x)=(car y) (cdr x)=(cdr y)) (nil)) というのでよろしいのでしょうか? また、4行目(この全文の)の意味がいまいち分かりません。

  • LISPでatomの数を数える

    XLISPでlistの中のatomの数を数えたいんです。 下のようにlistの中のatomだけを抜き出してリストにすることはできました。 (DEFUN F1(L) (COND((NULL L) NIL) ((LISTP(CAR L))(F1(CDR L))) (T (CONS (CAR L)(F1(CDR L)))) ) ) このコードを実行すると次のようになります。 (F1 '((A B) C D (E F) G)) (C D G) 後はこれをlengthで数えるだけだと思うのですがそのやり方が分かりません。 それとももしかしてSETQで変数を設定して Tのところで値を1つずつ足していくのでしょうか?

  • Lispについてわからないことが(Scheme)

    あるLispの勉強ソフトで、 「関数lを『引数としてxを受け取ると、xの要素の数を返す関数』として定義しなさい。」 という問題があるのですが、私は以下のようにしました。 (define l (lambda (x) (if (= x null?) 0 (+ 1 (l (cdr x)))))) しかしこれだとオーバーフローと表示されて強制終了されてしまいました。 そこで答えをネットで検索したところ以下のものが見つかりました。 (define l (lambda (x) (cond ((null? x) 0) (else (+ 1 (l (cdr x))))))) これが正解なようですが、この2つのリストの違いがわかりません。 初歩的なことですがifの使い方を間違っているんでしょうか?

  • リストを逆順にする関数(LISP)

    「初めての人のためのLISP[増補改訂版]」のP150のリストを逆順に関数がよくわかりません。 以下がその関数です。 (defun nreverse (x) (nrev2 x nil)) (defun nrev2 (x r) (cond ((null x) r) (t (nrev2 (cdr x) x) (rplacd x r) ))) xがnilになるまで再帰を繰り返し、((null x) r) で再帰を戻りますがなぜs (rplacd x r)でリストが逆順になるんでしょうか。例えばxを(a b c)とすると x:(a b c) r:nil ↓ x:(b c) r:(a b c) ↓ x:(c) r:(b c) ↓ x:nil r:(c) ↓ rplacd (c) (b c) ↓ rplacd (b c) (a b c) ↓ rplacd (a b c) nil となるのですが、これじゃあ全然リストは逆順になりませんよね。 誰が教えてください、お願いします。 ちなみにrplacd は第一引数のcdrを第二引数に変換する関数です。

  • LISPによる横型探索

    LISPのSchemeをつかって横型探索で探索した経路を出力するプログラムをつくっているのですが、 今は探索が終わると終了するとCLOSEDの中を表示するプログラムしかできていません もしこれに探索した経路の出力をする機能を加える場合どうすればいいですか? OPEN→待ちリスト CLOSED→展開済みリスト GOAL→目標地点 OP→オペレータの集まり nとopから展開の結果をだす (define (tenkai n op) (tenkai2 n op '())) (define (tenkai2 n op kekka) (if (null? op) kekka (if (= n (car (car op))) (tenkai2 n (cdr op) (cons (car (cdr (car op))) kekka)) (tenkai2 n (cdr op) kekka)))) (define (yokogata open goal op closed) (if (null? open) 'sippai (if (= (car open) goal) (display closed) (yokogata (append (cdr open) (tenkai (car open) op)) goal op (append closed (list (car open)))))))

  • common lispのコード

    リスト中の要素aの数をカウントするプログラムを反復で書いたのですが、実行しようとすると停止してしまいます。何が悪いのでしょうか?教えてもらえませんか? (defun dot (lst) (let ((c 0)) (do ((ls lst (cdr lst)) ((null ls) c) (if (eq 'a (car ls)) (+ c 1) (+ c 0)))))

  • lispに関する質問

    最近lispを勉強し始めたのですが、 Newton法を使った平方根を求めるプログラムがうまく書けず困っています。 (defun isqrt(n &aux x0 x1) (setq x0 (expt 2 (floor (integer-length n) 2))) (loop (setq x1 (floor (+ x0 (floor n x0)) 2)) (print x1) (cond ((= x0 x1)(return)) (t (setq x0 x1)))) x0) このように書くとnの値が3や8や15の時にx0、x1の値が無限に出てきてしまいます。 何でおかしいのでしょうか? 直すにはどうしたら良いですか? わかる方教えて下さい。 よろしくお願いします。

  • Lispでリストの中身もすべて反転する関数

    リストの中身をもすべて反転する関数を作っているのですが、 reverse関数を自分で実装はできたのですが、上記のような使用を持つ関数を作れません。どうぞどのようにしたらよいか教えていただけないでしょうか? ちなみに自分で作ったreverseはこれです。 (defun my-reverse (n) (if (null n) nil (append (my-reverse (cdr n)) (list (car n))))) 作りたい関数では以下のようになります。 (make-reverse '(a (b (c d))(e (f g)))) (((g f) e)((d c) b) a)

  • common lispのプログラミングについて

    色の英単語クイズをするプログラムが作りたいです。 イメージとしては =====hi!===== >ki yellow correct! >ao blue correct! >aka res wrong. >aka red correct! bye.(終了) というものです。 全部で5問あり、全ての問題が終了するとbye.と出てきたクイズが終わります。 (もし間違ってももう一回同じ問題が出ます。) これまでの成果としては、 (defun quiz () (princ "=====hi!=====") (terpri) (princ 'ao) (setq cc '((ki . yellow)(ao . blue)(aka . red) (cha . brown)(murasaki . purple))) (quiz-tr)) (defun quiz-tr () (cond ((eq cc nil) (pprint 'bye.)) (t (quiz-tr (print (cond ((eq (cdr (car (cdr cc))) (read)) 'correct!) (t 'wrong.))))))) という感じでご覧の通り、汎用性が全くないです。 末尾再帰などを使って5問まで回しながら、おのおのの問題について正誤判定していきたいのですが、非手続き型に慣れていないもので、良い案が浮かびません。 どなたかアドバイスを頂けると嬉しいです。

  • 「初めての人のためのLISP[増補改訂版]」で

    「初めての人のためのLISP[増補改訂版]」のP.46の練習問題をやっていくと (setq A nil) nil (setq B '(87 58 90)) (87 58 90) (setq C '(I B M)) (I B M) (null t) nil (null A) t (null (null A)) nil (cadr B) 58 (+ (car B) (caddr B)) 177 (cadr C) B (set (car C) (cdr B)) (58 90) (car C) I (atom C) nil となりますが、 なぜ (atom C) でnilが返ってくるのですか? "C"はアトムではないのですか?

専門家に質問してみよう