- 書名
- プログラミングGauche
- 著者
- Kahuaプロジェクト
- 監修
- 川合 史郎
- 出版
- オライリー
- 価格
- 3200円
- ISBN
- 978-4-87311-348-7
本日読了。これは素晴しい本ですね。Schemeを勉強したいなら、最初に読む べき本と言って良いでしょう。全体を通してかなり実用的・実践的に書かれて いると思います。2008年に出た本なので、最新版のGauche/Kahuaに合わせた内 容で第2版とか出ないですかねえ。出たらすぐ買うのだけど。
死せる詩人のWeblogです。読書記録とDungeons and Dragons Role Playing Gameのセッション記録が主です。リンクは御自由にどうぞ。
本日読了。これは素晴しい本ですね。Schemeを勉強したいなら、最初に読む べき本と言って良いでしょう。全体を通してかなり実用的・実践的に書かれて いると思います。2008年に出た本なので、最新版のGauche/Kahuaに合わせた内 容で第2版とか出ないですかねえ。出たらすぐ買うのだけど。
アイスウィンドデイルを舞台にしたキャンペーンです。DMはつかださん。参加者は以下の通り。全員2レベルです。
12時に開始して19時終了。戦闘遭遇は5回だったかな? ゾンビが多過ぎる……。まだ僕のキャラは何とか制御役の役目を果たせているかな。
本日読了。
映画に合わせて再読。読んだのは1998年だから実に16年ぶり? 瀬田訳も読もうかな。
表題のキャンペーンです。DMは羽生さん。レベルは全員13です。参加者は以下の通り。
指揮役のプレイヤがお休みなのでNPCが同行しました。通称お獅子仮面。からくりさんと僕のPCは前回戦死しているので、2人とも新キャラ投入です。
勉強がてらProject Eulerをやっています。まず1から8まで。使用している言語/処理系はScheme/Gaucheです。
;; Project Euler
;; http://odz.sakura.ne.jp/projecteuler/
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 指定した自然数 n で割り切れるかを判定する関数を創る関数
;; 戻り値 1引数の関数
;; 引数 1つの自然数 (n)
(define (mod-n n)
(if (zero? n)
(error "Natural number required, but got zero.")
(lambda (x)
(if (zero? (modulo x n))
#t
#f))))
;; 指定した2つの自然数からなる集合の環集合を返す
;; 戻り値 自然数のリスト
;; 引数 自然数からなる2つのリスト
(define (union l1 l2)
(cond
((null? l1) l2)
((null? l2) l1)
(else
(lset-union eq? l1 l2))))
;; 引数nが3で割り切れるか判定する
;; 戻り値 真偽値
;; 引数 自然数 n
(define (mod3? n)
((mod-n 3) n))
;; 引数nが5で割り切れるか判定する
;; 戻り値 真偽値
;; 引数 自然数 n
(define (mod5? n)
((mod-n 5) n))
(mod5? 10)
(mod5? 11)
;; プロジェクトオイラーの問題1のメイン
;; 与えられた自然数からなるリストの内、3の倍数と5の倍数の総和を求める
;; 戻り値 1つの自然数(3の倍数と5の倍数の総和)
;; 引数 自然数からなる1つのリスト l
(define (pj-euler1 l)
(cond
((null? l) 0)
(else
(fold + 0
(union
(filter mod3? l)
(filter mod5? l))))))
(pj-euler1 (iota 1000))
(pj-euler1 (iota 10))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; n項までのフィボナッチ数を求める
;; 戻り値 自然数(フィボナッチ数)
;; 引数 自然数 n
(define (fibo n)
(cond
((zero? n) 1)
((zero? (- n 1)) 2)
(else
(+ (fibo (- n 1)) (fibo (- n 2))))))
(time (fibo 100))
;; CPS版フィボナッチ数
(define (fibo/cps n cont)
(cond
((zero? n) (cont 1))
((zero? (- n 1)) (cont 2))
(else
(fibo/cps (- n 1)
(lambda (y) (fibo/cps (- n 2)
(lambda (z) (cont (+ y z)))))))))
(time (fibo/cps 100 (lambda (x) x)))
;; tati
(define (fib-i n)
(if (or (zero? n) (= n 1))
(values 1 1)
(receive (cur prev)
(fib-i (- n 1))
(values (+ cur prev) cur))))
;;動的計画法版フィボナッチ数
(define (fibo/dyna n)
(let loop ((a 1) (b 2) (i n))
(let1 c (+ a b)
(if (<= i 2)
c
(loop b c (- i 1))))))
;; n以下のフィボナッチ数の内偶数の物を返す
(time (let loop ((n 0) (ret 0))
(let1 f (fibo/dyna n)
(if (< f 4000000)
(if (even? f)
(loop (+ n 1) (+ ret f))
(loop (+ n 1) ret)))
ret)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use srfi-1)
;; 与えられた自然数 n 以下の素数のリストを返す
;; 戻り値 n 以下の素数のリスト
;; 引数 n 閾値となる自然数
(define (primes n)
(let loop ((l (unfold (cut > <> n) values (cut + <> 2) 3))
(prime-list '(2)))
(let1 m (car l)
(if (> (expt m 2) n)
(append (reverse prime-list) l)
(loop (remove (lambda (x) (zero? (modulo x m))) l) (cons m prime-list))))))
(define val 600851475143)
(define plist (reverse (primes (truncate (sqrt val)))))
(
(define (pj-euler3 n ls)
(cond
((zero? n) 0)
((null? ls) (error "list required, but got ()"))
(else
(if (zero? (modulo n (car ls)))
(car ls)
(pj-euler3 n (cdr ls))))))
(time (pj-euler3 val (reverse (primes (truncate (sqrt val))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use srfi-13)
(* 999 999)
(string-reverse (number->string 123))
;; 与えられた数が回文数か判定する関数
(define (palindromic? n)
(cond
((zero? n) #t)
((< n 10) #t)
(else
(let* ((stringed-n (number->string n))
(reversed-n (string-reverse stringed-n)))
(string=? stringed-n reversed-n)))))
(define pal
;; 入力した自然数の平方根が整数になるか調べる関数
(define (sq-int? n)
(integer? (sqrt n)))
(time (take-right (filter sq-int? (filter palindromic? (iota (- (* 999 999) (* 100 100)) (* 100 100)))) 1))
(sqrt 10201)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define max-v (lcm 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20))
(define (lcm? n)
(if (zero? n) #f
(and
(zero? (modulo n 20))
(zero? (modulo n 19))
(zero? (modulo n 18))
(zero? (modulo n 17))
(zero? (modulo n 16))
(zero? (modulo n 15))
(zero? (modulo n 14))
(zero? (modulo n 13))
(zero? (modulo n 12))
(zero? (modulo n 11)))))
(time (length (iota max-v -20)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(use srfi-1)
(define n 100)
(define (pj-euler6 n)
(- (expt (apply + (iota n 1)) 2)
(apply + (map (lambda (x) (* x x)) (iota n 1)))))
(time (pj-euler6 n))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define idx 10001)
(time (list-ref (primes (* 50 idx)) idx))
(use util.stream)
(use srfi-42)
(define (primes-shiro)
(stream-filter (lambda (k)
(not (any?-ec (: j 3 (sqrt k) 2) (zero? (modulo k j)))))
(stream-cons 2 (stream-iota -1 3 2))))
(time (stream->list (stream-take (primes-shiro) idx)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Problem 8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define quant 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450)
(define (integer->list i)
(letrec ((i->rl (lambda (j)
(cons (modulo j 10)
(if (< j 10)
'()
(i->rl (quotient j 10)))))))
(reverse (i->rl i))))
(define (1st l)
(car l))
(define (2nd l)
(car (cdr l)))
(define (3rd l)
(car (cdr (cdr l))))
(define (4th l)
(car (cdr (cdr (cdr l)))))
(define (5th l)
(car (cdr (cdr (cdr (cdr l))))))
(define l (integer->list 7316717653133062491922511967442657474))
(define (pj-euler8 l)
(cond
((> 5 (length l)) '())
(else
(cons (* (1st l) (2nd l) (3rd l) (4th l) (5th l)) (pj-euler8 (cdr l))))))
(time (apply max (pj-euler8 (integer->list quant))))
Scheme手習いの続編です。章立ても、手習いが1章から10章となっていて本書は11章から始まります。手習いの「はじめに」には「この本の内容を2回以下で理解出来ると思わない事」という注意がありました。本書では「5回以下で理解出来ると思わない事」というより難しい事を示唆する注意になっています。
僕は手習いは2回読んで、Yコンビネータ以外は何とか理解できたかなという程度でした。修行も2回読んだのですが、やはり手習いに比べると難解な部分が多く理解出来ていない割合が多いですね。継続は概念そのものは理解は出来るものの、活用方法がよく解りませんでした。継続については苦戦したので
この当たりを合わせて読んで理解の助けにしました。(Shiroさんのなんでも継続は続きがあるみたいなので是非読みたいですね)
Schemeの入門書として前書と合わせてお勧めされる事の多い本だと思うのですが、決して親切な本では無いなというのが正直な印象です。理解に苦しむ所が出てきても、その理解出来ない状況を突破する為の助けが全然無いので、淡泊な本文を必死に読むのですが本当に難しい部分はやっぱり読んでも分からないわけです。なんかedのエラーメッセージの様な文章だなと。