SICP Exercise 1.3 request for comments

后端 未结 17 1646
耶瑟儿~
耶瑟儿~ 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:22
    (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))))
    
    0 讨论(0)
  • 2020-12-08 21:25

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

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

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

    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.

    0 讨论(0)
提交回复
热议问题