Skip to content

Commit e111e8b

Browse files
committed
Add implementation of exercise 3-82
1 parent 5642fa6 commit e111e8b

File tree

4 files changed

+77
-11
lines changed

4 files changed

+77
-11
lines changed

README.org

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
习题完成情况:
2626
- 章节一: 43/46
2727
- 章节二: 88/97
28-
- 章节三: 71/82
28+
- 章节三: 72/82
2929
- 章节四: TODO
3030
- 章节五: TODO
3131
* 运行
@@ -144,6 +144,22 @@
144144
#+end_src
145145

146146
这里的蒙特卡罗实现真的是优雅
147+
148+
而基于流的实现更是优美:
149+
150+
#+begin_src scheme
151+
(define (monte-carlo experiment-stream passed failed)
152+
(define (next passed failed)
153+
(cons-stream
154+
(/ passed (+ passed failed))
155+
(monte-carlo
156+
(stream-cdr experiment-stream)
157+
passed
158+
failed)))
159+
(if (stream-car experiment-stream)
160+
(next (+ passed 1) failed)
161+
(next passed (+ failed 1))))
162+
#+end_src
147163
** 翻译错误
148164
第2版,238页,模块化,对象和状态,中文翻译是
149165
#+begin_quote

chapter3/exercise3-5.rkt

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,20 @@
2020
(abs (- y1 y2)))))
2121
(* (exact->inexact rectangle-area) (monte-carlo trials experiment))))
2222

23+
;; 以(5,7)为圆心,半径为3的圆,以(2,4)和(8,10)作为对角点的矩形包围着
24+
;; 这个圆, 计算这个圆的面积(假设 π未知),结果应该接近 28.274
25+
(define (square x)
26+
(* x x))
27+
28+
(define (in-circle? x y)
29+
(<= (+ (square (- x 5)) (square (- y 7)))
30+
(square 3)))
31+
(provide square in-circle?)
32+
2333
(module+ test
2434
(require rackunit)
2535
(require rackunit/text-ui)
2636

27-
;; 以(5,7)为圆心,半径为3的圆,以(2,4)和(8,10)作为对角点的矩形包围着
28-
;; 这个圆, 计算这个圆的面积(假设 π未知),结果应该接近 28.274
29-
(define (square x)
30-
(* x x))
31-
32-
(define (in-circle? x y)
33-
(<= (+ (square (- x 5)) (square (- y 7)))
34-
(square 3)))
35-
3637
(define (estimate-area-close? trials tolerance)
3738
(let ((area-estimate (estimate-integral in-circle? 2 8 4 10 trials)))
3839
(< (abs (- area-estimate 28.27431)) tolerance)))

chapter3/exercise3-82.rkt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#lang racket
2+
(require "stream.rkt")
3+
(require "infinite-stream.rkt")
4+
(require "exercise3-50.rkt")
5+
(require "exercise3-5.rkt")
6+
7+
(define (map-successive-pairs f s)
8+
(if (stream-null? s)
9+
the-empty-stream
10+
(let ((head (stream-car s)))
11+
(if (pair? head)
12+
(cons-stream
13+
(f (car head) (cadr head))
14+
(map-successive-pairs f (stream-cdr s)))
15+
(error "uknown parameter type " head)))))
16+
17+
(define (integral-experience-stream predicate x1 x2 y1 y2)
18+
(map-successive-pairs predicate
19+
(map-stream list
20+
(random-range-stream x1 x2)
21+
(random-range-stream y1 y2))))
22+
23+
(define (estimate-integral-stream predicate x1 x2 y1 y2)
24+
(let ((rectangle-area (* (abs (- x1 x2))
25+
(abs (- y1 y2)))))
26+
(stream-map (lambda (p) (* (exact->inexact rectangle-area) p))
27+
(monte-carlo (integral-experience-stream predicate x1 x2 y1 y2) 0 0)))
28+
)
29+
30+
(module+ test
31+
(require rackunit)
32+
;; 以(5,7)为圆心,半径为3的圆,以(2,4)和(8,10)作为对角点的矩形包围着
33+
;; 这个圆, 计算这个圆的面积(假设 π未知),结果应该接近 28.274
34+
(define circle-area 28.27431)
35+
(define (estimate-area-close? area-estimate tolerance)
36+
(< (abs (- area-estimate circle-area)) tolerance))
37+
38+
(test-case "Test for estimate-integral-stream"
39+
(define estimated-area-stream (estimate-integral-stream in-circle? 2 8 4 10))
40+
(check-true (estimate-area-close? (stream-ref estimated-area-stream 10000) 2.0))
41+
(check-true (estimate-area-close? (stream-ref estimated-area-stream 100000) 1.5))
42+
(check-true (estimate-area-close? (stream-ref estimated-area-stream 1000000) 1.4))
43+
)
44+
)

chapter3/infinite-stream.rkt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
(cons-stream random-init
5858
(stream-map rand-update random-number-stream)))
5959

60+
(define (random-range-stream low high)
61+
(cons-stream (random-in-range low high)
62+
(random-range-stream low high))
63+
)
64+
6065
(define (map-successive-pairs f s)
6166
(cons-stream
6267
(f (stream-car s) (stream-car (stream-cdr s)))
@@ -84,7 +89,7 @@
8489
(stream-filter (lambda (p) (not (= p 0)))
8590
(monte-carlo cesaro-stream 0 0))))
8691

87-
(provide add-streams scale-stream ones integers fibs interleave pairs integral monte-carlo)
92+
(provide add-streams scale-stream ones integers fibs interleave pairs integral monte-carlo random-range-stream map-successive-pairs)
8893

8994
(module+ test
9095
(require rackunit)

0 commit comments

Comments
 (0)