Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
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-01-31

お題(127): 指定コマンドを別プロセスで起動、Arcで参加etc

| 20:09 | お題(127): 指定コマンドを別プロセスで起動、Arcで参加etc - わだばLisperになる を含むブックマーク はてなブックマーク - お題(127): 指定コマンドを別プロセスで起動、Arcで参加etc - わだばLisperになる

Common Lisp部門

今回のお題は、指定コマンドを別プロセスで起動とのこと。

とりあえず、KMRCLのcommand-outputを紹介して終わりました。

Arc部門

もっと「俺も俺も」とドッカンドッカン投稿されるのかと思ってたんですが、今日現在盛り上がってるのは、アジア圏内参加者では私一人だけのようです。

関数名等がCommon Lisp系のものが殆どなので、Common Lispに馴染みがあるとなんとなく気軽かなという気はしています。

そんな感じなので、Schemeの人とかは、Schemeの標準関数とかSRFIを片っ端から作ってしまうという学習方法もアリな気もします(笑)

決められた枠が非常にゆるい気がするので、やりたい放題な印象も受けますし…。

あと、システムのソースのarc.arcを眺めるとやりたいことが、存外さっと見付かって良い感じです。

それはさておき、そういった感じで、簡単なのをつらつらと投稿しております。

  • Hello, world!

とりあえず、昨日のうちに記念で投稿しました。

  • 与えられた数字のケタ数

文字列にして勘定の方向で

  • コラッツ・角谷の問題

前にCLで作ったのを翻訳してみたんですが、元が遅いので動作が遅いままです。

afnってのがあるんですが、結構便利な気がします。

ネーミングはitの代りにselfで参照できるアナフォリック無名関数ってことなんでしょうか。

((afn (x)
   (if (< x 2)
       x
       (+ (self (- n 1))
	  (self (- n 2)))))
 2)

とか。

  • 重複無し乱数

Common Lispのrotatefを使った感じで作ってみました。

  • 重複する要素を取り除く

CL版をそのまま書き直し

  • アレイのuniq

元からあるので、それを紹介

  • n人中m人が当選するくじ

「重複する要素を取り除く」の解答を流用してやっつけ気味

Arcを使ってみてのちょっとしたこと
  1. 全体的に短く書けるだけに、無闇に短くしたくなる。
  2. 関数名が大体3文字に略された単語なので、自分が付ける名前もそんな感じになって行く…。
  3. cdr:memとか割と良い感じに思える。多分馴れると常套句が沢山できる気がする。とりあえず、引数を1つしか取らないのを見付けると、すぐ合体してみたくなる。
  4. (lst 3)とかも案外良い感じ、要するに、lst[3]ということなのだけれど…。
  5. (push (pop (nchcdr lst (rand (len lst)))) res)とかしたかったけど、現状では駄目らしい。

2008-01-22

お題(126): ライフゲーム

| 19:21 | お題(126): ライフゲーム - わだばLisperになる を含むブックマーク はてなブックマーク - お題(126): ライフゲーム - わだばLisperになる

一人でArc祭りをしていたため、どう書くorgのお題をスルーしておりました。

もちろん、ぱっと見で簡単なら、スルーしないんですが、ライフゲームってのがAIっぽくて、いやに難しそうだったので、まあ今回もスルーで良いかなと思っていたんですが、Wikipediaの解説を読んだら、ライフゲームが成立するルールは想像していたより簡単だったので、挑戦することにしました。

以前から升目を見る度に、*LISPが使えるんじゃないかと思ってはいたのですが、今回初めて*LISP(シミュレータ)で書いてみました。

*LISPは、Connection Machine用に開発されたこともあり、並列処理のための構文が沢山あります。

画像処理等も、1ピクセルを1プロセッサに割り振って、一回で処理したりするらしいです。

しかし、附属のチュートリアルを読んでも、全然理解できず、一発で並列処理させる構文も見付けられなかったので、無念ながら普通にループで書きました。

自分のイメージとしては、

(defun get-next!! (〜)
  "セルが次に生きているかを判定する関数"
  〜)

