
どうみても図形言語です。
にしても今年は一年中なんだか余裕がなかった。来年はなんとかする。
compactNumberList :: [Int] -> [[Int]]
compactNumberList = snd . partition ([]==) . tail . snd . mapAccumL collect [-1] . (++[-1])
where collect xx@(x:xs) y | y - x == 1 = (y:xx, [])
| xs ==[] = ([y], [x])
| otherwise = ([y], [last xx, head xx])
Main >putStr "abcdef\n"putStr の出力は IO () 型なので、結果として印字された「abcdef」は文字列ではない。じゃあ、IO () 型の出力はどこにいったんだろう? Show クラスのインスタンスがないということ? でも、だとしたらGHCがエラーを出力するんじゃなかったっけ?
abcdef
vacant :: IO () -> String
vacant o = "munashii"
Main >vacant $ putStr "subarashii\n"どうして「subarashii」が印字されないん?
"munashii"
gosh> (define (vacant o) "munashii")これが本物の副作用ということなのか!
vacant
gosh> (vacant (print "subarashii"))
subarashii
"munashii"
*Main> intMap (*2) 12345こういうintMapをどうやって作っていくか。(以下、とりあえず正の整数の場合だけを考える。)
[2,4,6,8,10]
*Main> foldr (+) 0 $ intMap id 123456789
45
intMap p n | n < 10 = [p n]ちなみにこれはコンパイルに通らない。floor とか (/) とかは、そのままでは Int型に対して使えないので。コンパイルするには最後の front を次のようにする必要がある。
| otherwise = reverse (p last : reverse front)
where
last = mod n 10
front = intMap p (floor (n/10))
front = intMap p $ fromEnum $ floor $ toEnum n/10(追記)整数の割り算がありました。front = intMap p (div n 10) でOK。(ここまで追記)
intMap :: (Int -> a) -> Int -> [a]自分が求めている型が分かったので、これをキーワードにして Hoogle で検索してみる。結果はいっぱい出るけど、その先頭には iterate という関数がひっかかるはずだ。リンクをクリックすると、GHCのドキュメントの iterate の項目にジャンプする。その説明によれば、iterate はこんな関数らしい。
iterate :: (a -> a) -> a -> [a]見るからに intMap の定義に使えそうだ。f として先ほどの定義の front に相当するものを与えてやれば、iterate f 1234 -> [1234, 123, 12, 1, 0, ...] といった具合にリストが得られるので、あとは各要素から mod 10 で 1の位を抜き出せばいい。
iterate f x returns an infinite list of repeated applications of f to x:
iterate f x == [x, f x, f (f x), ...]
intMap :: (Int -> a) -> Int -> [a]再帰がなくなり、標準関数をごにょごにょするだけで求める関数を作ることができた。
intMap p n = map (p . lastDigit) $ reverse $ takeWhile (> 0) $ iterate f n
where
f m = div m 10
lastDigit m = mod m 10
nabeatsu = [p i | i <- [1..]]
where has3 n = or $ intMap (== 3) n
p i | has3 i || mod i 3 == 0 = "aho"
| otherwise = intMap intToDigit i
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
# Wireless LAN
auto eth1
iface eth1 inet dhcp
wireless-essid ******
wireless-key **************************
xi ≧ 0 かつ Σ xi = 1 となるような乱数ようするに、数直線の0~1の間に均等な確率で弾を9発撃ち込むという行為を繰り返したとき、毎回の隣り合う各弾の間隔は同じような幅になると期待していいか、ということでしょう?
x1, ..., x10 がほしい。
そこで、区間 [0,1] 上の独立な一様乱数を 9 個作ってソートし、
得られた r1 ≦ … ≦ r9 を使って、
xi = ri - ri-1 としてみた。
(ただし r0 = 0, r10 = 1)
これは平等か?
たとえば x1 の分布と x5 の分布は等しいか?
(数式に頼らずうまく説明せよ)
0 ri-1 ri 1たとえば撃ち込む弾の数が毎回1発だったら、
-+--- …… ---+------+--- …… ---+-
`--xi--'
0 r1 1いかにも x1 と x2 が同じ分布になりそうだ。撃ち込むのが9発でも同じことだよね。というわけで、この方法で平等な乱数を10個作ることができる。
-+-------+---------+-
`--x1--'`---x2---'
P(xi = λ) = rii-1 × (1 - ri - λ)9-iいくつか具体的に計算してみると、x1 がλになる確率は以下のとおり。
P(x1 = λ) = r10 × (1 - r1 - λ)8同様に x2 がλになる確率は、
= (1 - r1 - λ)8
P(x2 = λ) = r21 × (1 - r2 - λ)7おや、なんだか P(x1 = λ) = P(x2 = λ) とも言えなそうだ。そこでおおざっぱに評価してみる。
= r2 (1 - r2 - λ)7
P(x2 = λ) / P(x1 = λ)最後の式は、r2 = 1/2 なら 1 になる。しかも、もし r1 = r2 だったら、途中の不等号が統合になるので、P(x1 = λ) = P(x2 = λ) になる。撃ち込む弾の数が毎回1発のケースは、この場合に相当していたのか。
= r2 (1 - r2 - λ)7 / (1 - r1 - λ)8
= (r2 / (1 - r1 - λ)) × ((1 - r2 - λ)7 / (1 - r1 - λ)7)
≦ (r2 / (1 - r1 - λ)) ← r1 ≦ r2 なので
= r2 / (1 - r2) ← λ = r2 - r1
(use srfi-1)にしても、「10分で中級、30分で初級」というshiroさんによるレベル設定が絶妙すぎると思う。
;; [name [tree ...]] -> [(tree-head . name)]
(define (child-parent ls)
(if (null? (cdr ls))
'()
(append-map
(lambda (l)
(cons (cons (car l) (car ls))
(child-parent l)))
(cdr ls))))
リストのcarと、リストのcdrたちのcarとを、逆順にconsして集めるのねこの場合は再帰も単純なので一発で書いちゃうけど、もうちょっと複雑な場合はテスト用のトリビアルな入力データをREPLで評価しながら関数に仕上げていく。あるいは、一発で関数を書いちゃってからテスト用のトリビアルな入力データを使ってREPLで評価し、意図していない結果であれば修正して(再帰の終了条件を修正する場合が多い)、これを繰り返して関数に仕上げていく。だいたいいつもこんな感じ。必要なら最後にCtrl-c tしてテストを作りますよ。gca.el最高!
↓
とりあえずcdrたちに対してmap-appendか
↓
そしてconsで再帰すればいいから、必然的に終了判定はnull?
↓
"(if (null? (cdr ls))"あたりから書き始める
es0> (eq? (quote a) (quote a)) #tt es1> (eq? (cons (quote a)) (cons (quote a))) #ff
es20> (define Y(この「Y」という名前は再帰に使うための名前じゃない。)
(lambda (le)
((lambda (f) (f f))
(lambda (f) (le (lambda (x) ((f f) x)))))))
es24> ((Y (lambda (len)なんかちゃんと動いてる!
(lambda (l)
(if (null? l)
0
(+ 1 (len (cdr l)))))))
(quote (beans beans we need jelly beans)))
6.000000
es0> (define null?
(lambda (ls)
(if (eq? (quote ()) ls)
#t #f)))
k16@miffy:~/myproj/es$ ./esソースはこれ。メモリリークしまくっている状態だけど。あとで時間がとれたら感想とか書く。
es0> (define fact
(lambda (n)
(if (eq? n 1)
1
(* n (fact (- n 1))))))
fact
es1> fact
#<closure ( n )>
es2> (fact 10)
3628800.000000
es3>
es0> (* 1 2)はやくSchemeになりたいよう。のこり必要なもの。
2.000000
es1> (+ 42 23)
65.000000
es2> (cons answer (cons is (cons 42 ())))
(answer . (is . (42.000000 . null)))
es3> (cdr (cons mouse (cons dolphin human)))
(dolphin . human)
es4>
S式 : アトムおなじみの (apple orange pizza) みたいなリストは、実際には null で終わっているドットペアの簡略表記にすぎない。この例であれば、その本当のすがたは (apple . (orange . (pizza . null))) という入れ子になったドットペア。そういえば null って本当は何のことなんだろう? いつも()って書いてるから、空っぽなリストぐらいにしかみなしてなかったけど、よく考えるとよくわからん。
| ( S式 . S式 )
;
%{ここで Sexp はS式をあらわす構造体で、直感的にAtomとPairの共用体として定義した。
#define YYSTYPE Sexp*
%}
%token ATOM
%token DOT
%token LPAREN
%token RPAREN
%%
list: { prompt(lineno); }
| list '\n'
| list sexp '\n' { prints($2); prompt(lineno); }
;
sexp: ATOM
| LPAREN sexp DOT sexp RPAREN { $$ = mk_oblist($2, $4); }
;
typedef struct Sexp {Atomは浮動小数点数か文字列とする。Pairはもちろんcarとcdrで構成される。
short type;
union {
struct Atom *atom;
struct Pair *pair;
} u;
} Sexp;
typedef struct Atom{そしてこの Pair を作る関数が mk_oblist。
short type;
union {
double num; /* type = 0 */
char *sym; /* type = 1 */
} u;
} Atom;
typedef struct Pair {
struct Sexp *car;
struct Sexp *cdr;
} Pair;
$ ./es
es0> (((((42)))))
(((((42.000000 . null) . null) . null) . null) . null)
es1> (the answer is 42)
(the . (answer . (is . (42.000000 . null))))
es2> (() ())
(null . (null . null))
<page>ちょっとタイトルにワクでも付けたいなと思ったら、こんなふうに適当なタグでくるんでみて、
<p0>Gaucheで本を作る</p0>
<p3 vskip="4zh" hskip="12zw">株式会社オーム社開発部</p3>
<p3 hskip="12zw">鹿野 桂一郎</p3>
<p3 hskip="12zw">kshikano@ohmsha.co.jp</p3>
</page>
<page>rules.scmにこんな2行を足すだけで(LaTeXの\fboxはワク付の箱でテキストを囲むコマンド)、
<p0><box>Gaucheで本を作る</box></p0>
<p3 vskip="4zh" hskip="12zw">株式会社オーム社開発部</p3>
<p3 hskip="12zw">鹿野 桂一郎</p3>
<p3 hskip="12zw">kshikano@ohmsha.co.jp</p3>
</page>
(define-tag boxこんなふうになる。
(make-latex-cmd 'fbox))