! Copyright (C) 2009 Daniel Ehrenberg. ! See https://factorcode.org/license.txt for BSD license. USING: accessors alien.c-types arrays assocs binary-search classes combinators kernel make math math.order sequences sequences.private sorting specialized-arrays ; SPECIALIZED-ARRAY: uint IN: interval-sets ! Sets of positive integers ! Intervals are a pair of { start end } TUPLE: interval-set { array uint-array read-only } ; : interval-in? ( key set -- ? ) interval-set check-instance array>> dupd [ <=> ] with search swap [ even? [ >= ] [ 1 - <= ] if ] [ 2drop f ] if* ; pairs ( sequence -- intervals ) [ dup number? [ dup 2array ] when ] map ; : disjoint? ( node1 node2 -- ? ) [ second-unsafe ] [ first-unsafe ] 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 ;