1 名前:デフォルトの名無しさん [2007/04/20(金) 19:41:39 ] Lisp全般のスレです 過去スレ Part16: pc11.2ch.net/test/read.cgi/tech/1172404795/ Part15: pc10.2ch.net/test/read.cgi/tech/1151025773/ Part14: pc8.2ch.net/test/read.cgi/tech/1132275726/ Part13: pc8.2ch.net/test/read.cgi/tech/1115901841/ Part12: pc8.2ch.net/test/read.cgi/tech/1100229366/ Part11: pc5.2ch.net/test/read.cgi/tech/1091456033/ Part10: pc5.2ch.net/test/read.cgi/tech/1075630259/ Part9: pc2.2ch.net/test/read.cgi/tech/1069594582/ http://が多すぎるらしいので分割
513 名前:デフォルトの名無しさん [2007/05/31(木) 23:51:57 ] あと二次元配列 O(1)でアクセスできるタイプ(効率重視)で perlで以下のことがLISPではどのように書くのでしょうか? *定義 $cell['A'][1] = ('国語' 100) <-- Lispのリスト $cell['A'][2] = ('算数' 20) <-- Lispのリスト $cell['A'][3] = ('理科' 30) <-- Lispのリスト $cell['B'][1] = ('家庭科' 90) <-- Lispのリスト *呼び出し % print $cell['A'][2]; ['算数', 20]
514 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 00:02:00 ] >>513 なんか日本語がよくわからないんだが、 多次元配列なら aref に次元の数だけ引数を渡す (aref #2A((1 2 3) (4 5 6)) 1 2) => 6 ところで多次元配列って Lisp では使ったことないんだけど、どういう時使う?
515 名前:デフォルトの名無しさん [2007/06/01(金) 00:15:09 ] >多次元配列って Lisp では使ったことないんだけど、どういう時使う? まだ構文を覚えている最中で、どういう時に使うかまだでは考えていなかったのです。 LISPでは、多次元配列という考え方でなく別の方法で対処しているということでしょうか? LISPらしい書き方を学ぶにはどうしたら良いのでしょうか? 私はPerlはかじっておりますので、perlと対比できたらわかりやすいです。 #2Aは何を意味するのでしょうか?2はニ次元Aは???? #3Bにしたらエラーになりました。
516 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 00:21:36 ] ちょっとは調べろよwww
517 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 00:30:49 ] >>514 ベタな例だけど行列とか
518 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 01:04:32 ] ある処理系での多次元配列の例 CL-USER>(make-array '(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)) #20A((((((((((((((((((((0))))))))))))))))))))
519 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 01:08:02 ] 20次元配列とかw まあ、全て2要素にした程度でも凄いサイズになるけどな。 扱えないレベルではないけど。
520 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 01:13:53 ] >>501-503 Hyperspecに答えが書いていたね。 www.lisp.org/HyperSpec/Body/fun_assoccm_a_assoc-if-not.html のexamplesをみてみて。
521 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 01:18:38 ] >>514 一番ありがちなのは lispで行列計算をしている場合。ライフゲームなどの 2次元空間グラフィック。そんなところじゃないのか
522 名前:デフォルトの名無しさん [2007/06/01(金) 04:04:33 ] schemeでany や every は any? every?じゃないんだな。
523 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 05:33:21 ] (any hoge? ...) という使い方になるわけだから俺には違和感ないな。
524 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 05:38:40 ] anyはブール値を返すわけじゃないからじゃね?
525 名前:デフォルトの名無しさん mailto:sage [2007/06/01(金) 06:49:57 ] for-all、existsとの違いがイマイチ
526 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 20:21:56 ] このスレのレベルが急速に低下してるな……
527 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 20:25:51 ] ...and justice for all
528 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 22:25:07 ] 関数型系の複数のスレに、全く同じレス付けてる >>526 って何なの?
529 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 22:46:56 ] >>527 '((justice is lost) (justice is raped) (justice is gone))
530 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 23:21:29 ] >>528 休みの日にデパートの屋上から路上を眺めるのが趣味の人なんじゃないの
531 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 23:34:40 ] 今の時代なら、休みの日にgoogleで海岸とかプールを拡大して 凝視してる人だろ
532 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 23:48:09 ] LIVE映像じゃないと、ちょっと行為としてしっくりこない気がする。
533 名前:デフォルトの名無しさん mailto:sage [2007/06/02(土) 23:51:27 ] では、ライブカメラを漁ってる人
534 名前:デフォルトの名無しさん [2007/06/03(日) 16:55:16 ] Lispは型推論を持たない
535 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 16:55:45 ] 唐突にどうしたんだぜ?
536 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 17:16:00 ] ヒント:日曜日
537 名前:デフォルトの名無しさん [2007/06/03(日) 17:37:08 ] >>536 正解!
538 名前:デフォルトの名無しさん [2007/06/03(日) 18:34:02 ] LISPに ne 等しくないという等号はありますか?
539 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 18:44:09 ] (defun ne (x y) (not (eq x y)))
540 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 19:04:01 ] 「等しくないという等号」にすげぇ違和感
541 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 19:09:59 ] そうですね はい次。
542 名前:デフォルトの名無しさん [2007/06/03(日) 23:27:36 ] pushすると ("C" "B" "A")となりますが 例えば、 (def test(x lst) ... ) (setq lst '()) (test "A" lst) (test "B" lst) (test "C" lst) (print lst) で("A" "B" "C")とするには、どのようにtest関数を作ればよいのでしょうか? pushした後 reverseせず、純粋に("A" "B"..というリストを作りたいです。
543 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 23:35:57 ] >pushすると >("C" "B" "A")となりますが なりませんでした はい次。
544 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 23:40:12 ] >>542 何故そんなに push を嫌うのか分からん
545 名前:デフォルトの名無しさん mailto:sage [2007/06/03(日) 23:45:09 ] rplacdでマクロ作ればいいんじゃね
546 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 00:17:17 ] push して nreverse が一番効率いいと思うがな
547 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 00:42:34 ] 誰一人>>543 の仕切りに従ってない点について。
548 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 00:49:08 ] そりゃー2chだもの
549 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 00:54:11 ] 拝啓547様 正しいマナーが根付くには時間がかかるものです。 悪癖は容易には正されません。 円滑なスレ進行のため今後も努力する所存です。 543
550 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 00:55:35 ] うまく人を逆撫でできる人は自分の話題に持ち込めるけど、 単なる阿呆、とだけ思われてオシマイだと、うち捨てられて終わりなんだよね。
551 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 03:29:47 ] >>542 君が欲しいのはこんな感じのものでは? (defmacro test (x lst) `(setq ,lst (append ,lst (list ,x)))) でも>>546 の言うとおり、pushしてnreverseのほうがたぶん速いよ。
552 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 04:08:00 ] 多分 queue が使いたいんじゃないかなーと思った。
553 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 13:51:23 ] Common Lispらしいという意味ではfill pointer付きarrayという手もあるな。使ったことないけど。
554 名前:デフォルトの名無しさん mailto:sage [2007/06/04(月) 21:13:09 ] >>553 コンシングを減らすために使ってみたことあるよ。 おれがヘボなせいかあんま高速化しなかったけどorz cl-user(5): (setq vec (make-array 10 :fill-pointer 0 :adjustable t)) #() cl-user(6): (vector-push "a" vec) 0 cl-user(7): (vector-push "b" vec) 1 cl-user(8): (vector-push "c" vec) 2 cl-user(9): vec #("a" "b" "c") cl-user(10): (concatenate 'list vec) ("a" "b" "c")
555 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 00:50:01 ] >>542 それはマクロでやると簡単。 (defmacro test (x lst) `(setf ,lst (append ,lst (list ,x))))
556 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 01:02:27 ] 既にでてたorz.
557 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 03:19:49 ] nreverseの方が早いっていうのは appendが新しいリストをconsセル一つ一つつなげて返すのに対して nreverseは元のリストを破壊操作で処理するからって言うことで正しいですか?
558 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 07:17:24 ] 最後に付け加えるのが時間かかるってことじゃない? nreverse なら cons セルのつなげかえをするだけなので O(n) なのに対して、 リストの最後に付け加えていくのはリストが長くなるほど たどる量が増えて O(n^2) になる、っていうことだと思う。
559 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 14:06:30 ] FreeBSD6.2RELEASEでGauche0.8.7をつかっています。 (inc (dec inc))と(1 2 3)を入力として与えると (2 (1 4))を返すような関数が欲しいんですけど、 なんか既にあるような気がします。 こ存じないですか?
560 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 14:16:59 ] (define (foo x y) '(2 (1 4)))
561 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 15:58:34 ] そんな変な関数ある気がしないw
562 名前:559 mailto:sage [2007/06/05(火) 16:20:06 ] そうですか… リストを構造体に見立てて、 別の構造体に変換するような操作は結構あるような気がしたんですが… だとすると俺のやりかたが間違っているんだろうか。 ちょっと違う形になりましたけど、とりあえず書いたもんさらしてみます。 (define (general-apply syn args) (eval `(,syn ,@args) (interaction-environment))) (define (data-convert index record convert-rule) (general-apply 'let (list (zip index record) convert-rule)) ) で、 (data-convert '(a b c) '(1 2 3) '(list (inc a) (list (dec b) (inc c)))) みたいな使い方をします。
563 名前:デフォルトの名無しさん mailto:sage [2007/06/05(火) 16:27:00 ] いまいちよくわからないんだけどutil.matchみたいなことを考えているのかな。 practical-scheme.net/gauche/man/gauche-refj_163.html#SEC435
564 名前:559 mailto:sage [2007/06/05(火) 17:31:16 ] >563 おお、なんかこれでよさそうです。 ありがとうございました。
565 名前:デフォルトの名無しさん mailto:sage [2007/06/08(金) 16:24:42 ] wilikiのスタイルシートってcgiと同じディレクトリにおけばいいの? 全然うごいてくれない
566 名前:デフォルトの名無しさん mailto:sage [2007/06/08(金) 17:15:18 ] 吐かれたHTML読んでみたら?
567 名前:デフォルトの名無しさん mailto:sage [2007/06/08(金) 20:38:12 ] >>565 キーワード引数で :style-sheet のとこにスタイルシート名を指定すること。
568 名前:565 mailto:sage [2007/06/10(日) 14:51:28 ] 結局解決できませんでした しかたないのでpukiwikiをインストールします
569 名前:デフォルトの名無しさん mailto:sage [2007/06/10(日) 15:02:04 ] うんそれがいいよ
570 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 00:38:23 ] (if (解決-p 565) (install wiliki) (install pukiwiki)) 残念。。
571 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 00:56:25 ] pukiwikiをschemeで書き直せばいいじゃん
572 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 00:59:38 ] ウッキ、ウッキ、ウィッキー
573 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 01:01:44 ] わかったよブービー(´・ω・`)
574 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 01:03:49 ] ウィッキーさん元気してるかね? なつかしすなー
575 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 04:45:52 ] ウィッキー→みのもんた だと思ってた時期が(ry
576 名前:デフォルトの名無しさん mailto:sage [2007/06/12(火) 21:31:35 ] ウィッキーは落語家のえーっと鶴なんとか
577 名前:デフォルトの名無しさん [2007/06/13(水) 21:15:05 ] (define port (open-input-file "c:\\tmp\\data.txt") (define line (read-line port)) (append lst (line)) テキストファイルから、一行ずつ読み込んでリストに加えて行くという処理を書いてるのですが、 3行目の(line)でエラーになります。 こういう場合、どう書けばいいんでしょう?
578 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 21:17:35 ] どんなエラーとか書こうぜ
579 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 21:32:15 ] >>578 > gosh: "error": invalid application: ("aaa") こんな感じです。 "aaa"は、テキストファイルから読み込んだ内容になってます。
580 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 21:50:46 ] (append lst line)
581 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 21:56:13 ] 質問です。 リテラルを破壊的に変更してはいけないといわれますが、次のような場合もでしょうか? (do ((i 10 (- i 1)) (r '() (cons i r))) ((zero? i) (reverse! r))) (reverse r) と書くべきなんでしょうか?
582 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 21:58:39 ] >>581 その例ならリテラルを破壊的に変更はしないと思う
583 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 22:08:26 ] >>582 じゃあ、次の場合はどうでしょうか。 リテラルを破壊的に変更してしまっているので、(reverse r) と書くべきでしょうか? (do ((i 0 (- i 1)) (r '() (cons i r))) ((zero? i) (reverse! r)))
584 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 22:12:33 ] wiliki の質問スレはどこですか?
585 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 22:13:31 ] >>583 空リストはそもそも破壊できるような物ではないので大丈夫
586 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 22:16:52 ] >>585 じゃあ、空リストでない次の場合には破壊的に変更しているので、 (reverse r) と書くべきですね? (let ((lst '(a b c))) (do ((i 0 (- i 1)) (r lst (cons i r))) ((zero? i) (reverse! r))))
587 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 22:17:53 ] >>586 そう。こういう場合は reverse! は厳禁。
588 名前:デフォルトの名無しさん mailto:sage [2007/06/13(水) 22:23:03 ] >>587 なるほど、やっと解ったような気がします。どうもありがとうございました。
589 名前:デフォルトの名無しさん [2007/06/16(土) 11:57:56 ] lisp厨、必死だなw
590 名前:デフォルトの名無しさん mailto:sage [2007/06/16(土) 17:34:58 ] ここはlisp厨のスレだが何か?
591 名前:デフォルトの名無しさん mailto:sage [2007/06/16(土) 18:47:59 ] チュウチュウうるさいなぁ、おまえらそんなにチュウが好きならスペースチャンネル5でもやってろ!
592 名前:デフォルトの名無しさん mailto:sage [2007/06/16(土) 20:57:21 ] Squeakもあるぜよ
593 名前:デフォルトの名無しさん mailto:sage [2007/06/16(土) 22:15:21 ] 本谷有希子さんとチュウしたい love6.2ch.net/test/read.cgi/book/1176782409/
594 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 14:29:24 ] FreeBSD6.2RELEASEでGauche0.8.10[utf-8]を使っています。 字句解析を使用と思い、以下の様なコードを書きました。 (define (lex-analyze inpx) ;; inpx: input port (define (op? inpx) (define op-char #\() (if (char=? op-char (peek-char inpx)) (begin (read-char inpx) (cons 'op (list op-char)) ) #f )) (define (cp? inpx) (define cp-char #\)) (if (char=? #\) (peek-char inpx)) (begin (read-char inpx) (cons 'cp (list cp-char)) ) #f ))
595 名前:594 mailto:sage [2007/06/18(月) 14:31:06 ] (define (ws? inpx) (if (char-whitespace? (peek-char inpx)) (let loop ((r (list (read-char inpx))) (nc (peek-char inpx)) ) (if (char-whitespace? nc) (loop (cons (read-char inpx) r) nc) (cons 'ws (reverse r)) )) #f )) (define (wd? inpx) (define (allowed-char? x) (not (char-whitespace? x))) (if (allowed-char? (peek-char inpx)) (let loop ((r (list (read-char inpx))) (nc (peek-char inpx)) ) (if (allowed-char? nc) (loop (cons (read-char inpx) r) nc) (cons 'wd (reverse r)) )) #f )) (define tokens (list op? cp? ws? wd?)) (define (f inpx) (let loop ((t tokens)) (cond ((null? t) #f) (((car t) inpx) => values) (else (loop (cdr t))) )))
596 名前:594 mailto:sage [2007/06/18(月) 14:32:01 ] (let loop ((r '())) (if (eof-object? (peek-char inpx)) (reverse r) (loop (cons (f inpx) r)) )) ) ここで、 echo '(+ 1 2)' > /tmp/hogeして作ったファイルを、 (define inp (open-input-file "/tmp/hoge"))として読み込ませて、 (lex-analyze inp)としたのですが、結果が返ってきません。 どうやら、2を読み込むところで時間がかかっている様なのですが、 どうしたらよいのでしょうか。
597 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 16:27:31 ] 答えじゃなくて悪いんだけど、 (let loop ((r (list (read-char))) (nc (peek-char))) letの束縛規則により、read-charとpeek-charの どっちの副作用が先に適用されるのか不明ですよ。 Cの関数呼び出し時の引数でgetcとungetcを同時にしてると考えてください。
598 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 16:28:16 ] とりあえずそのallowed-charでは ) も #t にしてしまう。
599 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 16:39:34 ] (loop (cons (read-char) r) nc) ncが更新されてないよ。 peek-charを使わずに書き直した方が良いのでは。
600 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 16:51:06 ] >>599 let loopの内側に(let ((nc peek-char)) ... ) でいいでしょ それよりファイル末尾がwhitespaceの列だったりするとws?がeof読もうとして死ぬ
601 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 17:18:39 ] そういえばchar=?で#<eof-object>を比較して大丈夫なの?
602 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 17:39:44 ] wd? は whitespace でしか終了しないでしょ。 ということは、 "2)" まで wd? で読み取って eof になっているが、 eof に対処するコードが wd? にないのでここで終了できなくなっている。これが原因でしょう。 仮に (+ 1 2 ) のように2と閉じカッコのあいだに空白を入れてみてごらん。それなら終わるから。 あと Gauche を使ってるなら text.parse とか便利なライブラリがあるから、そういうのを使った方がすっきり書けるよ。 ws? みたいなやつは skip-while を使えば一発だし。
603 名前:594 mailto:sage [2007/06/18(月) 18:32:44 ] >597 それは気づきませんでした。 ありがとうございます。 >598 すいません、怠けたかっただけなんです… でもそのせいみたいですね。 >602 ありがとうございます。 (+ 1 2 )にしてもエラーで止まってしまいます。 でもそこら辺にもんだいがありそうですね。 もう少しやってみます。 それからこれは自分でパーサを書いてみよう、という試みなので、 ライブラリを使うのは無しです。 でも参考にしてみようと思います。 みなさんありがとうございました。
604 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 20:08:26 ] 文字はリストやストリームとしていつでも取り出せるように蓄えとくと バックトラックとか副作用気にせずできて便利っすよ。 named-let活用したいみたいだしCPS勉強すると良いでしょう。 例えばトークン抽出時や#f返してる所は末尾コンテキストだから、 そのまま他の判定処理にたらい回しして継続できるし。 慣れればread-charとかのI/O操作は違うレイヤーとして管理できるよ。
605 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:37:01 ] 今日初めてreaderマクロなるものとCL-YACCと言う物を体験しました。 惚れた、もっと昔に食わず嫌いしないでやっておけばよかった。 ちょいとのめり込み中。
606 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 20:12:56 ] リストから、n番目の要素を削除して、その削除した要素を返す関数を書きました。 まず下のような感じで書いたのですが、これだと、nが0の場合にエラーになります。 (define (remove-at! ls n) (let loop((prev '()) (rest ls) (count n)) (if (zero? count) (begin (set-cdr! prev (cdr rest)) (car rest)) (loop rest (cdr rest) (- count 1))))) それで、nが0の場合は別に処理を入れてみたのですが、破壊的操作で、リストの先頭を削除するのがどうしてもわかりません。 どう書けばいいでしょうか? (define (remove-at! ls n) (cond ((null? ls) '()) ((zero? n) (let ((tmp (car ls))) (set-cdr! ls (cdr ls)) ;; ここがダメ tmp)) (else (let loop((prev '()) (rest ls) (count n)) (if (zero? count) (begin (set-cdr! prev (cdr rest)) (car rest)) (loop rest (cdr rest) (- count 1)))))))
607 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 20:41:55 ] >>606 > 破壊的操作で、リストの先頭を削除するのがどうしてもわかりません。 そういうことは原理的にできない。(理由は考えてみるべし) append! で第一引数が () の場合なども同様で、結果は明示的に返す必要がある。
608 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 21:24:07 ] (define (remove-at! ls n) (if (null? ls) (error "list too short") (if (zero? n) ((lambda (tmp) (set-car! ls (cadr ls)) (set-cdr! ls (cddr ls)) tmp) (car ls)) (remove-at! (cdr ls) (- n 1)))))
609 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 21:42:44 ] >>607 >(理由は考えてみるべし) Cだったら、下のようなコードで、仮引数のほうを書き換えて、実引数が変化しないって悩んでるようなもんですかね? struct cell { struct cell* next; const char *symbol; }; const char* remove_at(struct cell* p, int n) { p = ・・・・ ・・・ }
610 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 22:04:41 ] (define (remove-at! ls n) (cond ((null? ls) '()) ((zero? n) ((lambda (tmp) (set-car! ls (cadr ls)) (set-cdr! ls (cddr ls)) tmp) (car ls))) ((= 1 n) (if (null? (cdr ls)) '() (if (null? (cddr ls)) ((lambda (tmp) (set-cdr! ls '()) tmp) (cadr ls)) ((lambda (a b c) (set-car! b (car c)) (set-cdr! b (cdr c)) a) (cadr ls) (cdr ls) (cddr ls))))) (else (remove-at! (cdr ls) (- n 1)))))
611 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 22:42:56 ] >>608 >>610 サンキューです。 ((lambda (tmp) (set-car! ls (cadr ls)) (set-cdr! ls (cddr ls)) tmp) (car ls)) で、書き換えできるみたいですね。 勉強になります。
612 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 23:22:49 ] でも結局 (remove-at! 0 '(a)) とすると破綻する。 変数の参照先をconsセルから全く別のものに置き換える操作って無いよね?
613 名前:デフォルトの名無しさん mailto:sage [2007/06/20(水) 23:35:42 ] 話を単純にして、「リストの先頭を削除」を考えれ。 (set! リスト (cdr リスト)) これを関数化するのは不可能というのを理解してるかどうか。 (define (リスト削除 リスト) (set! リスト (cdr リスト)) リスト) (define リスト '(a b c)) (リスト削除 リスト) => (b c) リスト => (a b c) (set! リスト (リスト削除 リスト)) リスト => (b c) 答え (define-macro (リスト削除 リスト) `(let ((リスト ,リスト)) (set! リスト (cdr リスト)) リスト)) (リスト削除 リスト) リスト => (b c)