#!perl use 5.010; use strict; use warnings qw(FATAL all); my $balanced = qr{([^<>,]++|<(?-1),(?-1),(?-1),(?-1)>)}; my ($a, $b, $c, $d, $x, $y, $z) = map +qr((?<$_>$balanced)), 'a'..'d', 'x'..'z'; my $col = qr{(?[RB])}; sub balance { local $_ = shift; if( /^,$y,$c>,$z,$d>\z/ or /^>,$z,$d>\z/ or /^,$z,$d>>\z/ or /^>>\z/ ) { my ($aa, $bb, $cc, $dd) = @+{'a'..'d'}; my ($xx, $yy, $zz) = @+{'x'..'z'}; ",$yy,>"; } else { $_; } } sub ins { my ($xx, $tree) = @_; if($tree =~ m{^<$col,$a,$y,$b>\z} ) { my ($color, $aa, $bb, $yy) = @+{qw(col a b y)}; if( $xx < $yy ) { return balance "<$color,".ins($xx,$aa).",$yy,$bb>"; } elsif( $xx > $yy ) { return balance "<$color,$aa,$yy,".ins($xx,$bb).">"; } else { return $tree; } } elsif( $tree !~ /,/) { return ""; } else { print "Unexpected failure!\n"; print "Tree parts are: \n"; print $_, "\n" for $tree =~ /$balanced/g; exit; } } sub insert { my $tree = ins(@_); $tree =~ m{^<$col,$a,$y,$b>\z} or die; ""; } MAIN: { my @a = 1..10; for my $aa ( 1 .. $#a ) { my $bb = int rand( 1 + $aa ); @a[$aa, $bb] = @a[$bb, $aa]; } my $t = "!"; for( @a ) { $t = insert( $_, $t ); print "Tree: $t.\n"; } } print "Done\n";