(get-next!! *cell*)
とか
(map!! (lambda (x) (get-env!! x) *cell*) ...etc

みたいな感じで、グリッドを丸ごと一発で処理できる筈だと思ってはいるんですが…。(!!は、グリッド全体を一気に処理する関数に付く目印)

*LISPのインストールについては、割と手間が掛って面倒臭く、解説も長くなりそうなので別エントリに書いてみたいと思います。

2008-01-17

お題: 除算・余剰を使わずに閏年 etc

| 01:25 | お題: 除算・余剰を使わずに閏年 etc - わだばLisperになる を含むブックマーク はてなブックマーク - お題: 除算・余剰を使わずに閏年 etc - わだばLisperになる

お題(123): 必ず解ける迷路

問題を見てすぐに諦めてしまいました(笑)

こういう問題の解法思い付くようになりたいとは思えど…。

お題(124): 除算・余剰を使わずに閏年

割り算を使わないということで、要素数4、100、400の循環リストを作って組み合わせるという方法でアプローチ。時間帯が早朝で誰もいなかったので、1番乗りだ!と思ったら2番目でした…。

なんとなくFizzBuzzっぽい問題な気もしないでもないです。

2008-01-09

お題: 西暦 to 和暦

| 02:01 | お題: 西暦 to 和暦 - わだばLisperになる を含むブックマーク はてなブックマーク - お題: 西暦 to 和暦 - わだばLisperになる

今回の問題は、西暦を和暦に直す問題。といっても明治以降で対応すれば良し、とのこと。

しかし、明治6年までは太陰暦だったらしく、その辺をどう対応するのかはお題ではふれられていないので、意見が分かれている感じ。

…自分は対応しないということで、作成。

しかし、いつも下手なコードを投稿しているけれど、我ながら、今回はいつもに増してひどい気がするなあ(;´Д`)。

こういう予め決められたパラメータが多く出現するような問題の場合、パラメータの扱いをどうしたら良いのかが、いまいち分からない…。

2008-01-04

お題: ポーカーの役判定

| 01:21 | お題: ポーカーの役判定 - わだばLisperになる を含むブックマーク はてなブックマーク - お題: ポーカーの役判定 - わだばLisperになる

とりあえず新しいお題が出題されたので挑戦。

毎度ながらノープランで書き始め、なんとか完成。

コピペミスで古いバージョンをアップしてしまい修正。

Slimeだと開発が対話的で便利過ぎるのかLispのコアイメージの中の環境とファイルのソースに書かれた内容が食い違うことも発生しがちなので、提出の際には一旦コードを素の状態からロードさせて正しく動作するか確認するようにしないといけないな、と改めて思ったり。

しかし、多分、私は、Slimeの支援なしでは、何一つ書けないんだろうなと思う。

ちょっと書いて、直してコンパイル、コンパイラに怒られて、直してコンパイル、〜という感じで、コンパイラが指摘してくれないと、どこにも辿り着けない(´▽`*)

2008-01-03

お題: Hello, World! 等々

| 15:03 | お題: Hello, World! 等々 - わだばLisperになる を含むブックマーク はてなブックマーク - お題: Hello, World! 等々 - わだばLisperになる

最初は、Lisp1.5で問題を解くってのはかなり難しいのではと思っていましたが、そこそこ行けるんじゃないかと思えて来ました。

現在6/120なのでコンプリ率は約5%。Lisp 1.5のコーナーできたら良いなー。

(2)お題: Hello, world!(Lisp1.5)

文字の出力で空白の出力方法が分からなかったので後回しにしていたHello, World!

マニュアルに基本的な出力方法が記載されていたので、それを試してみた。

それにしても謎が多いLisp 1.5。

(40)お題: 与えられた数字のケタ数(Lisp1.5)

他の方は、文字列に変換して文字列の長さから桁を割出していましたが、

Lisp1.5では若干無理があるので、素直に勘定することに。

Lisp 1.5をさわってみて若干分かったことなど、なんの役にも立たないメモ

  • cond
    1. (cond (述部 実行部?))の実行部が暗黙のprognでない。また省略もできない。そのため、空の場合、明示的にNIL、F、()を置く。実行部には複数の式を書いてもエラーにはならないが、一番上だけ実行されて、あとは無視される。progで囲んだり、prog2で囲む必要あり。(しかし、マニュアルには載ってるけどprog2がみつからない…)lambdaで囲んでも丸ごと無視されるので、progで安定の模様。
    2. デフォルト節の述部は、(quote T)か、Tか*TRUE*で受ける。
  • M式

大文字で書かれたシンボルはquoteされていることを表わしているらしい。つまりM式のTは、S式で(quote t)のことで、律義に(quote t)と書いている人も結構いる。MACLISPで、'Tと書いたりする人がいるのは、この伝統を受け継いでいるのかもしれない。ちなみに、自分も'Tと書いていたら、点がないのはなんか寂しい気がして毎度付けてしまう変な癖が…。

2008-01-02

お題: コラッツ・角谷の問題 等々

| 22:46 | お題: コラッツ・角谷の問題 等々 - わだばLisperになる を含むブックマーク はてなブックマーク - お題: コラッツ・角谷の問題 等々 - わだばLisperになる

(120)お題: コラッツ・角谷の問題(Common Lisp)

お題の名前からして、久々に数学的で複雑な問題だー、と思って無理だと思い放置して風呂に入って寝ようと思っていましたが、どうにも気になって眠れなかったので、どういう仕組になるのかだけ簡単にさらってみることにしてみたら、そんなに嫌がる程の問題でもなかった様子。

別名3n+1問題ともいわれる有名な問題らしいです。

ひたすらCPUをぶん回すだけのコードでしたが、とりあえずできたので投稿してみました。Common Lisp部門2着。

他の方々は、賢くメモ化とかして高速化をはかっていました。そうなのか! メモ化とかするもんなのか!

投稿してから自分も真似して自作のものをメモ化などをして高速化をはかってみましたが、ハッシュでのメモ化による高速化具合と、数字を全部fixnumで宣言し2の割り算を左シフトしてコンパイラの頑張り任せにする馬鹿バージョンを計測したところ、どういうわけか割り算をシフトにした方が速かったので、まあ、これでも良いや、ということにしました。

fixnum宣言+左シフトは、SBCLそのままの割り算に比べて8倍位速くなるんですよね。どういう理屈かは知りませんが…。

3の掛け算も右シフト+Nにした方が若干速くなるし、fixnum宣言とシフト命令って相性が良いんでしょうか。まあ、fixnumの範囲を越えるとまずいですが、今回は範囲内なのでOKです。

(27)お題: リストを逆順に表示 (Lisp 1.5)

Common Lispに加えて、馬鹿っぽくLisp 1.5でも挑戦してみることにしました。

標準でREVERSEはあるっぽいんですが、自分が使ってるキットにはないので自作。まあ、次回からREVERSEの定義は省略ということで。

(16)お題: アレイのuniq (Lisp 1.5)

MEMBERも標準で付いてくるっぽいけどないので自作。マニュアルで確認しないといけないのが若干面倒なのでLisp 1.5関数一覧とか作ろうと思ったり。

(49)お題: 隣り合う二項の差 (Lisp 1.5)

一応再帰でも書けるので、再帰で書いてみた。

(120)お題: コラッツ・角谷の問題(Lisp 1.5)

Common Lispの内容をLisp 1.5で。7時間回して一応正しい答えだったので投稿。

  THE TIME ( 0/ 0  000.0) HAS COME, THE WALRUS SAID, TO TALK OF MANY THI
NGS .....   -LEWIS CARROLL-
 END OF EVALQUOTE OPERATOR
             FIN      END OF LISP RUN

それはさておき、Lisp 1.5では、実行が終わるとこのように表示されるんだけれども、この時間のところに実行時間とか入って欲しいなと。

どうするんだろう…。エミュレータじゃ無理なのだろうか。

2007-12-31

お題: コマンドライン引数の取得、年間カレンダー

| 10:01 | お題: コマンドライン引数の取得、年間カレンダー - わだばLisperになる を含むブックマーク はてなブックマーク - お題: コマンドライン引数の取得、年間カレンダー - わだばLisperになる

最近、アルゴリズム的な問題ばっかりだー、という意見がでてから、急にパズル的でない問題が増えてきました。

(118)コマンドライン引数

コマンドライン引数の取得は、処理系依存なので、KMRCLの紹介を投稿して終了。

良く考えれば、Common Lispでは処理系依存の処理を切り分ける記述ができるので、できるだけ多くの処理系をフォローするようなコードを書いた方が良かったと反省。

まあ、今からでも調べて投稿はできるんですが(笑)

(119)年間カレンダー

年間カレンダーを表示させる問題でこれもパズル的ではない問題。

他の言語の方をみてみると20行位で書いてました。自分には20行で書くのは無理だなーと思いつつ挑戦。

Date-Calcが使えそうだったので使ってみましたが、

無駄が多くて無理矢理気味な感じになってしまいました。

25行程度に収まったので、とりあえず良しとします。

2007-12-25

お題: ワーカスレッドを安全に終了させるまで待機

| 05:10 | お題: ワーカスレッドを安全に終了させるまで待機 - わだばLisperになる を含むブックマーク はてなブックマーク - お題: ワーカスレッドを安全に終了させるまで待機 - わだばLisperになる

今回もアルゴリズム云々ではないので、何とか試作する位はできそう、ということで挑戦。

メインのスレッドがあって、スレッドプールからスレッドを拾ってきて仕事をさせて、子供のスレッドが全部終了するのを確認して次の仕事へ…というようなものを作れとのこと。

うーん。マルチスレッド関係なのでPortable-Threadsが使えるとは思うものの、スレッドプールをどうしたもんかと。

結構ググったりしてみたけれど、スレッドの使い回しの情報はみつけられず、とりあえずスレッドプールを使ってない方も何名かいらしたので自分も使わないということにして、投稿。

Common Lispでの定番スレッド処理ってどんな感じなんでしょう。The Common Lisp Cookbook - Threadsも結構複雑です。

まあ、自分は、そもそもスレッド処理自体分かってなかったりしますが…。

何か題材を見付けて色々練習してみよう。

2007-12-23

お題: 法演算

| 06:03 | お題: 法演算 - わだばLisperになる を含むブックマーク はてなブックマーク - お題: 法演算 - わだばLisperになる

一時期、集中的に熱中してどう書く.orgに参戦して、自作のうんこちゃんクオリティのプログラムを投下していましたが、アルゴリズムを捻り出すような問題が多くなってきてしまったので、元が捻り出せない自分は挫折しておりました。

でも、やっぱり勉強になるのでできそうなもの位は投稿してみることにしました。

今回は、法演算ということですが、問題を見にいった時にschemeでの解答を見てしまったため、もう、それ以外の方法の解答は考えられなくなってしまい、結局パクリになりました。

(defmacro with-mod (div &body body)
  `(%with-mod ((+ - * /) ,div) ,@body))

(defmacro %with-mod (((&rest fns) div) &body body)
  (let ((g (gensym)))
    `(let ((,g (labels ,(mapcar
                         (lambda (fn)
                           `(,fn (&rest expr) 
                                 (mod (apply (symbol-function ',fn) expr) ,div)))
                         fns)
                 ,@body)))
       (if (numberp ,g) (mod ,g ,div) ,g))))

という解答でしたが、

%with-modは、fletにするべきでした。再帰してる訳でもないしsymbol-functionもいらなくなるし…。

こういうのは大体投稿してから気付くという。

(defmacro %with-mod (((&rest fns) div) &body body)
  (let ((g (gensym)))
    `(let ((,g (flet ,(mapcar
		       (lambda (fn)
			 `(,fn (&rest expr) 
			       (mod (apply #',fn expr) ,div)))
		       fns)
                 ,@body)))
       (if (numberp ,g) (mod ,g ,div) ,g))))

どう書く.orgのCommon Lisp部は、一時賑やかだったみたいですが、自分が参加し始めた9月頃からは、常駐組は恐らく1、2名程になってしまいました。もしかしたら、どう書く.org自体への参加者が減ってるのかもしれませんが…。ちなみに、Common Lisp部は自分が全体のレベルを下げておりますので、参加する際の敷居は低いと思われます。

2007-08-26

.1

| 23:10 | .1 - わだばLisperになる を含むブックマーク はてなブックマーク - .1 - わだばLisperになる

自分も「どう書く?org」に参加してみたくなってアカ

ウントを作成してみた。しかし自分の解けそうな問題が

あまりない…。

投稿するにはなんとなく旬を過ぎてしまったので、ここ

に載せてみるのだった…。

;; ================================================================
;; 隣り合う二項の差
;; ================================================================
(defun diff (list)
  (mapcar #'- (cdr list) list))

(defun diff (list)
  (do ((l list (cdr l))
       (r () (cons (- (cadr l) (car l)) r)))
      ((endp (cdr l)) (nreverse r))))

;; ================================================================
;;重複無し乱数リスト
;; ================================================================
(defun bingo (n)
  (let ((l (loop for i from 1 to n collect i)))
    (dotimes (i n l)
      (rotatef (nth i l) (nth (random n) l)))))

;; ================================================================
;; ビンゴの結果を整形表示 
;; ================================================================
(defun format-bingo (n)
  (let* ((keta (1+ (truncate (log n 10))))
	 (fstr (format nil "~{~A~}" (list "~{~" (1+ keta) "@A~}~%" 
					  "~{~" (1+ keta) "@A~}~%~%"))))
    (do ((cnt n (- cnt 10))
	 (l (bingo n) (nthcdr 10 l))
	 (idx (loop for i from 1 to n collect i) (nthcdr 10 idx)))
	((endp l))
      (if (<= 10 cnt)
	  (format t fstr (subseq idx 0 10) (subseq l 0 10))
	  (format t fstr idx l)))))