24

私は 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))))))
4

17 に答える 17

34

本のその時点で提示された概念のみを使用すると、次のようになります。

(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))))
于 2009-07-21T21:18:43.463 に答える
14

bigと呼ばれmaxます。そこにある場合は、標準ライブラリの機能を使用します。

私のアプローチは違います。多くのテストを行うのではなく、単純に 3 つのすべての平方を足してから、最小のものの平方を引きます。

(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 1およびSRFI 26も必要です。

(define (exercise1.3 . args)
  (apply + (map! (cut expt <> 2) (take! (sort! args >) 2))))
于 2008-10-02T10:27:56.193 に答える
6

テキストのその時点までに導入された概念のみを使用すると、かなり重要だと思いますが、別の解決策があります。

(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)))))
于 2009-07-05T15:52:45.180 に答える
5
(define (f a b c) 
  (if (= a (min a b c)) 
      (+ (* b b) (* c c)) 
      (f b c a)))
于 2012-01-30T14:08:06.917 に答える
4

私には問題ないように見えますが、特に改善したい点はありますか?

次のようなことができます:

(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) は、任意の数の引数を処理するように簡単に変換できます。

于 2008-10-02T10:26:13.467 に答える
4
(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))))
于 2012-01-30T09:28:24.650 に答える
3

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)))))
于 2009-12-10T14:11:49.740 に答える
2

リストを並べ替えて、並べ替えられたリストの1番目と2番目の要素の2乗を追加することもできます。

(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))))
于 2008-10-02T10:44:23.860 に答える
2

これを行う別の方法を次に示します。

#!/usr/bin/env mzscheme
#言語スキーム/ロード

(モジュール ex-1.3 スキーム/ベース
  (定義 (ex-1.3 abc)
    (let* ((square (ラムダ (x) (* xx)))
           (p (ラムダ (abc) (+ (平方 a) (平方 (if (> bc) bc))))))
      (if (> ab) (pabc) (pbac))))

  (スキーム/契約が必要)
  (提供/契約 [ex-1.3 (-> number? number? number? number?)]))

;; テスト
(モジュール ex-1.3/テスト スキーム/ベース
  (必要 (惑星 "test.ss" ("回路図" "schemeunit.plt" 2))
           (惑星 "text-ui.ss" ("回路図" "schemeunit.plt" 2)))
  ('ex-1.3 が必要)

  (テスト/テキスト-ui
   (テストスイート
    「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? (ラムダ () (ex-1.3 2+1i 0 0)))
    (test-equal? "all equal" (ex-1.3 3 3 3) 18))))

('ex-1.3/test が必要)

例:

$ mzscheme ex-1.3.ss
6 回の成功 0 回の失敗 0 回のエラー 6 回のテストの実行
0
于 2009-03-04T21:37:47.247 に答える
0

私は試してみました:

(define (procedure a b c)
    (let ((y (sort (list a b c) >)) (square (lambda (x) (* x x))))
        (+ (square (first y)) (square(second y)))))
于 2010-01-04T04:35:26.947 に答える
0

これが最小かつ最も効率的な方法だと思います:

(define (square-sum-larger a b c)
 (+ 
  (square (max a b))
  (square (max (min a b) c))))
于 2015-02-22T23:55:44.877 に答える
0
;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))))
于 2011-01-12T02:43:43.233 に答える