L99 オレオレ解答 P01 から P05。

どもです。
L99 についてですが,1日3問以上解いていければいいかなぁと。
悩みどころはどの武器を使えるかということ。
loop とか dolist とか使っていいのだろうか。
append とか push とかも。
正解は,それぞれを使って数種類の解答を用意することかな。だべ。
とか言って,まだ1種類しか作ってないボク。
あと,なるたけ functional になるように書きたいと思うワタシは,
もひとつ functional style を理解していない。
そういえば,cons とかを使う練習は,昔,Little Schemer とか Seasoned Schemer を読んだときに,
ノートに書いてやったなぁ。けど,復習してないし,scheme 使ってどうこうすることが
なかったため,whitypig さんは,それらをすっかり忘ている!
けど,pizza を作ったのは記憶にある。


あの本,練習にはいいけど,メタ的な説明がないからか,
記憶に残らんし,もひとつつかみ所がない感じ。
いや,それはオレが凡夫だからか。あと,プログラムについて今以上に
わかってなかったというのもある。で,たぶんだけど,あれらの本は,
1冊目にはあまり適さないかなぁと。
なんていうんだろう,こうやって計算するんですよ〜というのを教えられて,
計算していくだけ。定理とか定義とかの説明がない感じか。
やっていて楽しいことは楽しかったんですけどね。
ということは,やはり,それらを活かせなかったオレが原因ということになるな。


というわけで,P01 から P05 までのオレオレ解答。
my-reverse ですげー詰まったのはナイショだよ。

P01 から P05
;;;; P01
(defun my-last (lst)
  (if (null (cdr lst))
      lst
      (my-last (cdr lst))))

(my-last '(a b c d)) => (D)
(my-last '()) => NIL
(my-last '(a)) => (A)

;;;; P02
(defun my-but-last (lst)
  (if (null (cddr lst))
      lst
      (my-but-last (cdr lst))))

(my-but-last '(a b c d)) => (C D)
(my-but-last '()) => NIL
(my-but-last '(a)) => (A)
(my-but-last '(a b)) => (A B)

;;;; P03
(defun element-at (lst ix)
  (if (= ix 1)
      (car lst)
      (element-at (cdr lst) (1- ix))))

(element-at '(a b c d e) 3) => C
(element-at '(a) 1) => A

;;;; P04
(defun my-length (lst)
  (if (null lst)
      0
      (1+ (my-length (cdr lst)))))

(my-length '(a)) => 1
(my-length '(a b c d e)) => 5
(my-length '()) => 0

;;;; P05
(defun my-reverse (lst)
  (labels ((my-reverse-aux (lst ret)
             (if (null lst)
                 ret
                 (my-reverse-aux (cdr lst) (cons (car lst) ret)))))
    (my-reverse-aux lst nil)))

(my-reverse '(a b c)) => (C B A)
(my-reverse '(a b)) => (B A)
(my-reverse '(a)) => (A)
(my-reverse '()) => NIL