subset?とeqset?

※追記あり

subset?

s1、s2 のセット2つを引数にとり、s1 が s2 のサブセット(部分集合)のとき #t を返す関数。

(use mymodule)

(define subset?
  (lambda (s1 s2)
    (cond
      ((null? s1) #t)
      ((member? (car s1) s2) (subset? (cdr s1) s2))
      (else #f))))

(print (subset? '(5 chicken wings)
                '(5 hamburgers 2 pieces fried chicken and light duckling wings)))
(print (subset? '(4 pounds of horseradish)
                '(four pounds chicken and 5 ounces horseradish)))
^o^ > gosh -I. subset.scm
#t
#f

eqset?

2つのセット s1 と s2 が等しければ #t を返す関数。お互いがお互いのサブセットなら、等しいといえる。これをコードにするとこうなる。

(use mymodule)

(define subset?
  (lambda (s1 s2)
    (cond
      ((null? s1) #t)
      ((member? (car s1) s2) (subset? (cdr s1) s2))
      (else #f))))

(define eqset?
  (lambda (s1 s2)
    (cond
      ((subset? s1 s2) (subset? s2 s1))
      (else #f))))

(print (eqset? '(6 large chickens with wings)
               '(6 chickens with large wings)))
^o^ > gosh -I. eqset.scm
#t

and を使うともっと短くなる。eqset? だけ示すと:

(define eqset?
  (lambda (s1 s2)
    (cond
      (else (and (subset? s1 s2) (subset? s2 s1))))))

こうなると cond はいらなくなるので、もっと短くなる。

(define eqset?
  (lambda (s1 s2)
    (and (subset? s1 s2) (subset? s2 s1))))

3行になった。

追記

subset? も and を使うと短くなる。

(use mymodule)

(define subset?
  (lambda (s1 s2)
    (cond
      ((null? s1) #t)
      (else (and (member? (car s1) s2) (subset? (cdr s1) s2))))))

(print (subset? '(5 chicken wings)
                '(5 hamburgers 2 pieces fried chicken and light duckling wings)))
(print (subset? '(4 pounds of horseradish)
                '(four pounds chicken and 5 ounces horseradish)))
^o^ > gosh -I. subset2.scm
#t
#f

コメントを残す

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

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