! Copyright (C) 2009 Daniel Ehrenberg. ! See http://factorcode.org/license.txt for BSD license. USING: accessors alien.c-types arrays assocs binary-search combinators fry grouping kernel locals make math math.order sequences sequences.private sorting specialized-arrays ; SPECIALIZED-ARRAY: uint IN: interval-sets ! Sets of positive integers TUPLE: interval-set { array uint-array read-only } ; : in? ( key set -- ? ) check-interval-set array>> over dupd [ >=< ] curry search drop [ dup even? [ dup 1 + ] [ [ 1 - ] keep ] if rot [ nth-unsafe ] curry bi@ 1 - between? ] [ 2drop f ] if* ; pairs ( sequence -- intervals ) [ dup number? [ dup 2array ] when ] map ; ALIAS: start first-unsafe ALIAS: end second-unsafe : disjoint? ( node1 node2 -- ? ) [ end ] [ start ] bi* < ; : (delete-redundancies) ( seq -- ) dup length { { 0 [ drop ] } { 1 [ % ] } [ drop dup first2 < [ unclip-slice , ] [ 2 tail-slice ] if (delete-redundancies) ] } case ; : delete-redundancies ( seq -- seq' ) ! If the next element is >= current one, leave out both [ (delete-redundancies) ] uint-array{ } make ; : make-intervals ( seq -- interval-set ) uint-array{ } like delete-redundancies interval-set boa ; : >intervals ( seq -- seq' ) [ 1 + ] assoc-map concat ; PRIVATE> : ( specification -- interval-set ) spec>pairs sort-keys >intervals make-intervals ; : ( set1 set2 -- set ) [ array>> ] bi@ [ combine-or ] uint-array{ } make make-intervals ; > [ 0 ] [ last ] if-empty ] bi@ max ; PRIVATE> : ( set maximum -- set' ) [ array>> prefix-0 ] dip suffix make-intervals ; : ( set1 set2 -- set ) 2dup interval-max [ '[ _ ] bi@ ] keep ;