練習:even>odd?

「Scheme手習い」9章は問答についていくのが大変なので、今日はちょっとそこから離れて関数の練習。
東大のScheme演習のページから。

 cf. Scheme演習 第1回

問2
5つの整数を引数として受け取り、そのうち偶数が奇数より多い場合は #t を返し、奇数が偶数より多い場合は #f を返す述語 even>odd? を定義せよ。当然、いろいろな定義の仕方がある。

いろいろな定義の仕方がある、っていうんだから3つくらいは挙げなきゃな。
最初に思いついたのがこれ。

(define even>odd?
  (lambda (a b c d e)
    (> (length (filter even? (list a b c d e))) 2)))

(print (even>odd? 1 2 3 4 5))
(print (even>odd? 2 -3 4 5 -6))
^o^ > gosh even_gt_odd1.scm
#f
#t

次にこれ。上のやつの (length (filter even? ...)) の代わりに再帰関数で偶数の数を数えている。

(define even>odd?
  (lambda (a b c d e)
    (define evens
      (lambda (lis)
        (cond
          ((null? lis) 0)
          ((even? (car lis)) (+ 1 (evens (cdr lis))))
          (else (evens (cdr lis))))))
    (> (evens (list a b c d e)) 2)))

(print (even>odd? 1 2 3 4 5))
(print (even>odd? 2 -3 4 5 -6))
^o^ > gosh even_gt_odd2.scm
#f
#t

3つ目、前に作った evens-and-odds を使う。

(define even>odd?
  (lambda (a b c d e)
    (define evens-and-odds
      (lambda (lis co)
        (cond
          ((null? lis) (co '() '()))
          ((even? (car lis))
          (evens-and-odds (cdr lis) (lambda (e o) (co (cons (car lis) e) o))))
          (else
            (evens-and-odds (cdr lis) (lambda (e o) (co e (cons (car lis) o))))))))
    (define friend
      (lambda (e o)
        (> (length e) (length o))))
    (evens-and-odds (list a b c d e) friend)))

(print (even>odd? 1 2 3 4 5))
(print (even>odd? 2 -3 4 5 -6))
^o^ > gosh even_gt_odd3.scm
#f
#t

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください