! 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 } ; > swap dupd [ >=< ] curry search drop [ dup even? [ dup 1 + ] [ [ 1 - ] keep ] if rot ] [ drop f ] if* ; inline ERROR: not-an-interval-set obj ; : check-interval-set ( map -- map ) dup interval-set? [ not-an-interval-set ] unless ; inline PRIVATE> : in? ( key set -- ? ) check-interval-set dupd find-interval [ [ start ] [ end 1 - ] bi between? ] [ drop f ] if* ; pairs ( sequence -- intervals ) [ dup number? [ dup 2array ] when ] map ; : 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 ;