いわた
http://quasiquote.org/log2/ にて細々とやってます。
とりあえず足跡ぺたり。
つくった/っているもの
Gauche-lazy-ffi
Gaucheから共有ライブラリを簡単に呼出す試み。Chickenのlazy-ffiにならいました。
Gauche:FFIにあるようにScmForeignPointerが使えるようになれば、 もうちょっとスマートなものになるのかな?
subtract
Erlangのlists:subtract/2('--'演算子)みたいなのは無いのかなあ。探すのもめんどうだなあ。 ということで、 とりあえずベタベタなコードを書いてみた。
(define (subtract h . t)
(define (delete-first x li)
(let loop ((li li)
(buf '()))
(if (null? li)
(reverse buf)
(if (equal? (car li) x)
(append (reverse buf) (cdr li))
(loop (cdr li) (cons (car li) buf))))))
(define (subtract2 x y)
(let loop ((x x)
(y y))
(if (null? y)
x
(loop (delete-first (car y) x) (cdr y)))))
(let loop ((t t)
(buf h))
(if (null? t)
buf
(loop (cdr t) (subtract2 buf (car t))))))
使用例。こんなのが、
perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].
% test
lists:foreach(fun (X) -> io:fwrite("~s ", [X]) end, perms:perms("test")).
こんなのに。
(use srfi-42)
(define (perms l)
(if (null? l)
'(())
(list-ec (: h l) (: t (perms (subtract l (list h)))) (cons h t))))
;; test
(map list->string (perms (string->list "test")))
- 要素に重複がないのなら SRFI-1 の lset-difference とかはどうでしょう。上の定義も SRFI-1 を使って:
(use srfi-1) (define (delete-first x ys) (receive (h t) (break (cut equal? x <>) ys) (if (null? t) h (append! h (cdr t))))) (define (subtract xs . yss) (fold delete-first xs (concatenate! yss)))- おおう。短いですね。lset-*は便利そうです。めもめも。 --いわた