2010/07/30

fold, unfold

Gauche のマニュアル見ても unfold, unfold-right はいまいちピンときませんでしたが、srfi の方読んだらイメージが頭に定着した気がしました。気がしました。
unfold は基本的な再帰的リスト コンストラクタ
fold-right と unfold はある意味で逆操作
unfold-right は基本的な反復的リスト コンストラクタ
fold と unfold-right はある意味で逆操作

;; SRFI 1: リスト ライブラリ http://www.chino-js.com/tech/srfi/srfi-1/srfi-1.html#zip
(use srfi-1)
(unfold-right null? car cdr (fold cons '() '(1 2 3 4 5)))
;; (1 2 3 4 5)
(let ((seq (cut <> cons '() '(1 2 3 4 5)))
(rev (cut <> null? car cdr <>)))
(values (rev unfold-right (seq fold))
(rev unfold (seq fold-right))))
;; (1 2 3 4 5)
;; (1 2 3 4 5)
(let ((seq (cut <> cons '() '(1 2 3 4 5)))
(rev (cut <> null? car cdr <>)))
(equal? (rev unfold-right (seq fold))
(rev unfold (seq fold-right))))
;; #t
view raw fold-unfold.scm hosted with ❤ by GitHub


プログラミングGauche

2010/07/29

L-99 19 ~ 26

取りあえず貼っておきます。。

The Little Schemer, 4th Edition

Gauche group-sequence と L-99 の L09

マイペースに L-99 を続けてきましたが、L27 がなかなか解けなくて滞っています。。

