SICP 练习 1.3 征求意见

发布于 2024-07-06 05:00:27 字数 283 浏览 9 评论 0原文

我正在尝试通过 SICP 学习方案。 练习 1.3 如下:定义一个过程,以三个数字作为参数,并返回两个较大数字的平方和。 请评论我如何改进我的解决方案。

(define (big x y)
    (if (> x y) x y))

(define (p a b c)
    (cond ((> a b) (+ (square a) (square (big b c))))
          (else (+ (square b) (square (big a c))))))

I'm trying to learn scheme via SICP. Exercise 1.3 reads as follow: Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers. Please comment on how I can improve my solution.

(define (big x y)
    (if (> x y) x y))

(define (p a b c)
    (cond ((> a b) (+ (square a) (square (big b c))))
          (else (+ (square b) (square (big a c))))))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

会傲 2024-07-13 05:00:27

我使用以下代码完成了此操作,该代码使用内置的 minmaxsquare 过程。 它们非常简单,只需使用到目前为止文本中介绍的内容即可实现。

(define (sum-of-highest-squares x y z)
   (+ (square (max x y))
      (square (max (min x y) z))))

I did it with the following code, which uses the built-in min, max, and square procedures. They're simple enough to implement using only what's been introduced in the text up to that point.

(define (sum-of-highest-squares x y z)
   (+ (square (max x y))
      (square (max (min x y) z))))
心病无药医 2024-07-13 05:00:27

big 称为 max。 使用标准库功能。

我的方法不同。 我没有进行大量测试,而是简单地将所有三个的平方相加,然后减去最小的一个的平方。

(define (exercise1.3 a b c)
  (let ((smallest (min a b c))
        (square (lambda (x) (* x x))))
    (+ (square a) (square b) (square c) (- (square smallest)))))

当然,您是否喜欢这种方法,或者一堆 if 测试,取决于您。


使用 SRFI 95 的替代实现:

(define (exercise1.3 . args)
  (let ((sorted (sort! args >))
        (square (lambda (x) (* x x))))
    (+ (square (car sorted)) (square (cadr sorted)))))

