「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