ところで、掲題の通り L09 については、Gauche に group-sequence というものがあったのでメモ。
(use gauche.sequence)
(group-sequence '(1 1 1 2 3 4 4 2 2 3 1 1 3))
;; ((1 1 1) (2) (3) (4 4) (2 2) (3) (1 1) (3))
(group-sequence '(a a a a b c c a a d e e e e))
;; ((a a a a) (b) (c c) (a a) (d) (e e e e))


自分で書いたのは、こんな感じでした。
;; P09 (**) Pack consecutive duplicates of list elements into sublists.
;; If a list contains repeated elements they should be placed in separate sublists.
;; Example:
;; * (pack '(a a a a b c c a a d e e e e))
;; ((A A A A) (B) (C C) (A A) (D) (E E E E))
(define (pack ls . opt)
(let-optionals* opt ((eq? eq?))
(pair-fold-right
(lambda (pr acc)
(apply acons (car pr)
(if (or (null? acc)
(not (eq? (car pr)(caar acc))))
`(() ,acc)
`(,(car acc),(cdr acc)))))
'() ls)))
(pack '(a a a a b c c a a d e e e e))
;; ((a a a a) (b) (c c) (a a) (d) (e e e e))
(pack '(1))
;; ((1))
(pack '(1 2 3 1 2 3))
;; ((1) (2) (3) (1) (2) (3))
(pack '())
;; ()
(pack (map (cut cons <> '())
'(a a a a b c c a a d e e e e)))
;; (((a)) ((a)) ((a)) ((a)) ((b)) ((c)) ((c)) ((a)) ((a)) ((d)) ((e)) ((e)) ((e)) ((e)))
(pack (map (cut cons <> '())
'(a a a a b c c a a d e e e e)) equal?)
;; (((a) (a) (a) (a)) ((b)) ((c) (c)) ((a) (a)) ((d)) ((e) (e) (e) (e)))
view raw L09.scm hosted with ❤ by GitHub


プログラミングGauche

2010/07/24

連番リストの歯抜け

scheme でこんなんどうでしょう。

上は再帰で、歯抜けがあったらその歯抜けも追加したリストを次の再帰に渡しています。歯抜けは acc に保存。
下は iota で完全な集合(完全な連番のリスト)を作って、引数との差集合を求めています。
(define (pick-toothless ls)
(let rec ((ls ls)(acc '()))
(if (or (null? ls)
(null? (cdr ls)))
(reverse acc)
(let1 next (+ (car ls) 1)
(if (= next (cadr ls))
(rec (cdr ls) acc)
(rec (cons next (cdr ls))
(cons next acc)))))))
(pick-toothless '(1 2 3 5 6 8 9))
;; (4 7)
(pick-toothless '(1 2 4 5 10))
;; (3 6 7 8 9)
(use srfi-1)
(define (pick-toothless ls)
(if (null? ls)
'()
(let ((min (car ls))(max (last ls)))
(let1 pls (iota (+ (- max min) 1) min)
(lset-difference = pls ls)))))
(pick-toothless '(1 2 3 5 6 8 9))
;; (4 7)
(pick-toothless '(1 2 4 5 10))
;; (3 6 7 8 9)


The Little Schemer, 4th Edition

2010/07/21

fold with index : fold/index

でっち上げるとしたらこんな感じでしょうか。
;; fold with index
(define (fold/index proc init ls . lss)
(let1 idx 0
(apply fold (lambda args
(begin0
(apply proc (append args (list idx)))
(set! idx (+ idx 1))))
init (cons ls lss))))
(fold/index (lambda (e acc idx)
(acons idx e acc))
'() '(a b c d e))
;; ((4 . e) (3 . d) (2 . c) (1 . b) (0 . a))
(fold/index (lambda (e1 e2 acc idx)
(acons e1 (cons e2 idx) acc))
'() '(a b c d e)'(f g h i j k))
;; ((e j . 4) (d i . 3) (c h . 2) (b g . 1) (a f . 0))
;; fold-right with index
(use srfi-1)
(define (fold-right/index proc init ls . lss)
(let1 idx (- (length ls) 1)
(apply fold-right (lambda args
(begin0
(apply proc (append args (list idx)))
(set! idx (- idx 1))))
init (cons ls lss))))
view raw index.scm hosted with ❤ by GitHub

追記

書かなくてもありました。

プログラミングGauche

fold (複数リスト引数)

scheme を始めた当初から「どうなってんだろう?」と気になっていた複数のリストを引数に取れる fold や map 。
cars+cdrs 同様、カンニングしながら書いてみた。
(use srfi-8)
(define (fold proc init ls . lists)
(let loop ((lists (cons ls lists))(acc init))
(receive (cars cdrs)(apply cars+cdrs lists)
(let ((ans (apply proc (append cars (list acc)))))
(receive (l1 rest)(car+cdr cdrs)
(if (null? l1)
ans
(loop cdrs ans)))))))
(fold + 0 (with-module srfi-1 (iota 10 1)))
;; 55
(fold * 1 (with-module srfi-1 (iota 5 1)))
;; 120
(fold + 0 '(1 2 3 4 5)'(1 2 3 4 5))
;; 30
(fold cons '() '(a b c))
;; (c b a)
(fold acons '() '(a b c)'(1 2 3))
;; ((c . 3) (b . 2) (a . 1))
(with-module srfi-1 (fold acons '() '(a b c)'(1 2 3)))
;; ((c . 3) (b . 2) (a . 1))
view raw fold.scm hosted with ❤ by GitHub

これはなるほど過ぎる。。
receive が一つ余計かな、というか二つ目の receive のところダメかも?

追記

修正版。複数のリストを渡した時に、リストの要素数が違うとエラーになっていた部分を修正。最も要素数の少ないリストが終わるまで処理を行ないます。
;; srfi-1::fold
(use srfi-8) ; receive
(use srfi-1) ; car+cdr
(define (cars+cdrs ls . rest-lists)
(let/cc hop
(let loop ((lists (cons ls rest-lists)))
(if (null? lists)
(values '() '())
(receive (ls rest-lists)(car+cdr lists)
(if (null? ls)
(hop '() '())
(receive (a d)(car+cdr ls)
(receive (cars cdrs)(loop rest-lists)
(values (cons a cars)(cons d cdrs))))))))))
(define (fold proc init ls . lists)
(let loop ((lists (cons ls lists))(acc init))
(receive (cars cdrs)(apply cars+cdrs lists)
(let ((ans (apply proc (append cars (list acc)))))
(if (any null? cdrs)
ans
(loop cdrs ans))))))
(fold + 0 (with-module srfi-1 (iota 10 1)))
;; 55
(fold * 1 (with-module srfi-1 (iota 5 1)))
;; 120
(fold + 0 '(1 2 3 4 5)'(1 2 3 4 5))
;; 30
(fold cons '() '(a b c))
;; (c b a)
(fold acons '() '(a b c)'(1 2 3))
;; ((c . 3) (b . 2) (a . 1))
(with-module srfi-1 (fold acons '() '(a b c)'(1 2 3)))
;; ((c . 3) (b . 2) (a . 1))
(fold acons '() '(1 2 3 4 5)'(a b c d))
;; ((4 . d) (3 . c) (2 . b) (1 . a))
(fold acons '() '(a b c)'(1 2 3 4 5))
;; ((c . 3) (b . 2) (a . 1))
(fold acons '() '(1 2 3)'(a b c d e))


プログラミングGauche

cars+cdrs

カンニングしつつ書いてみた。
(use srfi-8)
(define (cars+cdrs ls . rest-lists)
(let1 lists (cons ls rest-lists)
(let loop ((lists lists))
(if (null? lists)
(values '() '())
(receive (ls rest-lists)(car+cdr lists)
(receive (a d)(car+cdr ls)
(receive (cars cdrs)(loop rest-lists)
(values (cons a cars)(cons d cdrs)))))))))
view raw cars+cars.scm hosted with ❤ by GitHub


プログラミングGauche

2010/07/16

「引用」のことがよくわからない

タンブラーとかツイッターとか、あの辺はどうなんでしょう。わりとやりたい放題やってるように見えますが。。

下記の文章を読んでもよくわかりません。
引用(第32条)
[1]公正な慣行に合致すること,引用の目的上,正当な範囲内で行われることを条件とし,自分の著作物に他人の著作物を引用して利用することができる。同様の目的であれば,翻訳もできる。(注5)[2]国等が行政のPRのために発行した資料等は,説明の材料として新聞,雑誌等に転載することができる。ただし,転載を禁ずる旨の表示がされている場合はこの例外規定は適用されない。
(注5)引用における注意事項
他人の著作物を自分の著作物の中に取り込む場合,すなわち引用を行う場合,一般的には,以下の事項に注意しなければなりません。
(1)他人の著作物を引用する必然性があること。
(2)かぎ括弧をつけるなど,自分の著作物と引用部分とが区別されていること。
(3)自分の著作物と引用する著作物との主従関係が明確であること(自分の著作物が主体)。
(4)出所の明示がなされていること。(第48条)
(参照:最判昭和55年3月28日 「パロディー事件」)

自分には判断できません。。
引用の目的上,正当な範囲内
引用する必然性がある
引用する著作物との主従関係が明確である
自分の著作物が主体

「どこまでOK?」迷ったときのネット著作権ハンドブック

言語は4層に分割されるべき

言語は少なくとも4つの層に分割されるべきだ:
  1. カーネル言語は単純で実装しやすいものとなる。どんなケースにおいても、動的な再定義は再考を加えて、このレベルでのサポートが必要かどうかを判断するべきだ。私は再定義可能なものがカーネル内に必要だとは思わない。
  2. 言語を肉付けする言語学的な層。この層は実装上の困難が若干伴うかもしれない。そしてここには多分、カーネルで実装するには高価すぎるが割愛するには重要すぎる動的な側面が含まれることになる。
  3. ライブラリ。Common Lispにあるものの大半はこの層に置かれる。
  4. 環境として提供されるエピ言語的機能。

個人的な妄想ですが、純 Lisp + いくつかのプリミティブ、マクロ、リーダーマクロ、継続を用意して、残りを全部それ自身で実装して行くのって楽しそうだなーなどと思います。
ところで、純 LISP を作れば、Lisp の他の機能はすべて実装できるって話がありますけども、実際やった人いるんでしょうか。本当にできるなら、それはそれで面白そうかも。

もしかして、純 LISP で 純 LISP + α を実装して、さらにその LISP で機能追加した LISP を実装して・・・の繰り返し、ということなんでしょうか。。

実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

物理的に身近なところに師匠が欲しいですね。

昨日 Twitter にて、掲題のようなこと(物理的に身近なところに師匠が欲しいですね。)を言っておりましたら、皆さん同じお気持ちのご様子で。何故そのような気持ちに至ったかと申しますと、下記の書籍を読んでいるためでございます。

ソフトウェア開発における徒弟制度や職人モデルの可能性について述べられております。

ソフトウェア職人気質―人を育て、システム開発を成功へと導くための重要キーワード (Professional Computing Series) P.74 より引用

職人は経験を積むことによって腕を上ていくものなのです。鍛冶屋のような伝統的な肉体的技芸でさえも, 70歳の名職人が自身の仕事の質を追求しています。古株はどのような分野においても価値があるのです。彼らの幅広く深い経験が, 仕事の品質に大きな違いをもたらすからです。職人は, 過去を尊重しながら, 現在も熱心に学習を続けるため, 将来的に技芸のさらに上の域を極めることができるのです。

...意気込みのある初心者と洞察力のある熟練者や職人がやり取りを行うと素晴しいことが起ります。実際に, 誰が弟子で誰が職人か判らないような場面にも出くわすくらいです。もちろん, ちょっと見ていれば役割は明らかなのですが。(Ken Auer, Role Model Software, Inc., 私信)

師匠というものは、作業風景を見ているだけで独習より実りあるものであると存じます。

私にも以前、師匠と呼べる人がおりました。3年という短い期間で師匠の元を去り、師事する機会を失ってしまったことは、自らの決断によるところとしても未だ悔まれるものであります。


ソフトウェア職人気質―人を育て、システム開発を成功へと導くための重要キーワード (Professional Computing Series)

面白そうなのでまとめとく


入門 GNU Emacs 第3版

面白かったのでまとめとく


On Lisp

2010/07/15

「たった1人のために設計する方が, ずっと大きな成功を収めることができるのです。」

ソフトウェア職人気質―人を育て、システム開発を成功へと導くための重要キーワード (Professional Computing Series) P.51 より
もしも50%の製品満足度を達成したいのであれば, 大衆全体を50%満足させるような方法ではだめなのです。これを実現するには, 人々の中から50%を選抜し, 彼らを100%満足させるしか方法はありません。しかしこれによって, 予想以上の結果が期待できるのです。そして市場の10%をターゲットとし, 彼らを100%熱狂させることができれば, ずっと大きな成功を得ることができるでしょう。このことは直感に反しているかもしれませんが, 大衆を満足させる最も有効な方法は「1人のユーザ」のために設計を行うことなのです。
(Cooper, A. The Inmates Are Running the Asylum, pp.125-126 邦訳:pp.228-229)

この引用の前のクライスラーの話も面白い。購買対象者の80%が嫌い、20%が好んだ車がベストセラーになったという。。

タイトル

記事のタイトルは コンピュータは、むずかしすぎて使えない! P.226-227 より。
「たった1人のために設計する方が, ずっと大きな成功を収めることができるのです。」

余談

達人プログラマー―システム開発の職人から名匠への道人月の神話―狼人間を撃つ銀の弾はない (Professional Computing Series) の他書籍での引用され率は異常。。
達人の方は持ってますが、途中までしか読んでいません。。人月の方は30年前の本なんでしったっけ。きっと絶版になることはないでしょうから、そのうち。

余談2

引用の加減が未だによくわからない。

ソフトウェア職人気質―人を育て、システム開発を成功へと導くための重要キーワード (Professional Computing Series)

fold わいいよ fold

L-99 の01~09を、fold 系手続きを使って書いた例。

L01
;; P01 (*) Find the last box of a list.
;; Example:
;; * (my-last '(a b c d))
;; (D)
(define (my-last ls . opt)
(let-optionals* opt ((failed #f))
(let/cc hop
(pair-fold-right (lambda (pr acc)
(print pr)
(if (null? (cdr pr))
(hop pr)
acc))
failed ls))))
(my-last '(a b c d))
;; (d)
(my-last '())
;; #f
(my-last '() "hoge")
;; "hoge"
(my-last '(a . b))
;; error
view raw L01.scm hosted with ❤ by GitHub

L02
;; P02 (*) Find the last but one box of a list.
;; Example:
;; * (my-but-last '(a b c d))
;; (C D)
(use srfi-1)
(define (my-but-last ls . opt)
(let-optionals* opt ((failed #f))
(let/cc hop
(pair-fold-right (lambda (pr acc)
(if (not (null? (cdr pr)))
(hop pr)
acc))
failed ls))))
(my-but-last '(a b c d))
;; (c d)
(my-but-last '(c d))
;; (c d)
(my-but-last '(d))
;; #f
(my-but-last '() '())
;; ()
view raw L02.scm hosted with ❤ by GitHub

L03
;; P03 (*) Find the K'th element of a list.
;; The first element in the list is number 1.
;; Example:
;; * (element-at '(a b c d e) 3)
;; C
(define (element-at ls n)
(if (or (< (length ls) n)
(not (positive? n)))
(error "out of range")
(let/cc hop
(fold (lambda (e acc)
(if (= acc 1)
(hop e)
(- acc 1)))
n ls))))
(element-at '(a b c d e) 3)
;; c
(element-at '(a b c d e) 0)
;; error
(element-at '() 0)
;; error
(element-at '(a b c) 5)
;; error
view raw L03.scm hosted with ❤ by GitHub

L04
;; P04 (*) Find the number of elements of a list.
(define (my-length ls)
(fold (lambda (e acc)
(+ acc 1))
0 ls))
(my-length '(1 2 3 4 5))
;; 5
view raw L04.scm hosted with ❤ by GitHub

L05
;; P05 (*) Reverse a list.
(define (my-reverse ls)
(fold cons '() ls))
(my-reverse '(1 2 3))
;; (3 2 1)
view raw L05.scm hosted with ❤ by GitHub

L07
;; P07 (**) Flatten a nested list structure.
;; Transform a list, possibly holding lists as elements into a `flat' list by replacing each list with its elements (recursively).
;; Example:
;; * (my-flatten '(a (b (c d) e)))
;; (A B C D E)
;; Hint: Use the predefined functions list and append.
(define (flatten tree)
(fold (lambda (e acc)
(append acc
(if (list? e)
(flatten e)
(list e))))
'() tree))
(flatten '(a (b (c d) e)))
;; (a b c d e)
(flatten '(((a)(b c d))(e (f g))(h i j (((((((k l m (n)))))))))))
;; (a b c d e f g h i j k l m n)
view raw L07.scm hosted with ❤ by GitHub

L08
;; P08 (**) Eliminate consecutive duplicates of list elements.
;; If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed.
;; Example:
;; * (compress '(a a a a b c c a a d e e e e))
;; (A B C A D E)
(define (compress ls . opt)
(let-optionals* opt ((ep? equal?))
(pair-fold
(lambda (pr acc)
(let/cc hop
(append acc
(if (null? (cdr pr))
pr
(if (ep? (car pr)(cadr pr))
(hop acc)
(list (car pr)))))))
'() ls)))
(compress '(a a a a b c c a a d e e e e))
;; (a b c a d e)
(compress '(a b))
;; (a b)
(compress '(a))
;; (a)
(compress (map (cut cons <> '()) '(a a a a b c c a a d e e e e)) eq?)
;; ((a) (a) (a) (a) (b) (c) (c) (a) (a) (d) (e) (e) (e) (e))
(compress (map (cut cons <> '()) '(a a a a b c c a a d e e e e)))
;; ((a) (b) (c) (a) (d) (e))
view raw L08.scm hosted with ❤ by GitHub

L09
;; P09 (**) Pack consecutive duplicates of list elements into sublists.
;; If a list contains repeated elements they should be placed in separate sublists.
;; Example:
;; * (pack '(a a a a b c c a a d e e e e))
;; ((A A A A) (B) (C C) (A A) (D) (E E E E))
(define (pack ls . opt)
(let-optionals* opt ((eq? eq?))
(pair-fold-right
(lambda (pr acc)
(apply acons (car pr)
(if (or (null? acc)
(not (eq? (car pr)(caar acc))))
`(() ,acc)
`(,(car acc),(cdr acc)))))
'() ls)))
(pack '(a a a a b c c a a d e e e e))
;; ((a a a a) (b) (c c) (a a) (d) (e e e e))
(pack '(1))
;; ((1))
(pack '(1 2 3 1 2 3))
;; ((1) (2) (3) (1) (2) (3))
(pack '())
;; ()
(pack (map (cut cons <> '())
'(a a a a b c c a a d e e e e)))
;; (((a)) ((a)) ((a)) ((a)) ((b)) ((c)) ((c)) ((a)) ((a)) ((d)) ((e)) ((e)) ((e)) ((e)))
(pack (map (cut cons <> '())
'(a a a a b c c a a d e e e e)) equal?)
;; (((a) (a) (a) (a)) ((b)) ((c) (c)) ((a) (a)) ((d)) ((e) (e) (e) (e)))
view raw L09.scm hosted with ❤ by GitHub


その他、一般的な再帰や末尾再帰でも書いています。

実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

2010/07/14

L-99 07, 08

これ少しずつやってます。
git にリポジトリ作ったんですが、gist みたいに手軽にブログに貼り付けられないので困りました。。何か他に手軽な方法はないかしら・・・。
うーん、やっぱ貼り付けたいな。大したものでなくても、その方がモチベーション上がる。

Schemeによる記号処理入門

git error: failed to push some refs to 'git@github.com:foo/hoge.git' To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes before pushing again. See the 'non-fast forward' section of 'git push --help' for details.

error: failed to push some refs to 'git@github.com:foo/hoge.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'non-fast forward'
section of 'git push --help' for details.


作業用ブランチ作る



git branch temp1
git checkout temp1

作業用ブランチにpullする



git pull origin +master:temp1

作業用ブランチとmasterブランチの差分を確認する



git diff temp1 master

masterブランチに作業用ブランチの内容をマージする



git checkout master
git merge temp1

入門Git

L-99 和訳 Python

私も先日からぼちぼちやってみています。日本語訳はありがたいです。
Python と言えば、昨日書店で見かけた リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing) がすごく面白そうでした。
アプリケーションをハックして壊す方法など,きわどいネタがてんこ盛り。
リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)

多くの情報を抱え込みたくなる理由

アドレナリンジャンキー プロジェクトの現在と未来を映す86パターン P.121 「裸の組織」より
ほかの人が知っていることを知らないことに対する恐怖である。
この恐怖に屈すると、初めてのおとなの宴席に参加した子供のように、何か食べ損ねることを恐れて、おいしそうなものを全部口に詰め込んでしまう。
自分の情報プレートにどれぐらいの分量がちょうどいいかを知ることは、単に優れた戦略であるだけでなく、おとなになるということだ。
思い当たります。すぐに溢れます。焦ります。難しいです・・・。
あの人は理解しているのに、自分ときたら何一つ理解していない・・・。
あの人はやっているのに、自分ときたら何一つやっていない・・・。
あの人は読み終わっているのに、自分ときたら何一つ読み終わっていない・・・。
こういうことよくあります。でも、目標とする人や憧れる人がいても、その人になる必要はないんですよね。同じことを知っていて、同じことができるっていうのはおもしろくなさそうです。同じようにできないから良いんですよ、きっと。そう思うことにしましょう。

理解できるところから始めて、やるべきことよりやりたいことをやって、読みたいものを読む。それで別に悪くないじゃあないか、と思います。その方が健康的です。結果はどうあれ。


アドレナリンジャンキー プロジェクトの現在と未来を映す86パターン

2010/07/13

L-99 01 ~ 06

こういうのをボチボチやるの好きです。
って、いつものように gist のノリでコードを貼り付けようと思ったら・・・、あれは github の方にはないんですね・・・。

PAIP「第3部の内容を習得した読者は、上級のLispプログラマと見なしてよいだろう。」

送信者 Jennifer
とうとう買いましたー\(^o^)/熊本市内は下通りダイエーの喜久屋書店で。
第3部の内容を習得した読者は、上級のLispプログラマと見なしてよいだろう。(まえがきより)
ちなみに第5部まで25章928ページ!すげぇ厚さです・・・。

20年くらい前の本の和訳とのことです。著者の人は現在 Google のえらい人なのだとか。
よそ様の書評とか

こんなのあってるのか・・・。良いな、東京。しかしなんで404の人んち?

実用 Common Lisp (IT Architects’Archive CLASSIC MODER)

2010/07/09

git permission denied (publickey) faital: the remote end hung up unexpectedly

最近 gist しか使ってなくて、久しぶりに git の方でコミットしようと思ったら・・・。
$ git push origin master
Permission denied (publickey).
fatal: The remote end hung up unexpectedly


入門Git実用Git

0~9の数字からなる3~4桁の組み合わせで1と6を含むもの

をサクッと知りたかった。
;; http://d.hatena.ne.jp/ibaza/20080303/1204476552
;; nCr(n個からr個取り出す組合せ)は、
;; 1. リストの先頭要素を除いた残りのリストからr-1個を選ぶ組合せのそれぞれに先頭要素を加えたものと、
;; 2. リストの先頭要素を除いたリストからr個を選ぶ組合せの合計となる(1および2はそれぞれ再帰処理となる)。
;; 3. n = r のときは選び方は一つなのでリストをそのままリストにして返す。例:(a b c) なら ((a b c)) にして返す
;; 4. r = 1 のときは選び方はn通りあるのでリストの要素をそれぞれリストにして返す。例:(a b c) なら ((a) (b) (c)) にして返す
;; 5. r = 0 または r がリストの要素数より大きいときは空リストを返す。
(define (combination ls r)
(let ((nlen (length ls)))
(cond ((or (null? ls)
(not (positive? r))
(< nlen r)) '())
((= r 1)(map list ls))
((= nlen r)(list ls))
(else (append (map (pa$ cons (car ls))
(combination (cdr ls)(- r 1)))
(combination (cdr ls) r))))))
(print (combination '(1 2 3 4 5 6 7 8 9) 3))
(use util.combinations)
(use srfi-1)
(lset= equal?
(combination '(1 2 3 4 5 6 7 8 9) 3)
(combinations '(1 2 3 4 5 6 7 8 9) 3))
(define (members ls obj . objs)
(let ((objs (cons obj objs)))
(every identity (map (cut member <> ls) objs))))
(define (members ls obj . objs)
(let ((objs (cons obj objs)))
(every identity (map (compose not not (cut member <> ls)) objs))))
(define (members ls obj . objs)
(let ((objs (cons obj objs)))
(let/cc hop
(fold (lambda (e acc)
(if e
(cons e acc)
(hop #f)))
'()
(map (cut member <> ls) objs)))))
(print (members '(1 2 3 4 5) 3 5))
(print (members '(1 2 3 4 5) 6))
(define (contains ls n . ns)
(let ((ns (cons n ns)))
(filter (lambda (ls)
(apply members ls ns))
ls)))
(contains (combinations (iota 5) 2) 1)
(contains (combinations (iota 10) 4) 6 1)
(contains (combinations (iota 10) 3) 6 1)
(define (combinations-list src count . counts)
(let ((counts (cons count counts)))
(fold (lambda (e acc)
(append acc (combinations src e)))
'()
counts)))
(combinations-list (iota 5) 3 4)
(combinations-list (iota (- 4 (- 3 1)) 3))
(define (make-list min max . opt)
(let-optionals* opt ((step 1))
(iota (- (quotient max step)(- min 1)) min step)))
;; (define (contains-combinations src min max obj . objs)
;; (let ((objs (cons obj objs)))
;; (apply contains (apply combinations-list src (make-list min max)) objs)))
;; (contains-combinations (iota 10 0) 3 4 1 6)
(contains (combinations-list (iota 10) 3 4) 1 6)
(define (disp-combinations ls)
(for-each print
ls))
(disp-combinations (contains (combinations-list (iota 10) 3 4) 1 6))
;; (0 1 6)
;; (1 2 6)
;; (1 3 6)
;; (1 4 6)
;; (1 5 6)
;; (1 6 7)
;; (1 6 8)
;; (1 6 9)
;; (0 1 2 6)
;; (0 1 3 6)
;; (0 1 4 6)
;; (0 1 5 6)
;; (0 1 6 7)
;; (0 1 6 8)
;; (0 1 6 9)
;; (1 2 3 6)
;; (1 2 4 6)
;; (1 2 5 6)
;; (1 2 6 7)
;; (1 2 6 8)
;; (1 2 6 9)
;; (1 3 4 6)
;; (1 3 5 6)
;; (1 3 6 7)
;; (1 3 6 8)
;; (1 3 6 9)
;; (1 4 5 6)
;; (1 4 6 7)
;; (1 4 6 8)
;; (1 4 6 9)
;; (1 5 6 7)
;; (1 5 6 8)
;; (1 5 6 9)
;; (1 6 7 8)
;; (1 6 7 9)
;; (1 6 8 9)

gauche の util.combinations の combinations 手続きのソースがエレガントだったぁ・・・。
ローカルだと
  • /Gauche/share/gauche/0.9/lib/util/combinations.scm

プログラミングGauche

2010/07/07

プログラミング Clojure 読了

先日、遅ればせながら プログラミングClojure を読み始めました。
で、読み終わったわけですが、Clojure カッコイイですね!読了後の感想も上記のものと同様です。
clojureql に興味が湧きました。

ところで

最近、Lisp 本が続きました。
次は何か別の本が読みたいですね。ということで、アドレナリンジャンキー プロジェクトの現在と未来を映す86パターン を読み始めました。

これまた @finalfusion さんに頂いた本です!
これ、めっちゃめちゃおもしろいです。乱暴に言うとソフトウェア開発の「あるある」。

プログラミングClojureアドレナリンジャンキー プロジェクトの現在と未来を映す86パターン


10進数と2進数の変換

もちろん書く必要はないのですが、ラフスケッチ的な。
(define (quotient-down n divider)
(let loop ((n n)(acc '()))
(if (zero? n)
acc
(loop (quotient n divider)(cons n acc)))))
(define (number-list->number lis)
(string->number (string-join (map x->string lis) "")))
(define (dec->bin n)
(number-list->number
(map (lambda (e)
(if (zero? (remainder e 2)) 0 1))
(quotient-down n 2))))
(dec->bin 172)
(number->string 172 2)
(dec->bin 60)
(number->string 60 2)
(dec->bin 128)
(number->string 128 2)
(dec->bin 100)
(number->string 100 2)
(define (number->number-list n)
(map (compose string->number string)
(string->list (number->string n))))
(use srfi-1)
(define (reverse-index-expt ls)
(unfold null?
(lambda (s)
(expt 2 (- (length s) 1)))
cdr ls))
(define (bin->dec n)
(let1 bls (number->number-list n)
(apply + (filter-map (lambda (b e)
(and (= b 1) e))
bls
(reverse-index-expt bls)))))
(bin->dec 10011001)
(bin->dec 1111)
(bin->dec 1101)
(bin->dec 1110)
view raw dec2bin.scm hosted with ❤ by GitHub

プログラミングGauche

2010/07/05

ServersMan@VPS に Gauche と Kahua

一月ほど前に ServersMan@VPS に申し込みました。
CentOS だそうです。取りあえず、Emacs を入れました。CentOS なんて全然触ったことありませんが、Emacs さえ入れてしまえば慣れたインターフェースです。

Emacs をある程度設定後、次に Gauche-0.9 を入れました。

Kahua も入れてみましたが、どうやらちゃんと動いていない様子。。また明日やってみます。


プログラミングGauche

    2010/07/01

    社会とのマッチ

    書いていて思い出しました。同日、同じく @shunsuk さんにこう紹介されました。
    「やりたいことや好きなことが社会とマッチしない人」
    その言い方カッコイイな。実際はただの無職なんですけどね(笑)ホント、ものは言い様ですね。

    「努力」することで「やりたいこと」に近づくことができるなら“向いている”範囲

    ああ、そうだ、最近たまたま読んだこの記事もタイムリーと言えばタイムリーですね。
    もちろん「やりたいこと」と「やれること」が一致すればこれほど幸せなことはないのだけれど、一致しないから多くの人が苦しんでいる。しかも「努力」することで「やりたいこと」に近づくことができるならまだ問題ないのですが(それは“向いている”範囲だと思う)、多くは努力以前の「才能」の問題だったりします。 
    働かなくて済めば、こんなこと考えずに「やりたいこと」だけやれるんでしょうにね。

    やりたいこと

    そういえば、「やりたいこと」ってあったかなー。あまり思いつきません。「やりたくないこと」ならたくさんありますけどね。働きたくない、というのもその一つです。

    「知りたいこと」とか「できるようになりたいこと」ならたくさんあります。最近は珍しく「作ってみたいもの」もあります。それらが「やりたいこと」なんでしょうかね。よくわかりませんが。

    どちらにせよ、それらが収入に結びつく気はしません。

    (Lisp も、少しずつわからないことが分かるようになり、以前よりは少しだけエレガントに書けるようになり、勉強するのも楽しい。というのは、確かに向いてる範囲なのかもしれませんね。まー、収入に関係ないところで楽しんでやってることに向き不向きなんて関係ないわけですが。)

    結局

    で、結局何が言いたいかというと。特に何もないわけです。

    やりたいことだけやって収入を得るなんてことが、ほとんど不可能であることくらい理解していますし、そうしたいわけでもありません。むしろ、何もせずに月50万くらい欲しいです。(つつましいでしょ?)

    できるだけストレスがなくて、気が向いた時にやりたいことができる時間や、ゴロゴロ何もしない時間が欲しいんです。今は無職でいることが選択できるので、そうしているわけです。そうしたいのにそうしない、なんて損じゃないですか。

    ただ、今のところ無職にも期限があるので、どうしようかなーと悩んだりしています。(悩むというほどではないかもしれませんが。)無理にやる気をだしたり、働く気を起こすのも、自分をそのように仕向けるのも、何か違うと思うんですよ。
    @valvallow 元気は出るまで出すな、という私の好きな言葉もありますし。やる気も同様じゃないですかね。
    禿同です。やる気も働く気もそうだと思っています。
    無職でいられなくなった時、どうしようかなー・・・。

    ベーシック・インカム入門 (光文社新書)

    「センスが悪い」と感じることがあれば、それは良い傾向だ

    「音痴の人でも、自分がハズれているとわかる人は治る。」
    「センスが悪いと感じるのであれば、それはセンスがあるということ。」
    正確には忘れましたが、先日 @shunsuk さんに会った時にこういうことを言われました。少し気分が晴れました。

    ありがとうございます!デジザキ先生

    (「Lisp 書いてて全然うまく書けなくて、書けば書くほど自分にはセンスがないなーと思います。」という話の流れから。そう言うほどには書いてないですけどねorz)

    Paul Graham も似たようなことを ...

    Paul Graham の Great Hackers の一文を思い出しました。
    頭がずきんずきんと痛むというのは、それ自体は良いことではないが、 良いことを示すサインではあり得る。例えば、頭を強く打った後で、 意識を取り戻しつつある場合なんかだ。
    富の格差は、生産性の格差を示している可能性がある (一人だけからなる社会では、両者は等しい)。 だとしたら、それ自身はほぼ確実に良いことだと言える。 生産性に格差が無い社会があったとしたら、それは皆がトーマス・エジソンである 社会であるよりは、トーマス・エジソンがいない社会である可能性の方が高い。
    なんか似てるような気がして。

    むしろこっちか。


    ハッカーと画家 コンピュータ時代の創造者たち