faster version of the code
svn: r17525
This commit is contained in:
parent
41261c6047
commit
39595d2d05
|
@ -1,12 +1,10 @@
|
|||
(module norm-arity '#%kernel
|
||||
(#%require "for.ss" "define.ss" "small-scheme.ss" "sort.ss")
|
||||
(#%require "define.ss" "small-scheme.ss" "sort.ss")
|
||||
(#%provide norm:procedure-arity
|
||||
norm:raise-arity-error
|
||||
normalize-arity) ;; for test suites
|
||||
(define norm:procedure-arity
|
||||
(let ([procedure-arity
|
||||
(λ (p)
|
||||
(normalize-arity (procedure-arity p)))])
|
||||
(let ([procedure-arity (λ (p) (normalize-arity (procedure-arity p)))])
|
||||
procedure-arity))
|
||||
(define norm:raise-arity-error
|
||||
(let ([raise-arity-error
|
||||
|
@ -17,8 +15,8 @@
|
|||
(andmap (λ (x) (or (exact-nonnegative-integer? x)
|
||||
(arity-at-least? x)))
|
||||
arity-v)))
|
||||
(apply raise-arity-error name (normalize-arity arity-v) arg-vs)
|
||||
|
||||
(apply raise-arity-error name
|
||||
(normalize-arity arity-v) arg-vs)
|
||||
;; here we let raise-arity-error signal an error
|
||||
(apply raise-arity-error name arity-v arg-vs)))])
|
||||
raise-arity-error))
|
||||
|
@ -36,62 +34,41 @@
|
|||
;; - no duplicate entries
|
||||
;; - nats are sorted
|
||||
;; - at most one arity-at-least, always at the end
|
||||
;; - if there is only one possibility, it is returned by itself (ie, not in a list)
|
||||
(define (normalize-arity a)
|
||||
(if (pair? a)
|
||||
(let-values ([(min-at-least) #f])
|
||||
|
||||
(for ((a (in-list a)))
|
||||
(when (arity-at-least? a)
|
||||
(when (or (not min-at-least)
|
||||
(< (arity-at-least-value a)
|
||||
(arity-at-least-value min-at-least)))
|
||||
(set! min-at-least a))))
|
||||
|
||||
(if-one-then-no-list
|
||||
(cond
|
||||
[min-at-least
|
||||
(append (uniq
|
||||
(sort
|
||||
(filter (λ (x) (and (number? x)
|
||||
(< x (arity-at-least-value
|
||||
min-at-least))))
|
||||
a)
|
||||
<))
|
||||
(list min-at-least))]
|
||||
[else
|
||||
(uniq (sort a <))])))
|
||||
a))
|
||||
;; - if there is only one possibility, it is returned by itself (ie,
|
||||
;; not in a list)
|
||||
(define (normalize-arity arity)
|
||||
(if (pair? arity)
|
||||
(let loop ([min-at-least #f] [min-num 0] [as arity] [numbers '()])
|
||||
;; (1) find the minimal arity-at-least if any, find only numbers
|
||||
(if (pair? as)
|
||||
(let ([a (car as)] [as (cdr as)])
|
||||
(if (arity-at-least? a)
|
||||
(if (and min-at-least (<= min-num (arity-at-least-value a)))
|
||||
(loop min-at-least min-num as numbers)
|
||||
(loop a (arity-at-least-value a) as numbers))
|
||||
(loop min-at-least min-num as (cons a numbers))))
|
||||
;; (2) remove redundant numbers and sort
|
||||
(let loop ([numbers (sort (if min-at-least
|
||||
(filter-below min-num numbers)
|
||||
numbers)
|
||||
>)] ; reversed in the loop below
|
||||
[result (if min-at-least (list min-at-least) '())])
|
||||
;; (3) throw out duplicates (while reversing the list)
|
||||
(cond [(pair? numbers)
|
||||
(loop (cdr numbers)
|
||||
(if (and (pair? result)
|
||||
(eq? (car numbers) (car result)))
|
||||
result
|
||||
(cons (car numbers) result)))]
|
||||
;; result is never null (otherwise the input would be null)
|
||||
[(null? (cdr result)) (car result)]
|
||||
[else result]))))
|
||||
arity))
|
||||
|
||||
;; have my own version of this to avoid a circular dependency
|
||||
(define (filter p l)
|
||||
(cond
|
||||
[(null? l) l]
|
||||
[else
|
||||
(let ([x (car l)])
|
||||
(if (p x)
|
||||
(cons x (filter p (cdr l)))
|
||||
(filter p (cdr l))))]))
|
||||
|
||||
(define (if-one-then-no-list lst)
|
||||
(cond
|
||||
[(and (pair? lst) (null? (cdr lst)))
|
||||
(car lst)]
|
||||
[else lst]))
|
||||
|
||||
;; uniq : sorted list of integers -> sorted, uniqe list of integers
|
||||
(define (uniq lst)
|
||||
(cond
|
||||
[(null? lst) null]
|
||||
[(null? (cdr lst)) lst]
|
||||
[else
|
||||
(let loop ([fst (car lst)]
|
||||
[rst (cdr lst)])
|
||||
(cond
|
||||
[(null? rst) (list fst)]
|
||||
[else
|
||||
(let ([snd (car rst)])
|
||||
(if (= fst snd)
|
||||
(loop fst (cdr rst))
|
||||
(cons fst (loop snd (cdr rst)))))]))])))
|
||||
|
||||
(define (filter-below max l)
|
||||
(cond [(null? l) l]
|
||||
[else (let ([x (car l)])
|
||||
(if (< x max)
|
||||
(cons x (filter-below max (cdr l)))
|
||||
(filter-below max (cdr l))))])))
|
||||
|
|
Loading…
Reference in New Issue
Block a user