2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |
2008-03-16
CLOSでL-99 (P12 ランレングス圧縮の伸長)
もの凄く下らないんですがconspを使用するような、ifを排除する方法として、補助関数は、先頭の要素だけ別の引数として持っていて、その型を調べるという方法が、イディオムとして使えるなということに気付きました。
もちろんif式を排除する必要性はどこにもありません(笑)
(decode '((4 A) B (2 C) (2 A) D (4 E))) ;=> ((A A A A) (B) (C C) (A A) (D) (E E E E)) (defgeneric DECODE (lst) (:method (lst) (decode1 (car lst) lst))) (defgeneric decode1 (head lst) (:method (head (lst null)) () ) (:method ((head cons) (lst cons)) (let ((head (car lst))) (cons (make-list (car head) :initial-element (cadr head)) (decode1 (cadr lst) (cdr lst))))) (:method (head (lst cons)) (cons (list head) (decode1 (cadr lst) (cdr lst)))))
■
ArcでL-99 (P36 素因数分解 その2)
今回は素因数分解した結果を因数ごとに纏めてリストにして表現するというものです。
ヒントとして、P13をちょっと応用せよ、ということが書いてあります。
という訳で、P13と前回の解答を合体しました。
(def prime-factors-mult (n) ((afn (lst acc) (if no.lst rev.acc (self cdr.lst (cons `(,caar.lst ,(len car.lst)) acc)))) (pack:prime-factors n) () ))
■
第3回 PAIP 本読書会に参加してきました
今日は、Peter Norvig氏の名著「Paradigms of Artificial Intelligence Programming」の読書会に参加して来ました。
初心者の自分に果してついて行けるかどうかということと、まだ本を入手していないということで、今回は見学というスタンスでしたが、欠席の方のPAIPを貸して頂けることになったので普通に参加させて頂くことになりました。
内容は、PAIPの内容を各自順に音読して訳しつつ進めるというものでした。
人前で英語で内容を即時訳して行くのは高校以来位であり、また内容も予習していないので、頭が真っ白になり何を読んでいるのか全然把握できていませんでしたが、周りの皆様に助けて頂きどうにか進めることができました。
頭が真っ白だったので、記憶が曖昧なのですが、以下適当に纏めてみました。
2. A Simple Lisp Program
- ここでは、Lispを使って英文を生成させつつ、抽象化をの技法の入門といった感じ。
- 人に読みやすいプログラムを書くということを解説しつつ、また、そうすることで、Lispベースのちょっとした専用言語のようなものができることを示されているような、いないような。
3. Overview of Lisp
とりあえず、Norvig家家訓として、
コードは、
- 明確に書くべし
- 抽象化を活用すべし
- 簡潔に書くべし
- 予め用意されているもの(関数等)は活用すべし
- 一貫性を持たせるべし
の6訓があるようです。
- defun、defvar、defparameter等のdef-系の説明で、defvar、defparameter、defconstantの使い分けについてと、defstructの機能の解説。
- setfの解説。値を代入するだけでなく、値の場所を指定することにより、その場所を展開して値を代入することが可能であることを解説。また、ユーザがsetfの拡張を定義することが可能。途中、佐野さんより、define-setf-methodという表記は古いというツッコミがはいる。ANSI Common Lispでは、define-setf-expanderに名称変更。また、(defun (setf foo)〜)という定義も可能だよね、というツッコミもありつつ。
- 同じことをするにも複数の書き方があるが、どれが適切かを良く考えることと、どういう表現をするにしても一貫性をもって表現することが大事であることを強調
ちなみに、色々あるlengthの実装で、自分が一番妙だなと思ったのは、
(defun length8 (list) (if (null list) 0 (+ 1 (position-if #'true list :from-end t))))
で、これは、かなり捻らないと出てこない発想じゃないかと思います。読書会の後で話題にもなりました。
また、関連するところでは、Norvig先生は、trueという引数を与えられたら無条件にtを返すという関数を定義しています。
(defun true (&rest ignore) t)
確か、こういう用途には、何かあった筈…という話題も読書会の後の飲み会で出ましたが、家で調べたらconstantlyでした。
constantlyは関数を返す関数で、
(mapcar (constantly t) '(1 2 3 4 5 6)) ;=> (T T T T T T)
のように使えます。こういう場所位でしか使いどころがないと思うので、個人的には是非使ってあげたい関数かなと思います(笑)
また、例に挙げられていない方法でlengthを考えてみる、というのもちょこっと話題になったのですが、自分は、
(defun length-1192 (lst) (apply #'+ (mapcar (constantly 1) lst)))
というのを考えてみました。内容を全部1に置き換えて最後に+を適用するというものです。
次回は、続きで、Macroのところから。
読書会後の飲み会的な会
今回、CL風味の方が結構集まった様子。折角なので、会場近所の店で、色々お話することになりました。
自分としても色々御聞きしたいことがあったのですが、自分は、ひきこもっているということもあり、あまり話をしていない反動で、延々と自分の好きな話題を喋りまくっておりました。ほんとに、すいません(笑)
こういう会をきっかけに、CLが草の根的にどんどん盛り上がっていったら良いなと思いつつ帰宅しました。
■
QiでL-99 (P12 ランレングス圧縮の伸長)
Qiでは、nthが0オリジンではなく、1オリジンというところにはまってしまいました。
(nth 0 ~)とかすると、処理系から返事がなくなってしまったりします。
(decode [[4 a] b [2 c] [2 a] d [4 e]]) \=> [[a a a a] [b] [c c] [a a] [d] [e e e e]] \ (define decode [ ] -> [ ] [H | T] -> [(unpack* (nth 2 H) (nth 1 H) [ ]) | (decode T)] where (cons? H) [H | T] -> [[H] | (decode T)]) (define unpack* Item Cnt Acc -> Acc where (= 0 Cnt) Item Cnt Acc -> (unpack* Item (1- Cnt) [Item | Acc]))