Dorai Sitaram さんの "Teach Yourself Scheme in Fixnum Days" を訳しました。著者の承諾を得て 公開しています。 誤訳等がそうとうあるはずですので、気づかれたら是非おしえて下さい。
後半部分はかなり読みずらい訳になっています。これは、私が正確に理解できないまま訳したからです。このあたり、是非、ツッコンでくださいまし。
(2003/08/25 21:07:17 PDT) WiLiKi ページを用意しました。ツッコミなどこちらに書きこんでいただけると嬉しいです。
Gauche Hacking GuideというWiLiKiサイトを作りました。意図は、Gauche のソースコードをハックしたときの記録を公開しようというものです。ソースコードをハックした、あるいは、している、あるいは、しようとしている方がどんどん書き込んでいただけると面白いものができそう。よろしくおねがいします。
……なんか Haskell 版 wiki ができるまでの当座しのぎの WiLiKi サイトが欲しくなってきたんですけど、用意してもらえますか? - shelarcy
以前といたことがあるんですが。。。
(define us-coins '(50 25 10 5 1))
(define uk-coins '(100 50 20 10 5 2 1 0.5))
(define (cc amount coin-values)
(cond ((= amount 0) 1)
((or (< amount 0) (null? coin-values)) 0)
(else
(+ (cc amount
(cdr coin-values))
(cc (- amount
(car coin-values))
coin-values)))))
(cc 100 us-coins) ==> 292
(define (cc2 total arg-list)
(cond ((null? arg-list) total)
((= (caar arg-list) 0)
(cc2 (+ total 1) (cdr arg-list)))
((or (< (caar arg-list) 0) (null? (cdar arg-list)))
(cc2 total (cdr arg-list)))
(else
(cc2 total
`((,(caar arg-list) . ,(cddar arg-list))
(,(- (caar arg-list) (cadar arg-list)) . ,(cdar arg-list))
. ,(cdr arg-list))))))
(cc2 0 `((100 . ,us-coins))) ==> 292
(use srfi-1)
(define us-coins '(1 5 10 25 50))
(define uk-coins '(0.5 2 5 10 20 50 100))
(define (cc3 total-amount coin-values)
(define unit (car coin-values))
(define seq-length (/ total-amount unit))
(define (coin-length coin) (/ (list-ref coin-values coin) unit))
(define (prev-count ls n)
(cond ((null? ls) 0)
((= n 0) (car ls))
(else (prev-count (cdr ls) (- n 1)))))
(define initials (list 1))
(define ones (iota seq-length 1 0))
(define max-coin
(- (length (filter (lambda (c) (<= c total-amount))
(reverse coin-values)))
1))
(define (cc max coin index prevs currs)
(if (> index seq-length)
(if (= max coin)
(car currs)
(cc max (+ coin 1) 1 currs initials))
(let ((count (+ (prev-count prevs (- seq-length index))
(prev-count currs (- (coin-length coin) 1)))))
(cc max coin (+ index 1) prevs (cons count currs)))))
(cc max-coin 1 1 ones initials))
gosh> (cc3 100 us-coins)
292
(define (cc4 amount coin-values)
(let ((coins (apply vector (reverse coin-values)))
(x-size (+ 1 (apply max coin-values)))
(y-size (+ 1 (length coin-values))))
(define v (make-vector (* x-size y-size) 0))
(define (address x y) (+ (modulo x x-size) (* y x-size)))
(define (aref x y) (vector-ref v (address x y)))
(define (aset x y val) (vector-set! v (address x y) val))
(do ((y 1 (+ y 1)))
((= y y-size))
(aset 0 y 1))
(do ((x 1 (+ x 1)))
((> x amount) (aref amount (- y-size 1)))
(do ((y 1 (+ y 1)))
((= y y-size))
(aset x y (+ (aref x (- y 1))
(aref (- x (vector-ref coins (- y 1))) y)))))))
gosh> (cc4 100000 us-coins)
66793412685001
今年もたのしく、Hack,Hack,Hack! -- 2003-01-01
(define b "foo")
(define a b)
とならべるのと
(define a b)
(define b "foo")
とでは、同じ効果であってほしい。
後者はエラーになりますが、これは Scheme の仕様なんだろうか?
(let ((a 1))
(define (f x)
(define b (+ a x))
(define a 5)
(+ a 5))
(f 10))
Gaucheで評価してみたところ、
*** ERROR: number required: #<undef>
Stack Trace:
_______________________________________
gosh>
でした。Gaucheではどのような解釈になっているのでしょう。
(define (add a b) (+ a b))
と定義しておくと
(add 1 2) ==> (+ 1 2) ==> 3
は当然として、
(add 1) ==> (lambda (x) (+ 1 x))
ができると何かと便利なんです。