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

Author: randy7 factor 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```

```: matching-split ( text open-char close-char -- seq )