sicp每日一题[2.41]

Exercise 2.41

Write a procedure to find all ordered triples of distinct positive integers i, j, and k less than or equal to a given integer n that sum to a given integer s.


这道题有一点难度,主要是要使用两次 flatmap 函数,仿照2元组的构造方式构造出3元组来,然后再筛选出和为s的。

; 获取不大于正整数n的1/3的最大整数
(define (one-third-factor n)
  (cond ((= (remainder n 3) 0) (/ n 3))
        ((= (remainder n 3) 1) (/ (- n 1) 3))
        (else (/ (- n 2) 3))))

(define (ordered-triple-sum n s)
  (if (or (< s 6) (> n (- s 3)))     ; n是不同的3个正整数之和,所以s至少是6,且n至少比s小3
      nil
      (filter (lambda (seq) (= (accumulate + 0 seq) s))
              (flatmap (lambda (i)
                         (flatmap (lambda (j)
                                    (map (lambda (k) (list i j k))
                                         (enumerate-interval (+ j 1) n)))    ; 第三个数比第二个大
                                    (enumerate-interval (+ i 1) (- n 1))))   ; 第二个数比第一个大
                       (enumerate-interval 1 (one-third-factor n))))))       ; 需要的是有序3元组,所以第一个数最大也比n/3小


(ordered-triple-sum 15 20)

; 执行结果
'((1 4 15) (1 5 14) (1 6 13) (1 7 12) (1 8 11) (1 9 10) (2 3 15) (2 4 14) (2 5 13) (2 6 12) (2 7 11) (2 8 10) (3 4 13) (3 5 12) (3 6 11) (3 7 10) (3 8 9) (4 5 11) (4 6 10) (4 7 9) (5 6 9) (5 7 8))
posted @ 2024-10-11 08:23  再思即可  阅读(3)  评论(0编辑  收藏  举报