in reply to Peeling the Peelings

This avoids loops (external to the regex at least). It might compare favorably if you remove the balance check code.

sub peeln { local $_ = shift; my $n = shift; my($o, $c) = (tr[(][], tr[)][]); warn 'Unbalanced parens' unless $o == $c; $n = $c if $n == -1 or $n > $c; m[^ (?: .*? \( .*?){$n} (.+) (?: .*? \) .*?){$n} $]x; $1; } my @tests = ( 'hello(what(is(this(all(about)))))', 'hello(what(is(this(all(about))))))', 'hello((what(is(this(all(about)))))', 'A(B(c) D(e) f(g(h(i))))', ); for my $test ( @tests ) { print "$test : $_ : ", peeln( $test, $_ ) for -1 .. 5; } __END__ P:\>270595 hello(what(is(this(all(about))))) : -1 : about hello(what(is(this(all(about))))) : 0 : hello(what(is(this(all(about)) +))) hello(what(is(this(all(about))))) : 1 : what(is(this(all(about)))) hello(what(is(this(all(about))))) : 2 : is(this(all(about))) hello(what(is(this(all(about))))) : 3 : this(all(about)) hello(what(is(this(all(about))))) : 4 : all(about) hello(what(is(this(all(about))))) : 5 : about Unbalanced parens at P:\270595.pl8 line 28. Use of uninitialized value in print at P:\270595.pl8 line 42. hello(what(is(this(all(about)))))) : -1 : Unbalanced parens at P:\270595.pl8 line 28. hello(what(is(this(all(about)))))) : 0 : hello(what(is(this(all(about) +))))) Unbalanced parens at P:\270595.pl8 line 28. hello(what(is(this(all(about)))))) : 1 : what(is(this(all(about))))) Unbalanced parens at P:\270595.pl8 line 28. hello(what(is(this(all(about)))))) : 2 : is(this(all(about)))) Unbalanced parens at P:\270595.pl8 line 28. hello(what(is(this(all(about)))))) : 3 : this(all(about))) Unbalanced parens at P:\270595.pl8 line 28. hello(what(is(this(all(about)))))) : 4 : all(about)) Unbalanced parens at P:\270595.pl8 line 28. hello(what(is(this(all(about)))))) : 5 : about) Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : -1 : all(about Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : 0 : hello((what(is(this(all(about +))))) Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : 1 : (what(is(this(all(about)))) Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : 2 : what(is(this(all(about))) Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : 3 : is(this(all(about)) Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : 4 : this(all(about) Unbalanced parens at P:\270595.pl8 line 28. hello((what(is(this(all(about))))) : 5 : all(about Use of uninitialized value in print at P:\270595.pl8 line 42. A(B(c) D(e) f(g(h(i)))) : -1 : A(B(c) D(e) f(g(h(i)))) : 0 : A(B(c) D(e) f(g(h(i)))) A(B(c) D(e) f(g(h(i)))) : 1 : B(c) D(e) f(g(h(i))) A(B(c) D(e) f(g(h(i)))) : 2 : c) D(e) f(g(h(i)) A(B(c) D(e) f(g(h(i)))) : 3 : e) f(g(h(i) A(B(c) D(e) f(g(h(i)))) : 4 : g(h(i Use of uninitialized value in print at P:\270595.pl8 line 42. A(B(c) D(e) f(g(h(i)))) : 5 :

It doesn't handle (?term?) nesting like this a(b(c) d(e)), but it was unclear to me what the return would be in these circumstances?


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Replies are listed 'Best First'.
Re: Re: Peeling the Peelings
by bobn (Chaplain) on Jul 02, 2003 at 01:33 UTC
    Actually, your cosde is a lot slower, once again, go figure: Results:
    Benchmark: timing 15000 iterations of his, mine, mine-less-lgnt, other +... his: 5 wallclock secs ( 4.94 usr + 0.00 sys = 4.94 CPU) @ 30 +36.44/s (n=15000) mine: 5 wallclock secs ( 4.94 usr + 0.01 sys = 4.95 CPU) @ 30 +30.30/s (n=15000) mine-less-lgnt: 3 wallclock secs ( 3.43 usr + 0.00 sys = 3.43 CPU) +@ 4373.18/s (n=15000) other: 22 wallclock secs (20.89 usr + 0.03 sys = 20.92 CPU) @ 71 +7.02/s (n=15000)


    --Bob Niederman, http://bob-n.com

      UpdateThis version is competely wrong!! It is quick because it does nothing at all. I benchmarked this, but verified the output of a completely different, correct, but much slower piece of code.

      A subtle variation on my last version acheives a worthwhile speedup. It's about 50% quicker than my previous best and over twice as fast as the original.

      I wish there was a way to put a big red cross through the code as well.

      ## !!! DO NOT USE !!! TOTALLY BOGUS CODE. !!! sub peel2 { my( $s, $n ) = @_; my($start, $stop, $p, $q) = (length $s, 0, 0); ($start, $stop) = ($p, $q) while $p = 1+index( $s, ')', $stop ) < 0 and $q = rindex( $s, '(', $start ) < 0 and $n--; substr $s, $start, $stop - $start; } Rate his mine-less-lgnt buk2 + buk3 his 569/s -- -35% -45% + -62% mine-less-lgnt 875/s 54% -- -15% + -42% buk2 1026/s 80% 17% -- + -32% buk3 1502/s 164% 72% 46% + --

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


      As my original attempt was so crap, I thought I'd take another crack. Abandoning any attempt at validation and avoiding the regex engine completely, I came up with this which seems to be about 15% better than the best so far.

      sub peel { my( $s, $n ) = @_; my( $start, $stop ) = ( 0, length $s ); ($start,$stop) = ( 1 + index( $s, '(', $start ), rindex( $s, ')', $stop -1 ) # reformatting_for_posting error corrected # Was ) while $n-- > 0 and index( $s, '(', $start +1 ) > 0; ) while $n-- and index( $s, '(', $start +1 ) > 0; substr $s, $start, $stop - $start; } Rate mine-less-lgnt buk2 mine-less-lgnt 918/s -- -15% buk2 1075/s 17% --

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


        Not bad, but pluggiing it into Aristotle's magic machine (at here) yields:
        not ok 8 - by substr for case -1 # Failed test (./t53.pl at line 90) # got: 'hello(what(is(this(all(about)))))' # expected: 'about'
        It's easy to be fast when you don't cover all the cases. ;-P

        --Bob Niederman, http://bob-n.com

      Oh well, worth a try:)


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller