racket/collects/mrflow/util.ss
Eli Barzilay 16f01a1109 {quick,merge}sort -> sort
svn: r2569
2006-04-01 12:24:15 +00:00

270 lines
8.0 KiB
Scheme

(module util (lib "mrflow.ss" "mrflow")
(require (prefix list: (lib "list.ss"))
(lib "pretty.ss")
(lib "class.ss")
(prefix cst: "constants.ss"))
(provide (all-defined))
;;
;; Number functions
;;
(define natural? (lambda (n) (and (integer? n) (>= n 0))))
;;
;; List functions
;;
(define length-one?
(lambda (x) (and (pair? x) (null? (cdr x)))))
(define nonempty-list-of?
(lambda (p) (lambda (xs) (and (pair? xs) (andmap p xs)))))
(define unfold-onto
(lambda (p f g seed onto)
(if (p seed) onto
(cons (f seed) (unfold-onto p f g (g seed) onto)))))
(define unfold
(lambda (p f g seed)
(unfold-onto p f g seed '())))
;; int -> list int
(define iota
(lambda (n)
(unfold (lambda (x) (= x n)) (lambda (x) x) add1 0)))
(define min-list-numbers
(let ([remove-duplicates ;; remove duplicate numbers from a sorted list
(lambda (xs) ;; of numbers, returned list is reversed
(if (null? xs) '()
(let loop ((xs (cdr xs)) (acc (list (car xs))))
(if (null? xs) acc
(if (< (car xs) (car acc))
(loop (cdr xs) (cons (car xs) acc))
(loop (cdr xs) acc))))))])
(lambda (nums)
(remove-duplicates (list:sort nums >)))))
(define/contract lol->vov ((listof (listof any/c)) . -> . vector?)
(lambda (xss) (list->vector (map list->vector xss))))
(define map2deep
(lambda (f xss)
(map (lambda (xs) (map f xs)) xss)))
(define no-duplicates?/c
(flat-named-contract "List without duplicates"
(lambda (xs)
(let ([tbl (make-hash-table)])
(let/ec return-with
(for-each (lambda (x)
(when (hash-table-get tbl x cst:thunk-false)
(return-with #f))
(hash-table-put! tbl x #t))
xs)
#t)))))
;;
;; Vector functions
;;
(define foldr-vector
(lambda (f init v)
(let loop ([i 0])
(if (= i (vector-length v)) init
(f (vector-ref v i) (loop (add1 i)))))))
(define interval->list
(lambda (v lo hi)
(let loop ([i lo])
(if (= i hi) '()
(cons (vector-ref v i) (loop (add1 i)))))))
(define list->immutable-vector
(lambda xs
(apply vector-immutable xs)))
(define/contract map-vector ((any/c . -> . any) vector? . -> . vector?)
(lambda (f v)
(let* ([len (vector-length v)]
[new-v (make-vector len #f)])
(let loop ([i 0])
(when (< i len)
(vector-set! new-v i (f (vector-ref v i)))
(loop (add1 i))))
new-v)))
(define/contract map-vector-of-vector ((any/c . -> . any) (vectorof vector?) . -> . (vectorof vector?))
(lambda (f vov)
(map-vector (lambda (v) (map-vector f v)) vov)))
(define/contract for-each-vector ((any/c . -> . any) vector? . -> . void?)
(lambda (f v)
(let ([len (vector-length v)])
(let loop ([i 0])
(when (< i len)
(f (vector-ref v i))
(loop (add1 i)))))
cst:void))
; Replace each element e in a vector with (f e)
(define/contract for-each-vector! ((any/c . -> . any) vector? . -> . vector?)
(lambda (f v)
(let ([len (vector-length v)])
(let loop ([i 0])
(when (< i len)
(vector-set! v i (f (vector-ref v i)))
(loop (add1 i)))))
v))
(define/contract for-each-vov ((any/c . -> . any) (vectorof (vectorof any/c)) . -> . void?)
(lambda (f vov)
(for-each-vector (lambda (v) (for-each-vector f v) v) vov)))
; Replace each element in a vector of vectors with (f e)
(define/contract for-each-vov! ((any/c . -> . any) (vectorof (vectorof any/c)) . -> . any)
(lambda (f vov)
(for-each-vector! (lambda (v) (for-each-vector! f v) v) vov)
vov))
(define vector-of?
(lambda (pred v)
(let/ec escape
(let loop ([i 0])
(if (= i (vector-length v)) #t
(if (pred (vector-ref v i))
(loop (add1 i))
(escape #f)))))))
(define vector-of-vector-of?
(lambda (pred vov)
(vector-of? (lambda (v) (vector-of? pred v)) vov)))
(define vector-has?
(lambda (pred v)
(let/ec escape
(let loop ([i 0])
(if (= i (vector-length v)) #f
(if (pred (vector-ref v i))
(escape #t)
(loop (add1 i))))))))
(define vector-of-vector-has?
(lambda (pred vov)
(vector-has? (lambda (v) (vector-has? pred v)) vov)))
;;
;; Hash functions
;;
(define hash-table-size
(lambda (h)
(let ([size 0])
(hash-table-for-each h (lambda (_ _2) (set! size (add1 size))))
size)))
(define hash-table-empty?
(lambda (h)
(let/ec escape
(hash-table-for-each h (lambda (k v) (escape #f)))
#t)))
(define/contract hash-table-has-key? (hash-table? any/c . -> . boolean?)
(lambda (hash-table key)
(if (hash-table-get hash-table key cst:thunk-false) #t #f)))
;; (hash-table key (list value)) key value -> (hash-table key (list value))
(define/contract hash-table-prepend! (hash-table? any/c any/c . -> . any)
(lambda (hash-table key value)
(hash-table-put! hash-table key
(if (hash-table-has-key? hash-table key)
(cons value (hash-table-get hash-table key
(lambda () (error 'hash-table-prepend! "Could not prepend"))))
(list value)))))
;;
;; Function functions
;;
(define (curry f)
(lambda (x) (f x)))
;;
;; Boolean functions
;;
(define true?
(lambda (x) (eq? x #t)))
;;
;; Random functions
;;
(define/contract numberify-symbol (symbol? integer? . -> . symbol?)
(lambda (sym x)
(string->symbol (string-append (symbol->string sym) ":" (number->string x)))))
(define/contract numberify-list ((cons/c symbol? (listof any/c)) integer? . -> . (cons/c symbol? (listof any/c)))
(lambda (syms x)
(cons (numberify-symbol (car syms)) (cdr syms))))
(define/contract pretty-error (symbol? any/c . -> . any)
(lambda (sym v)
(let ([out (open-output-string)])
(pretty-print v out)
(error sym (get-output-string out)))))
(define andmap4-vector
(lambda (f v0 v1 v2 v3)
(let loop ([i 0])
(if (= i (vector-length v0)) #t
(and (f (vector-ref v0 i) (vector-ref v1 i) (vector-ref v2 i) (vector-ref v3 i))
(loop (add1 i)))))))
(define andmap2-vector-interval
(lambda (f v0 v1 lo high)
(let loop ([i lo])
(if (= i high) #t
(and (f (vector-ref v0 i) (vector-ref v1 i))
(loop (add1 i)))))))
(define andmap2-vector
(lambda (f v0 v1)
(andmap2-vector-interval f v0 v1 0 (vector-length v0))))
; return #t if the p(i) = # for all i in the half-open interval lo <= i < hi
(define andmap-vector-interval
(lambda (f v0 lo high)
(let loop ([i lo])
(if (= i high) #t
(and (f (vector-ref v0 i))
(loop (add1 i)))))))
(define andmap-vector
(lambda (f v0)
(andmap-vector-interval f v0 0 (vector-length v0))))
(define ormap4-vector
(lambda (f v0 v1 v2 v3)
(let loop ([i 0])
(if (= i (vector-length v0)) #f
(or (f (vector-ref v0 i) (vector-ref v1 i) (vector-ref v2 i) (vector-ref v3 i))
(loop (add1 i)))))))
;; Classes
(define counter%
(class object%
(init-field [start 0])
(define count start)
(define/public get
(lambda () count))
(define/public next!
(lambda () (set! count (add1 count)) count))
(super-new)))
)