An open API service indexing awesome lists of open source software.

https://github.com/ramsayleung/sicp_solution

We toast the Lisp programmer who pens his thoughts within nests of parentheses.
https://github.com/ramsayleung/sicp_solution

design lisp programming racket scheme sicp

Last synced: 22 days ago
JSON representation

We toast the Lisp programmer who pens his thoughts within nests of parentheses.

Awesome Lists containing this project

README

          

#+LATEX_CLASS: ramsay-org-article
#+LATEX_CLASS_OPTIONS: [oneside,A4paper,12pt]
#+AUTHOR: Ramsay Leung
#+EMAIL: ramsayleung@gmail.com
#+DATE: 2022-11-07 一 21:07
* Structure and Interpretation of Computer Programs
《计算机程序的构造和解释》题解,使用标准Racket 实现(开发环境是Emacs)

#+begin_quote
If art interprets our dreams, the computer executes them in the guise of programs!

如果说艺术解释了我们的梦想,那么计算机就是以程序的名义执行着它们
#+end_quote

#+begin_quote
We toast the Lisp programmer who pens his thoughts within nests of parentheses.
#+end_quote

向以括号为画笔的Lisp程序员举杯,干杯!
* 安装依赖
#+begin_src shell
raco pkg install --auto --batch # 类似 JavaScript 的 npm install
#+end_src
* 习题
习题完成情况:
- 章节一: 43/46
- 章节二: 88/97
- 章节三: 72/82
- 章节四: TODO
- 章节五: TODO
* 运行
运行所有的习题
#+begin_src shell
raco test -t .
#+end_src

运行指定的习题:
#+begin_src shell
raco test chapter1/exercise1-10.scm
#+end_src
* 笔记
** chapter2
*** 图形语言
racket的 =sicp= package 包含了一个画图工具,可以画出类似书中的效果

#+begin_src scheme
#lang racket
(require sicp-pict)
(define (flipped-pairs painter)
(let ((painter2 (beside painter (flip-vert painter))))
(below painter2 painter2)))

(define (right-split painter n)
(if (= n 0)
painter
(let ((smaller (right-split painter (- n 1))))
(beside painter (below smaller smaller)))))

(define (up-split painter n)
(if (= n 0)
painter
(let ((smaller (up-split painter (- n 1))))
(below painter (beside smaller smaller)))))

(define (corner-split painter n)
(if (= n 0)
painter
(let ((up (up-split painter (- n 1)))
(right (right-split painter (- n 1))))
(let ((top-left (beside up up))
(bottom-right (below right right))
(corner (corner-split painter (- n 1))))
(beside (below painter top-left)
(below bottom-right corner))))))

(define (square-limit painter n)
(let ((quarter (corner-split painter n)))
(let ((half (beside (flip-horiz quarter) quarter)))
(below (flip-vert half) half))))

(paint (square-limit einstein 6))
#+end_src

在 =DrRacket= 的运行效果(只能在DrRacket 运行,在终端无法展示图片):

[[file:img/chapter2/square-limit-einstein.png]]

配合 [[file:chapter2/exercise2-49.org][wave的实现]],画出来的效果:

[[file:img/chapter2/wave-square-limit.png]]
** chapter3
*** 蒙特卡罗模拟步骤来计算 π
3.1 赋值与局部变量, 155 页
#+begin_quote
举例来说,6/π^2 是随机选取的两个整数之间没有公因子(也就是说,它们的最大公因子是1)的概率。我们可以利用这一事实做出π的近似值。
#+end_quote

完全读不懂这段话,没理解是怎么可以算出π的近似值的。

查阅完资料都知道:

随机选取两个正整数,它们互质(即最大公约数GCD为1)的概率是 $\frac{6}{\pi^2}$ , 所谓的 互质指两个数没有公共因子(如8和15互质,但8和12不互质,因为公约数为4)。

而这一结论是源自数论中关于 *互质数的密度* 的研究,与黎曼ζ函数相关(难怪我看不懂了)。

而用蒙特卡罗模拟步骤来计算 ${\pi}$:

随机实验:重复多次随机选取两个整数,检查它们的GCD是否为1。

例如:
- (3, 5) → GCD=1(计数+1)
- (4, 6) → GCD=2(不计数)

统计概率:

若总实验次数为 N,其中 k 次GCD=1,则互质概率的估计值为 $\frac{k}{N}$

关联π:

根据数论结论 $\frac{k}{N} \approx \frac{6}{\pi^2}$,解得 $\pi \approx \sqrt{\frac{6N}{k}}$。

当直接计算π困难时,可通过概率实验间接逼近。

这里利用了数论中的概率规律,将π与随机事件联系起来。(高数对于我来说已是雪泥鸿爪,更遑论数论的知识了)

#+begin_src racket
#lang racket

(define (estimate-pi trials)
(sqrt (/ 6 (monte-carlo trials cesaro-test))))

(define (cesaro-test)
(= (gcd (rand) (rand)) 1))

(define (monte-carlo trials experiment)
(define (iter trials-remaining trial-passed)
(cond ((= trials-remaining 0)
(/ trials-passed trials))
((experiment)
(iter (- trials-remaining 1) (+ trials-passed 1)))
(else
(iter (- trials-remaining 1) trials-passed))))
(iter trials 0))
#+end_src

这里的蒙特卡罗实现真的是优雅

而基于流的实现更是优美:

#+begin_src scheme
(define (monte-carlo experiment-stream passed failed)
(define (next passed failed)
(cons-stream
(/ passed (+ passed failed))
(monte-carlo
(stream-cdr experiment-stream)
passed
failed)))
(if (stream-car experiment-stream)
(next (+ passed 1) failed)
(next passed (+ failed 1))))
#+end_src
** 翻译错误
第2版,238页,模块化,对象和状态,中文翻译是
#+begin_quote
练习3.70
b) 所有正正数序对 (i,j) 的流,其中要求 i<=j, 而且这里的i或者j可以被2,3或者5整除
#+end_quote

原文是:
#+begin_quote
the stream of all pairs of positive integers ( i , j ) with i ≤ j , where neither i nor j is divisible by 2, 3, or 5,
#+end_quote

https://sarabander.github.io/sicp/html/3_002e5.xhtml#g_t3_002e5

i和j不可以被2,3,5整除,翻译成了可以被2,3或者5整除,意思完全相反,真的是服了。
** 排版错误
第2版,240页,模块化,对象和状态

练习3.74 输入信号流和过零点信号流完全没有对齐