過去の問題にリベンジ(その1)

この間,入門Common Lispを読んだおかげか「なりふりかまわなければ」Lispでも少しくらい何か書けるような自信がついた.


というわけで埃をかぶっていたLispの本を持ち出して,演習問題を解いてみることにした.


【ちょっと回想】学部3年の頃,情報工学科のLispの演習授業にもぐっていたのだが,そのときEssential Lisp(邦題:これがLispだ!)という,演習が充実している本を自習に使っていた.結局高階関数の章あたりで講義の範囲をオーバーしてしまったため,そこで辞めてしまった.(今思えば,高階階数までやらないLispの授業って・・・まぁ半期だし)
以降,Lispに触れることなく早3年が経っていた.
演習問題がかなり豊富で,きちんと解答までついているので,独習に非常に向いている.ページをめくってみると,解いた日付や書き込みがけっこうしてある.こんな勉強したのに使えるようになっていないなんて,正直そう思った(笑)

×がついている問題,スルーされている問題.「もしかして今なら解けるんじゃね?」と思って解いてみた.


 「解ける,解けるぞ!私にも問題が解ける!」(シャア風に)


というわけでかなり時間がかかっていますが,昔よりかはチカラがついているようです.単純に手続き型脳が強化(笑)されているためだと思いますが.特にうれしかったのがdiamondというひし形を描く問題.こういうもの

> (diamond 4)
   *
  ***
 *****
*******
 *****
  ***
   *

これが解けなかった.再帰の章なので再帰で書くべきなのだろうが.手続き脳のボクにはそんなことできません.力づくで書いてしまいました.

;; 7.16
; リスト再帰の章だが,再帰ではなく計数反復を使用
; 再帰バージョンもやりませう
(defun diamond (x)
  (and (triangle-top (1- x))
       (dotimes (count (1- (* 2 x)) t)
	 (princ "*"))
       (princ "\n")
       (triangle-bottom (1- x))))

(defun triangle-top (x)
  (dotimes (count x t)
    (dotimes (incount (- x count) t)
      (princ " "))
    (dotimes (incount (1+ (* 2 count)) t)
      (princ "*"))
    (princ "\n")))

(defun triangle-bottom (x)
  (dotimes (count x t)
    (dotimes (incount (1+ count) t)
      (princ " "))
    (dotimes (incount (1- (* 2 (- x count))) t)
      (princ "*"))
    (princ "\n")))
triangle-bottom

(diamond 10)
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
 *****************
  ***************
   *************
    ***********
     *********
      *******
       *****
        ***
         *
t

3年越しの悲願達成なので,うれしくてクリスタルくらいの大きさにしてしまいました.ものすごくレベルの低い話だけれど,ものすごく嬉しかったです.

これがLISPだ! (Information & computing (30))

これがLISPだ! (Information & computing (30))