如上所述,但作为单行代码(感谢 synx @ freenode #scheme); 还需要 SRFI 1SRFI 26

(define (exercise1.3 . args)
  (apply + (map! (cut expt <> 2) (take! (sort! args >) 2))))

big is called max. Use standard library functionality when it's there.

My approach is different. Rather than lots of tests, I simply add the squares of all three, then subtract the square of the smallest one.

(define (exercise1.3 a b c)
  (let ((smallest (min a b c))
        (square (lambda (x) (* x x))))
    (+ (square a) (square b) (square c) (- (square smallest)))))

Whether you prefer this approach, or a bunch of if tests, is up to you, of course.


Alternative implementation using SRFI 95:

(define (exercise1.3 . args)
  (let ((sorted (sort! args >))
        (square (lambda (x) (* x x))))
    (+ (square (car sorted)) (square (cadr sorted)))))

As above, but as a one-liner (thanks synx @ freenode #scheme); also requires SRFI 1 and SRFI 26:

(define (exercise1.3 . args)
  (apply + (map! (cut expt <> 2) (take! (sort! args >) 2))))
じее 2024-07-13 05:00:27

仅使用本书中该部分提出的概念,我会这样做:

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

(define (sum-of-squares x y) (+ (square x) (square y)))

(define (min x y) (if (< x y) x y))

(define (max x y) (if (> x y) x y))

(define (sum-squares-2-biggest x y z)
  (sum-of-squares (max x y) (max z (min x y))))

Using only the concepts presented at that point of the book, I would do it:

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

(define (sum-of-squares x y) (+ (square x) (square y)))

(define (min x y) (if (< x y) x y))

(define (max x y) (if (> x y) x y))

(define (sum-squares-2-biggest x y z)
  (sum-of-squares (max x y) (max z (min x y))))
夏花。依旧 2024-07-13 05:00:27
;exercise 1.3
(define (sum-square-of-max a b c)
  (+ (if (> a b) (* a a) (* b b))
     (if (> b c) (* b b) (* c c))))
;exercise 1.3
(define (sum-square-of-max a b c)
  (+ (if (> a b) (* a a) (* b b))
     (if (> b c) (* b b) (* c c))))
早茶月光 2024-07-13 05:00:27

像这样的事怎么办?

(define (p a b c)
  (if (> a b)
      (if (> b c)
          (+ (square a) (square b))
          (+ (square a) (square c)))
      (if (> a c)
          (+ (square a) (square b))
          (+ (square b) (square c)))))

What about something like this?

(define (p a b c)
  (if (> a b)
      (if (> b c)
          (+ (square a) (square b))
          (+ (square a) (square c)))
      (if (> a c)
          (+ (square a) (square b))
          (+ (square b) (square c)))))
柏拉图鍀咏恒 2024-07-13 05:00:27

仅使用文本中介绍的概念,我认为这相当重要,这是一个不同的解决方案:

(define (smallest-of-three a b c)
        (if (< a b)
            (if (< a c) a c)
            (if (< b c) b c)))

(define (square a)
        (* a a))

(define (sum-of-squares-largest a b c) 
        (+ (square a)
           (square b)
           (square c)
           (- (square (smallest-of-three a b c)))))

Using only the concepts introduced up to that point of the text, which I think is rather important, here is a different solution:

(define (smallest-of-three a b c)
        (if (< a b)
            (if (< a c) a c)
            (if (< b c) b c)))

(define (square a)
        (* a a))

(define (sum-of-squares-largest a b c) 
        (+ (square a)
           (square b)
           (square c)
           (- (square (smallest-of-three a b c)))))
情归归情 2024-07-13 05:00:27
(define (f a b c) 
  (if (= a (min a b c)) 
      (+ (* b b) (* c c)) 
      (f b c a)))
(define (f a b c) 
  (if (= a (min a b c)) 
      (+ (* b b) (* c c)) 
      (f b c a)))
不必了 2024-07-13 05:00:27
(define (sum-sqr x y)
(+ (square x) (square y)))

(define (sum-squares-2-of-3 x y z)
    (cond ((and (<= x y) (<= x z)) (sum-sqr y z))
             ((and (<= y x) (<= y z)) (sum-sqr x z))
             ((and (<= z x) (<= z y)) (sum-sqr x y))))
(define (sum-sqr x y)
(+ (square x) (square y)))

(define (sum-squares-2-of-3 x y z)
    (cond ((and (<= x y) (<= x z)) (sum-sqr y z))
             ((and (<= y x) (<= y z)) (sum-sqr x z))
             ((and (<= z x) (<= z y)) (sum-sqr x y))))
和影子一齐双人舞 2024-07-13 05:00:27

我认为这是最小且最有效的方法:

(define (square-sum-larger a b c)
 (+ 
  (square (max a b))
  (square (max (min a b) c))))

I think this is the smallest and most efficient way:

(define (square-sum-larger a b c)
 (+ 
  (square (max a b))
  (square (max (min a b) c))))
掐死时间 2024-07-13 05:00:27

以下是我想出的解决方案。 我发现当代码被分解为小函数时,更容易推理出解决方案。

            ; Exercise 1.3
(define (sum-square-largest a b c)
  (+ (square (greatest a b))
     (square (greatest (least a b) c))))

(define (greatest a b)
  (cond (( > a b) a)
    (( < a b) b)))

(define (least a b)
  (cond ((> a b) b)
    ((< a b) a)))

(define (square a)
  (* a a))

Below is the solution that I came up with. I find it easier to reason about a solution when the code is decomposed into small functions.

            ; Exercise 1.3
(define (sum-square-largest a b c)
  (+ (square (greatest a b))
     (square (greatest (least a b) c))))

(define (greatest a b)
  (cond (( > a b) a)
    (( < a b) b)))

(define (least a b)
  (cond ((> a b) b)
    ((< a b) a)))

(define (square a)
  (* a a))
挖个坑埋了你 2024-07-13 05:00:27

很高兴看到其他人如何解决这个问题。 这是我的解决方案:

(define (isGreater? x y z)
(if (and (> x z) (> y z))
(+ (square x) (square y))
0))

(define (sumLarger x y z)
(if (= (isGreater? x y z) 0)   
(sumLarger y z x)
(isGreater? x y z)))

我通过迭代解决了它,但我更喜欢 ashitaka 和 (+ (square (max xy)) (square (max (min xy) z))) 解决方案,因为在我的版本中,如果 z 是最小的数,是更大的吗? 被调用两次,造成不必要的缓慢和迂回的过程。

It's nice to see how other people have solved this problem. This was my solution:

(define (isGreater? x y z)
(if (and (> x z) (> y z))
(+ (square x) (square y))
0))

(define (sumLarger x y z)
(if (= (isGreater? x y z) 0)   
(sumLarger y z x)
(isGreater? x y z)))

I solved it by iteration, but I like ashitaka's and the (+ (square (max x y)) (square (max (min x y) z))) solutions better, since in my version, if z is the smallest number, isGreater? is called twice, creating an unnecessarily slow and circuitous procedure.

呆萌少年 2024-07-13 05:00:27

这是另一种方法:

#!/usr/bin/env mzscheme
#lang scheme/load

(module ex-1.3 scheme/base
  (define (ex-1.3 a b c)
    (let* ((square (lambda (x) (* x x)))
           (p (lambda (a b c) (+ (square a) (square (if (> b c) b c))))))
      (if (> a b) (p a b c) (p b a c))))

  (require scheme/contract)
  (provide/contract [ex-1.3 (-> number? number? number? number?)]))

;; tests
(module ex-1.3/test scheme/base
  (require (planet "test.ss" ("schematics" "schemeunit.plt" 2))
           (planet "text-ui.ss" ("schematics" "schemeunit.plt" 2)))
  (require 'ex-1.3)

  (test/text-ui
   (test-suite
    "ex-1.3"
    (test-equal? "1 2 3" (ex-1.3 1 2 3) 13)
    (test-equal? "2 1 3" (ex-1.3 2 1 3) 13)
    (test-equal? "2 1. 3.5" (ex-1.3 2 1. 3.5) 16.25)
    (test-equal? "-2 -10. 3.5" (ex-1.3 -2 -10. 3.5) 16.25)
    (test-exn "2+1i 0 0" exn:fail:contract? (lambda () (ex-1.3 2+1i 0 0)))
    (test-equal? "all equal" (ex-1.3 3 3 3) 18))))

(require 'ex-1.3/test)

示例:

$ mzscheme ex-1.3.ss
6 success(es) 0 failure(s) 0 error(s) 6 test(s) run
0

Here's yet another way to do it:

#!/usr/bin/env mzscheme
#lang scheme/load

(module ex-1.3 scheme/base
  (define (ex-1.3 a b c)
    (let* ((square (lambda (x) (* x x)))
           (p (lambda (a b c) (+ (square a) (square (if (> b c) b c))))))
      (if (> a b) (p a b c) (p b a c))))

  (require scheme/contract)
  (provide/contract [ex-1.3 (-> number? number? number? number?)]))

;; tests
(module ex-1.3/test scheme/base
  (require (planet "test.ss" ("schematics" "schemeunit.plt" 2))
           (planet "text-ui.ss" ("schematics" "schemeunit.plt" 2)))
  (require 'ex-1.3)

  (test/text-ui
   (test-suite
    "ex-1.3"
    (test-equal? "1 2 3" (ex-1.3 1 2 3) 13)
    (test-equal? "2 1 3" (ex-1.3 2 1 3) 13)
    (test-equal? "2 1. 3.5" (ex-1.3 2 1. 3.5) 16.25)
    (test-equal? "-2 -10. 3.5" (ex-1.3 -2 -10. 3.5) 16.25)
    (test-exn "2+1i 0 0" exn:fail:contract? (lambda () (ex-1.3 2+1i 0 0)))
    (test-equal? "all equal" (ex-1.3 3 3 3) 18))))

(require 'ex-1.3/test)

Example:

$ mzscheme ex-1.3.ss
6 success(es) 0 failure(s) 0 error(s) 6 test(s) run
0
苹果你个爱泡泡 2024-07-13 05:00:27

您还可以对列表进行排序并添加排序列表的第一个和第二个元素的平方:

(require (lib "list.ss")) ;; I use PLT Scheme

(define (exercise-1-3 a b c)
  (let* [(sorted-list (sort (list a b c) >))
         (x (first sorted-list))
         (y (second sorted-list))]
    (+ (* x x) (* y y))))

You can also sort the list and add the squares of the first and second element of the sorted list:

(require (lib "list.ss")) ;; I use PLT Scheme

(define (exercise-1-3 a b c)
  (let* [(sorted-list (sort (list a b c) >))
         (x (first sorted-list))
         (y (second sorted-list))]
    (+ (* x x) (* y y))))
吝吻 2024-07-13 05:00:27

在 Scott Hoffman 和一些 irc 的帮助下,我纠正了我的错误代码,如下

(define (p a b c)
    (cond ((> a b)
        (cond ((> b c)
            (+ (square a) (square b)))
            (else (+ (square a) (square c)))))
        (else
            (cond ((> a c)
                (+ (square b) (square a))))
             (+ (square b) (square c)))))

With Scott Hoffman's and some irc help I corrected my faulty code, here it is

(define (p a b c)
    (cond ((> a b)
        (cond ((> b c)
            (+ (square a) (square b)))
            (else (+ (square a) (square c)))))
        (else
            (cond ((> a c)
                (+ (square b) (square a))))
             (+ (square b) (square c)))))
千年*琉璃梦 2024-07-13 05:00:27

我已经尝试过了:

(define (procedure a b c)
    (let ((y (sort (list a b c) >)) (square (lambda (x) (* x x))))
        (+ (square (first y)) (square(second y)))))

I've had a go:

(define (procedure a b c)
    (let ((y (sort (list a b c) >)) (square (lambda (x) (* x x))))
        (+ (square (first y)) (square(second y)))))
物价感观 2024-07-13 05:00:27
(define (sum a b) (+ a b))
(define (square a) (* a a))
(define (greater a b ) 
  ( if (< a b) b a))
(define (smaller a b ) 
  ( if (< a b) a b))
(define (sumOfSquare a b)
    (sum (square a) (square b)))
(define (sumOfSquareOfGreaterNumbers a b c)
  (sumOfSquare (greater a b) (greater (smaller a b) c)))
(define (sum a b) (+ a b))
(define (square a) (* a a))
(define (greater a b ) 
  ( if (< a b) b a))
(define (smaller a b ) 
  ( if (< a b) a b))
(define (sumOfSquare a b)
    (sum (square a) (square b)))
(define (sumOfSquareOfGreaterNumbers a b c)
  (sumOfSquare (greater a b) (greater (smaller a b) c)))
如歌彻婉言 2024-07-13 05:00:27

我觉得还不错,您有什么具体需要改进的地方吗?

你可以这样做:

(define (max2 . l)
  (lambda ()
    (let ((a (apply max l)))
      (values a (apply max (remv a l))))))

(define (q a b c)
  (call-with-values (max2 a b c)
    (lambda (a b)
      (+ (* a a) (* b b)))))

(define (skip-min . l)
  (lambda ()
    (apply values (remv (apply min l) l))))

(define (p a b c)
  (call-with-values (skip-min a b c)
    (lambda (a b)
      (+ (* a a) (* b b)))))

这个 (proc p) 可以很容易地转换来处理任意数量的参数。

Looks ok to me, is there anything specific you want to improve on?

You could do something like:

(define (max2 . l)
  (lambda ()
    (let ((a (apply max l)))
      (values a (apply max (remv a l))))))

(define (q a b c)
  (call-with-values (max2 a b c)
    (lambda (a b)
      (+ (* a a) (* b b)))))

(define (skip-min . l)
  (lambda ()
    (apply values (remv (apply min l) l))))

(define (p a b c)
  (call-with-values (skip-min a b c)
    (lambda (a b)
      (+ (* a a) (* b b)))))

And this (proc p) can be easily converted to handle any number of arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文