Paste: matching braces - beginner (are there much shorter ways?)

Author: randy7
Mode: factor
Date: Wed, 23 Sep 2009 15:02:22
Plain Text |
USING: arrays assocs combinators fry grouping io kernel math
math.order math.ranges namespaces prettyprint sequences sorting
;
IN: braces-matcher

: positions ( text char -- seq )
    [ >array ] dip '[ swap _ = [ drop f ] unless ] map-index sift ;

: prepare-run-count ( seq int -- pairs )
    [ dup length ] dip <array> zip ;
    
: inc-positions ( text char -- pairs )
    positions 1  prepare-run-count ;

: dec-positions ( text char -- pairs )
    positions -1 prepare-run-count ;
    
    

: off? ( var -- ? )
    get f = ;
: on? ( var -- ? )
    off? not ;

<PRIVATE
SYMBOLS: brace-count up? ;
PRIVATE>

    

: counter+ ( int -- current )
    brace-count [ get + ] [ set ] [ get ] tri ;

: reset-counter ( -- )
    brace-count 0 swap set ;

: counter-case ( pos count -- pos/f ) 
    { 
        { [ dup 1 = up? off? and ] [ drop  up? on  ] } ! came from 0
        { [ dup 0 = ] [ drop  up? off ] }
        { [ dup 0 < ] [ 2drop reset-counter f ] }
        [ 2drop f ]  
    } cond ;
    
: open-close-list ( text open-char close-char -- seq )
     [ inc-positions ] [ dec-positions ] bi-curry* bi append sort-keys ;
  
: matching-pairs  ( text open-char close-char -- seq ) 
    reset-counter open-close-list
    [ first2 counter+ counter-case ] map sift 2 <groups> >array ;
  
! testcase:
! [ { { 0 10 } { 14 16 } } ] [ "{ { } { } } } { }" CHAR: { CHAR: } matching-pairs ] unit-test

Annotation: addition

Author: randy7
Mode: factor
Date: Wed, 23 Sep 2009 15:22:08
Plain Text |
: matching-split ( text open-char close-char -- seq ) 
    [ 2drop ] [ matching-pairs ] 3bi 
    [ first2 1 + rot <slice> >string ] with map ;

New Annotation

Summary:
Author:
Mode:
Body: