mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 21:59:17 +02:00
325 lines
9.8 KiB
Scheme
325 lines
9.8 KiB
Scheme
|
|
(define (vector-empty? vec)
|
|
(zero? (uvector-length vec)))
|
|
|
|
(define (vector= . vecs)
|
|
(let lp1 ((ls vecs))
|
|
(or (null? ls)
|
|
(null? (cdr ls))
|
|
(let* ((v1 (car ls))
|
|
(v2 (cadr ls))
|
|
(len (uvector-length v1)))
|
|
(and (= len (uvector-length v2))
|
|
(let lp2 ((i 0))
|
|
(or (>= i len)
|
|
(and (= (uvector-ref v1 i)
|
|
(uvector-ref v2 i))
|
|
(lp2 (+ i 1)))))
|
|
(lp1 (cdr ls)))))))
|
|
|
|
(define (reverse-list->uvector ls)
|
|
(list->uvector (reverse ls)))
|
|
|
|
(define (uvector-unfold f len seed)
|
|
(let ((res (make-uvector len)))
|
|
(let lp ((i 0) (seed seed))
|
|
(if (>= i len)
|
|
res
|
|
(call-with-values (lambda () (f i seed))
|
|
(lambda (x seed)
|
|
(uvector-set! res i x)
|
|
(lp (+ i 1) seed)))))))
|
|
|
|
(define (uvector-unfold-right f len seed)
|
|
(let ((res (make-uvector len)))
|
|
(let lp ((i (- len 1)) (seed seed))
|
|
(if (< i 0)
|
|
res
|
|
(call-with-values (lambda () (f i seed))
|
|
(lambda (x seed)
|
|
(uvector-set! res i x)
|
|
(lp (- i 1) seed)))))))
|
|
|
|
(define (vector-copy vec . o)
|
|
(let ((start (if (pair? o) (car o) 0))
|
|
(end (if (and (pair? o) (pair? (cdr o)))
|
|
(cadr o)
|
|
(uvector-length vec))))
|
|
(uvector-unfold (lambda (i _) (values (uvector-ref vec (+ i start)) _))
|
|
(- end start)
|
|
#f)))
|
|
|
|
(define (vector-reverse-copy vec . o)
|
|
(let ((start (if (pair? o) (car o) 0))
|
|
(end (if (and (pair? o) (pair? (cdr o)))
|
|
(cadr o)
|
|
(uvector-length vec))))
|
|
(uvector-unfold (lambda (i _) (values (uvector-ref vec (- end i 1)) _))
|
|
(- end start)
|
|
#f)))
|
|
|
|
(define (vector-concatenate vecs)
|
|
(let* ((len (apply + (map uvector-length vecs)))
|
|
(res (make-uvector len)))
|
|
(let lp ((ls vecs) (i 0))
|
|
(if (null? ls)
|
|
res
|
|
(let ((v-len (uvector-length (car ls))))
|
|
(vector-copy! res i (car ls))
|
|
(lp (cdr ls) (+ i v-len)))))))
|
|
|
|
(define (vector-append . vecs)
|
|
(vector-concatenate vecs))
|
|
|
|
(define (vector-append-subvectors . o)
|
|
(let lp ((ls o) (vecs '()))
|
|
(if (null? ls)
|
|
(vector-concatenate (reverse vecs))
|
|
(lp (cdr (cddr ls))
|
|
(cons (vector-copy (car ls) (cadr ls) (car (cddr ls)))
|
|
vecs)))))
|
|
|
|
(define (vector-fill! vec x . o)
|
|
(let ((start (if (pair? o) (car o) 0))
|
|
(end (if (and (pair? o) (pair? (cdr o)))
|
|
(cadr o)
|
|
(uvector-length vec))))
|
|
(let lp ((i (- end 1)))
|
|
(when (>= i start)
|
|
(uvector-set! vec i x)
|
|
(lp (- i 1))))))
|
|
|
|
(define (vector-swap! vec i j)
|
|
(let ((tmp (uvector-ref vec i)))
|
|
(uvector-set! vec i (uvector-ref vec j))
|
|
(uvector-set! vec j tmp)))
|
|
|
|
(define (vector-reverse! vec . o)
|
|
(let lp ((left (if (pair? o) (car o) 0))
|
|
(right (- (if (and (pair? o) (pair? (cdr o)))
|
|
(cadr o)
|
|
(uvector-length vec))
|
|
1)))
|
|
(cond
|
|
((>= left right) (if #f #f))
|
|
(else
|
|
(vector-swap! vec left right)
|
|
(lp (+ left 1) (- right 1))))))
|
|
|
|
(define (vector-copy! to at from . o)
|
|
(let* ((start (if (pair? o) (car o) 0))
|
|
(end (if (and (pair? o) (pair? (cdr o)))
|
|
(cadr o)
|
|
(uvector-length from)))
|
|
(limit (min end (+ start (- (uvector-length to) at)))))
|
|
(if (<= at start)
|
|
(do ((i at (+ i 1)) (j start (+ j 1)))
|
|
((>= j limit))
|
|
(uvector-set! to i (uvector-ref from j)))
|
|
(do ((i (+ at (- end start 1)) (- i 1))
|
|
(j (- limit 1) (- j 1)))
|
|
((< j start))
|
|
(uvector-set! to i (uvector-ref from j))))))
|
|
|
|
(define (vector-reverse-copy! to at from . o)
|
|
(let ((start (if (pair? o) (car o) 0))
|
|
(end (if (and (pair? o) (pair? (cdr o)))
|
|
(cadr o)
|
|
(uvector-length from))))
|
|
(vector-copy! to at from start end)
|
|
(vector-reverse! to at (+ at (- end start)))))
|
|
|
|
(define (vector-take vec n)
|
|
(vector-copy vec 0 n))
|
|
|
|
(define (vector-take-right vec n)
|
|
(vector-copy vec (- (uvector-length vec) n)))
|
|
|
|
(define (vector-drop vec n)
|
|
(vector-copy vec n))
|
|
|
|
(define (vector-drop-right vec n)
|
|
(vector-copy vec 0 (- (uvector-length vec) n)))
|
|
|
|
(define (vector-segment vec n)
|
|
(let ((len (uvector-length vec)))
|
|
(let lp ((i 0) (res '()))
|
|
(if (>= i len)
|
|
(reverse res)
|
|
(lp (+ i n)
|
|
(cons (vector-copy vec i (min (+ i n) len)) res))))))
|
|
|
|
(define (vector-fold kons knil vec1 . o)
|
|
(let ((len (uvector-length vec1)))
|
|
(if (null? o)
|
|
(let lp ((i 0) (acc knil))
|
|
(if (>= i len)
|
|
acc
|
|
(lp (+ i 1) (kons acc (uvector-ref vec1 i)))))
|
|
(let lp ((i 0) (acc knil))
|
|
(if (>= i len)
|
|
acc
|
|
(lp (+ i 1)
|
|
(apply kons acc (uvector-ref vec1 i)
|
|
(map (lambda (v) (uvector-ref v i)) o))))))))
|
|
|
|
(define (vector-fold-right kons knil vec1 . o)
|
|
(let ((len (uvector-length vec1)))
|
|
(if (null? o)
|
|
(let lp ((i (- len 1)) (acc knil))
|
|
(if (negative? i)
|
|
acc
|
|
(lp (- i 1) (kons acc (uvector-ref vec1 i)))))
|
|
(let lp ((i (- len 1)) (acc knil))
|
|
(if (negative? i)
|
|
acc
|
|
(lp (- i 1)
|
|
(apply kons acc (uvector-ref vec1 i)
|
|
(map (lambda (v) (uvector-ref v i)) o))))))))
|
|
|
|
(define (vector-map! f vec1 . o)
|
|
(apply vector-fold
|
|
(lambda (i . o)
|
|
(uvector-set! vec1 i (apply f o))
|
|
(+ i 1))
|
|
0 vec1 o))
|
|
|
|
(define (vector-map f vec1 . o)
|
|
(let ((res (vector-copy vec1)))
|
|
(apply vector-map! f res o)
|
|
res))
|
|
|
|
(define (vector-for-each f vec1 . o)
|
|
(apply vector-fold (lambda (acc . o) (apply f o) acc) (if #f #f) vec1 o))
|
|
|
|
(define (vector-count f vec1 . o)
|
|
(apply vector-fold
|
|
(lambda (sum . o) (+ sum (if (apply f o) 1 0)))
|
|
0 vec1 o))
|
|
|
|
(define (vector-cumulate f knil vec)
|
|
(let* ((len (uvector-length vec))
|
|
(res (make-uvector len)))
|
|
(let lp ((i 0) (acc knil))
|
|
(if (>= i len)
|
|
res
|
|
(let ((acc (f acc (uvector-ref vec i))))
|
|
(uvector-set! res i acc)
|
|
(lp (+ i 1) acc))))))
|
|
|
|
(define (vector-index pred vec)
|
|
(let ((len (uvector-length vec)))
|
|
(let lp ((i 0))
|
|
(cond ((>= i len) #f)
|
|
((pred (uvector-ref vec i)) i)
|
|
(else (lp (+ i 1)))))))
|
|
|
|
(define (vector-index-right pred vec)
|
|
(let lp ((i (- (uvector-length vec) 1)))
|
|
(cond ((negative? i) #f)
|
|
((pred (uvector-ref vec i)) i)
|
|
(else (lp (- i 1))))))
|
|
|
|
(define (vector-skip pred vec)
|
|
(vector-index (lambda (x) (not (pred x))) vec))
|
|
|
|
(define (vector-skip-right pred vec)
|
|
(vector-index-right (lambda (x) (not (pred x))) vec))
|
|
|
|
(define (vector-take-while vec pred)
|
|
(vector-copy vec 0 (or (vector-skip pred vec)
|
|
(uvector-length vec))))
|
|
|
|
(define (vector-take-while-right vec pred)
|
|
(vector-copy vec (or (vector-skip-right pred vec) 0)))
|
|
|
|
(define (vector-drop-while vec pred)
|
|
(vector-copy vec (or (vector-index pred vec) 0)))
|
|
|
|
(define (vector-drop-while-right vec pred)
|
|
(vector-copy vec 0 (or (vector-index-right pred vec)
|
|
(uvector-length vec))))
|
|
|
|
(define (vector-binary-search vec value cmp)
|
|
(let lp ((lo 0) (hi (- (uvector-length vec) 1)))
|
|
(and (<= lo hi)
|
|
(let* ((mid (quotient (+ lo hi) 2))
|
|
(x (uvector-ref vec mid))
|
|
(y (cmp value x)))
|
|
(cond
|
|
((< y 0) (lp lo (- mid 1)))
|
|
((> y 0) (lp (+ mid 1) hi))
|
|
(else mid))))))
|
|
|
|
(define (vector-any pred? vec1 . o)
|
|
(let ((len (apply min (uvector-length vec1)
|
|
(map uvector-length o))))
|
|
(let lp ((i 0))
|
|
(and (< i len)
|
|
(or (apply pred? (uvector-ref vec1 i)
|
|
(map (lambda (v) (uvector-ref v i)) o))
|
|
(lp (+ i 1)))))))
|
|
|
|
(define (vector-every pred? vec1 . o)
|
|
(let ((len (apply min (uvector-length vec1)
|
|
(map uvector-length o))))
|
|
(let lp ((i 0))
|
|
(let ((x (apply pred? (uvector-ref vec1 i)
|
|
(map (lambda (v) (uvector-ref v i)) o))))
|
|
(if (= i (- len 1))
|
|
x
|
|
(and x (lp (+ i 1))))))))
|
|
|
|
(define (vector-partition pred? vec)
|
|
(let* ((len (uvector-length vec))
|
|
(res (make-uvector len)))
|
|
(let lp ((i 0) (left 0) (right (- len 1)))
|
|
(cond
|
|
((= i len)
|
|
(if (< left len)
|
|
(vector-reverse! res left))
|
|
(values res left))
|
|
(else
|
|
(let ((x (uvector-ref vec i)))
|
|
(cond
|
|
((pred? x)
|
|
(uvector-set! res left x)
|
|
(lp (+ i 1) (+ left 1) right))
|
|
(else
|
|
(uvector-set! res right x)
|
|
(lp (+ i 1) left (- right 1))))))))))
|
|
|
|
(define (vector-filter pred vec)
|
|
(list->uvector
|
|
(reverse
|
|
(vector-fold (lambda (ls elt) (if (pred elt) (cons elt ls) ls))
|
|
'() vec))))
|
|
|
|
(define (vector-remove pred vec)
|
|
(vector-filter (lambda (x) (not (pred x))) vec))
|
|
|
|
(define (reverse-vector->list vec . o)
|
|
(let ((vec (if (pair? o) (apply vector-copy vec o) vec)))
|
|
(vector-fold (lambda (ls x) (cons x ls)) '() vec)))
|
|
|
|
(define (reverse-list->vector ls)
|
|
(list->uvector (reverse ls)))
|
|
|
|
(define (uvector->vector vec . o)
|
|
(list->vector (apply uvector->list vec o)))
|
|
|
|
(define (vector->uvector vec . o)
|
|
(list->uvector (apply vector->list vec o)))
|
|
|
|
(define make-vector-generator
|
|
(let ((eof (read-char (open-input-string ""))))
|
|
(lambda (vec)
|
|
(let ((i 0) (len (uvector-length vec)))
|
|
(lambda ()
|
|
(if (>= i len)
|
|
eof
|
|
(let ((res (uvector-ref vec i)))
|
|
(set! i (+ i 1))
|
|
res)))))))
|
|
|
|
(define write-vector write)
|