SICP Exercise 1.3 request for comments

后端 未结 17 1647
耶瑟儿~
耶瑟儿~ 2020-12-08 21:06

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 la

相关标签:
17条回答
  • 2020-12-08 21:39

    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))))
    
    0 讨论(0)
  • 2020-12-08 21:39

    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)))))
    
    0 讨论(0)
  • 2020-12-08 21:41
    (define (f a b c) 
      (if (= a (min a b c)) 
          (+ (* b b) (* c c)) 
          (f b c a)))
    
    0 讨论(0)
  • 2020-12-08 21:46

    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.

    0 讨论(0)
  • 2020-12-08 21:49

    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)))))
    
    0 讨论(0)
提交回复
热议问题