第4夜:わけのわからない数と大根
数の悪魔*1を題材にプログラミングしてます。今回は大根です。本では計算機で出していました。
じゃ、このトリックの名前、ぜひおぼえておこう。「後ろにホップする」じゃなくて、「大根を抜く」っていうんだ。ほら、地面から根を引き抜くみたいに - 数の悪魔
(define (radish v) (define (separate2fig n l) (if (< n 1) l (separate2fig (quotient n 100) (cons (remainder n 100) l)))) (define (max-number v d) (define (max-number-iter n m) (if (>= v m) (values n (- v m)) (max-number-iter (- n 1) (- m (* d 10) n n -1)))) (max-number-iter 9 (+ (* d 90) 81))) (define (radish-iter l d a r) (if (null? l) (cons a r) (receive (na nr) (max-number (+ (* r 100) (car l)) d) (radish-iter (cdr l) (+ (* d 10) na na) (+ (* a 10) na) nr)))) (radish-iter (separate2fig v '()) 0 0 0) ) (define (main args) (print (radish 5929)) 0)
筆算式の開平法で書いてみました。自然数の(小さくて一番近い)平方根を求め、その値と余りをconsセルで返します。結果はこちら。
(77 . 0)
もう少し何か無いかなと探していた途中、2進法を使ったスマートな処理を見つけました(SICPを翻訳された和田英一氏でしょうか)。パラメトロン計算機: 開平法
http://listlibrary.net/ruby-math/2003/08/00vP80du/にあったNewton法も興味深いです。
ルートを開こうは開平法の参考にさせていただきました。
センスは磨けるうちに磨けと思った日でした。
最後に、ウルフラム・アルファさんに聞いてみよう:http://www.wolframalpha.com/input/?i=sqrt%285929%29