Frage

Ich versuche Schema über SICP zu lernen. Aufgabe 1.3 lautet wie folgt: eine Prozedur definieren, die drei Zahlen als Argumente und gibt die Summe der Quadrate der beiden größeren Zahlen nimmt. Bitte kommentieren, wie ich meine Lösung zu verbessern.

(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))))))
War es hilfreich?

Lösung

Sieht ok für mich ist es etwas Bestimmtes Sie wollen verbessern?

Sie etwas tun könnten, wie:

(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)))))

Und das (proc p) kann leicht eine beliebige Anzahl von Argumenten zu handhaben umgewandelt werden.

Andere Tipps

Mit nur die an dieser Stelle des Buches vorgestellten Konzepte, würde ich es tun:

(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))))

big wird max genannt. Verwenden Sie Standard-Bibliothek Funktionalität, wenn es da ist.

Mein Ansatz ist anders. Anstatt viele Tests, habe ich einfach die Quadrate aller drei addieren, subtrahieren Sie dann das Quadrat der kleinste.

(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)))))

Ob Sie diesen Ansatz bevorzugen, oder eine Reihe von if Tests ist bis zu Ihnen, natürlich.


Alternative Implementierung mit SRFI 95 :

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

Wie oben, aber als Einzeiler (dank synx @ freenode #scheme); auch erfordert SRFI 1 und SRFI 26 :

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

Ich habe es mit dem folgenden Code, der die integrierten in min verwendet, max und square Verfahren. Sie sind einfach genug, nur mit zu implementieren, was zu diesem Zeitpunkt in dem Text nach oben eingeführt worden ist.

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

Was ist so etwas wie das?

(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)))))

nur die Konzepte verwenden zu diesem Punkt des Textes eingeführt up, was ich denke, ist ziemlich wichtig , hier ist eine andere Lösung:

(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)))))
(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 (f a b c) 
  (if (= a (min a b c)) 
      (+ (* b b) (* c c)) 
      (f b c a)))

Mit Scott Hoffman und einig irc Hilfe, die ich meinen fehlerhaften Code korrigiert, hier ist es

(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)))))

Sie können auch die Liste sortieren und die Quadrate des ersten und zweiten Elements der sortierten Liste hinzufügen:

(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))))

Hier ist noch eine weitere Möglichkeit, es zu tun:

#!/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)

Beispiel:

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

Es ist schön zu sehen, wie andere Leute dieses Problem gelöst haben. Dies war meine Lösung:

(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)))

Ich löste es durch Iteration, aber Ich mag ashitaka ist und die (+ (Quadrat (max xy)) (Quadrat (max (min xy) z))) Lösungen besser, da in meiner Version, wenn z die kleinste Zahl ist , ist besser? zweimal aufgerufen wird, ein unnötig langsam und umständlichen Verfahren zu schaffen.

(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)))

Ich habe ein zu gehen habe:

(define (procedure a b c)
    (let ((y (sort (list a b c) >)) (square (lambda (x) (* x x))))
        (+ (square (first y)) (square(second y)))))
;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))))

Ich denke, das ist die kleinste und effizienteste Art und Weise:

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

Im Folgenden finden Sie die Lösung, die ich mit aufkommen. Ich finde es einfacher, eine Lösung Grund, wenn der Code in kleine Funktionen zerlegt wird.

            ; 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))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top