<jupyter_start><jupyter_text>SICP 习题 （2.40）解题总结：unique-pairs SICP习题2.40要求我们实现一个叫unique-pairs的函数，用于生成小于等于n的所有整数组合。然后题目要求我们使用(unique-pairs)函数去简化书中提到的(prime-sum-pairs)函数 首先我们需要面对的是如何生成小于等于某一数的所有数字的序列，书中提到了(enumerate-interval)函数，函数定义如下：<jupyter_code>(define (enumerate-interval low high) 
   (if (> low high) 
       '()
       (cons low (enumerate-interval (+ low 1) high))))<jupyter_output><empty_output><jupyter_text>像下面这样的调用就可以生成0到10的序列<jupyter_code>(enumerate-interval 0 10)<jupyter_output><empty_output><jupyter_text>接着可以通过以下的(map)函数生成i和比i小的数的所有序对：<jupyter_code>(define i 10)
(map
  (lambda (j) 
    (list i j))
  (enumerate-interval 1 (- i 1)))<jupyter_output><empty_output><jupyter_text>在外面再套一层map函数就可以生成比n小的所有序对了：<jupyter_code>(define n 10)
(map (lambda (i) 
	 (map
	  (lambda (j) 
	    (list i j))
	  (enumerate-interval 1 (- i 1))))
       (enumerate-interval 1 n))<jupyter_output><empty_output><jupyter_text>这个差不多已经是题目要求的结果了，就是格式不太对。题目要求我们把生成的序对放在一个序列里，我们这里生成的是嵌套的序列。通过accumulate把他们串起来就好了：<jupyter_code>(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
	  (accumulate op initial (cdr sequence)))))


(define (unique-pairs n)
  (accumulate append '() (map (lambda (i) 
	 (map
	  (lambda (j) 
	    (list i j))
	  (enumerate-interval 1 (- i 1))))
       (enumerate-interval 1 n))))
(unique-pairs 10)<jupyter_output><empty_output><jupyter_text>然后就是去简化(prime-sum-pairs)函数， 先看看检查一个序对和是不是质数的方法：先拷贝之前的检查质数的prime?函数：<jupyter_code>(define (smallest-divisor n)
  (find-divisor n 2))

(define (find-divisor n test-divisor)
  (cond ((> (square test-divisor) n) n)
	((divides? test-divisor n) test-divisor)
	(else (find-divisor n (+ test-divisor 1)))))

(define (divides? a b)
  (= (remainder b a) 0))

(define (square x)
  (* x x))

(define (prime? n)
  (= n (smallest-divisor n)))<jupyter_output><empty_output><jupyter_text>检查序对和是不是质数的方法定义如下：<jupyter_code>(define (prime-sum? pair)
  (prime? (+ (car pair) (cadr pair))))<jupyter_output><empty_output><jupyter_text>通过map调用prime-sum?就可以计算哪组序对满足条件了：<jupyter_code>(map prime-sum? (unique-pairs 10))<jupyter_output><empty_output><jupyter_text>接着想用系统的filter函数来直接过滤出来，后来发现 Calysto Scheme的filter实现有点奇怪，老是报错，于是就自己实现了一遍：<jupyter_code>(define (filter function input-list)
  (if (pair? input-list)
      (if (function (car input-list))
          (cons (car input-list) (filter function (cdr input-list)))
          (filter function (cdr input-list)))
      ()
      ))<jupyter_output><empty_output><jupyter_text>效果如下：<jupyter_code>(filter  prime-sum? (unique-pairs n))<jupyter_output><empty_output><jupyter_text>最后就是按(prime-sum-paris)的要求把序对的和也算出来放进序列里，定义成函数如下：<jupyter_code>(define (prime-sum-pairs n)
  (map (lambda (pair-sum)
	 (append pair-sum (list (+ (car pair-sum) (cadr pair-sum)))))

   (filter  (lambda (pair) 
	      (prime-sum? pair)) (unique-pairs n))))<jupyter_output><empty_output><jupyter_text>执行效果如下：<jupyter_code>(prime-sum-pairs 10)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15099427030670712, 'fraction_numerical': 0.011459386585776879, 'mean_word_length': 5.918414918414919, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '86046', 'license': 'MIT', 'n_tokens_mistral': 1464, 'n_tokens_neox': 1462, 'n_words': 188, 'path': 'cn/sicp-2-40.ipynb', 'repo_name': 'DamonDeng/sicp_exercise', 'size': '2967'}