Gaucheでも集合関係の関数を書いてみた

ここでRを使って書いたやつをGaucheを使って書いてみました。こっちのほうが素直だな。再帰使ってリスト操作とかはまあいいんだけど、文字列で出力するための部分が泥だけど、まあいいか。てか、組み込み関数に冪集合を生成する関数があるとかすごすぎるんだけど。

;;;集合族とかを書き出す関数
(define (write-set set)
  (if (list? set)
      (if (any (lambda (x) (list? x)) set)
	  (string-append "{" (string-join (map (lambda (x) (write-set x)) set)",")"}")
	  (string-append "{" ((lambda (x sep) (string-join (map x->string x) sep)) set ",") "}"))
      (string-append "{" (x->string set) "}")))

(write-set 1)
(write-set '(() 1 2 (1 2)))
(write-set '(1 2 3 (4 5 6)))

(use util.combinations)

;;;combinationsを使って冪集合を生成、出力する
(let ((lis '(1 2 3)))
  (write-set 
   (cons ()
	 (reverse 
	  (fold (lambda (x init) (fold (lambda (y init) (cons y init)) init x)) 
		() 
		(map 
		 (lambda (x) (combinations lis x))
		 (make-natural-number-list 1 (length lis))))))))

;;;組み込みの冪集合を生成する関数
(write-set (power-set '(1 2 3)))

;;直積
(cartesian-product '((1 2) (3 4)))

(string-append "{" (string-join (map (lambda (x) (
		  (lambda (x) (string-append "(" (x->string (car x)) "," (x->string (car (cdr x))) ")" )) x)) 
     (cartesian-product '((1 2) (3 4)))) ",") "}")

;;;直積関数。ドット対でやっている。cadrとかに注意
(map (lambda (x) (* (car x) (cdr x))) 
     (map (lambda (x) (cons (car x) (cadr x)))
	  (cartesian-product '((1 2) (3 4)))))

;;;ref http://d.hatena.ne.jp/rui314/20070416/p1
(define (x str n)
  (with-output-to-string
   (lambda ()
     (dotimes (i n)
       (display str)))))
(map (lambda (m) (x (car m) (cdr m))) 
     (map (lambda (x) (cons (car x) (cadr x)))
	  (cartesian-product '(("syou6162" "Hash") (2 3)))))