「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