#f 在 repl.it 内输出方案结果

#f output for scheme result inside repl.it

我正在做一些来自 Structure and Interpretation of Computer Programs

的问题

我的案例在 repl.it 解释器中输出 #f 作为有效结果。我正在申请 (and (not (max a b c)) (not (min a b c))) 以获得中间值。

我已经尝试重新排列中间函数的值。最大和最小函数工作正常。

(define (max a b c) 
(cond 
  ((and(>= a b)(>= a c)) a)
  ((and(>= b a)(>= b c)) b)
  ((and(>= c a)(>= c b)) c)
))

(define (min a b c) 
(cond 
  ((and(<= a b)(<= a c)) a)
  ((and(<= b a)(<= b c)) b)
  ((and(<= c a)(<= c b)) c)
))

(define (mid a b c)
(and 
  (not (max a b c)) 
  (not (min a b c))
))

(mid 10 8 6)

repl.it 方案解释​​器中的输出是:

=> #f

我预计会出现某种错误或数字值错误,但此代码 return 是绿色的 #f 所以我假设它意味着错误?我如何使用条件表达式将此代码修复为 return a mid?

我意识到我从 max AND min 传递了一个 NOT,这就是为什么它每次都评估为 false 的原因,因为这些表达式总是有一个错误的结果。我继续使用比较来获得正确的解决方案,并调整了例外情况,将中间值设为一个值,如果它不小于最大值或大于最小值,则重复三次或两次。唯一令人不安的是,我必须基本上表达所有有效条件以隔离中间数,并且不能将中间数明确定义为不是最大数也不是最小数。话虽如此,必须有更好的方法来减少这些功能并消除大量比较...

(define (mid a b c) 
(cond 
  ((and(< a (max a b c))(> a (min a b c))) a)
  ((and(< b (max a b c))(> b (min a b c))) b)
  ((and(< c (max a b c))(> c (min a b c))) c)
  (else (cond
    ((= (min a b c) (max a b c)) a)
    ((= a b) a)
    ((= a c) a)
    ((= b c) b)
))
))

我认为值得考虑需要进行多少次测试才能计算这些东西:要在任何排序运算符下计算三个元素的极值,您只需进行不超过 3 次比较:

(define (extremum/3 ordered? a b c)
  ;; find the extremum of three elements under ordered?
  (cond ((and (ordered? a b) (ordered? a c)) a)
        ((ordered? b c) b)
        (else c)))

有了这个通用函数,您现在可以轻松定义 max/3 和 min/3:

(define (max/3 a b c)
  (extremum/3 >= a b c))

(define (min/3 a b c)
  (extremum/3 <= a b c))

计算三个元素的中点也只需要三个测试:

(define (mid/3 a b c)
  (if (>= a b)
      (if (>= a c)
          ;; a is greatest, so we need to pick b or c
          (if (>= b c) b c)
          ;; a is the mid point
          a)
      (if (>= a c)
          ;; a is the mid point
          a
          ;; a is the minimum, pick b or c
          (if (>= c b) b c))))

考虑需要进行多少次比较才能找到 n 项的中点,这很有趣。