Re: [SPOILER] Perl Quiz of the Week #23

Kripa Sundar <Kripa.Sundar-HKixBCOQz3hWk0Htik3J/[email protected]>
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Hello all,

I posted my script without testing for "0" and "1" in the
input.  The regex in the for(;;) doesn't work for these
special cases.

I append the script corrected to catch these special cases up
front.

For n == 2 to 13, the Catalan count published by Colin Rafferty
last week are correct in this script.  Here is the output of
"time parens $N > p$N", pasted against "wc -l < p$N".

2: 0.02u 0.02s 0:00.06 66.6%	       2
3: 0.03u 0.03s 0:00.05 120.0%	       5
4: 0.02u 0.03s 0:00.06 83.3%	      14
5: 0.01u 0.04s 0:00.06 83.3%	      42
6: 0.03u 0.02s 0:00.07 71.4%	     132
7: 0.11u 0.02s 0:00.13 100.0%	     429
8: 0.32u 0.02s 0:00.35 97.1%	    1430
9: 1.25u 0.03s 0:01.28 100.0%	    4862
10:5.06u 0.01s 0:05.11 99.2%	   16796
11:20.82u 0.08s 0:20.94 99.8%	   58786
12:86.09u 0.06s 1:26.30 99.8%	  208012
13:354.32u 0.20s 5:55.31 99.7%	  742900


Corrected script:
----------------------\/--------BEGIN---------\/----------------------
#!/usr/bin/env perl

# Intention: MJD's QOTW #23.

# $Id: matching-parens.pl,v 1.11 2004/09/07 15:31:45 ksundar Exp ksundar $

# Core idea:
# * Use "0" to indicate left parens and "1" for right parens.
# * Step from "0000...1111" (maximal nesting) to "010101...01" (zero nesting).
# * If balanced, translate to parens and print.
#
# Advantages of zero-one:
# * I find zero's and one's easier to think about than left and right parens.
# * No need to backslash "\(" and "\)" in regexps.
# * $x computation in &parity is simpler.
#
# Disadvantages:
# * It needs $x and y/// before printing.

use 5.006; use strict; use warnings; $^W = 1;

my $N=shift;

# Take care of the two special cases that the for(;;) doesn't like.
exit 0 if !$N;
print "()\n" and exit 0 if $N == 1;

my $x;

for ($_ = ((0 x $N) . (1 x $N)); # Maximal nesting: "0000...1111"
     ! /^(01)+11$/;              # Haven't gone past zero nesting.
     s/0(1*)1$/1 . (0 x length($1)) . 1/e   # Step along.
    ) {
    ($x=$_) =~ y/01/()/, print $x, "\n"
        if ((y/0/0/ == y/1/1/) && &parity);
} # for

exit 0;

sub parity {
    my $x;
    for (split "") {
        return 0 if ($x += $_ ? -1 : 1) < 0;
    }
    1;
} # &parity

__END__

Buggestions:
----------------------/\---------END----------/\----------------------


peace,          || Byatrayanapura: Better governance thru online taxes:
--{kr.pA}       || http://tinyurl.com/296js
-- 
"If I have not seen farther, it is because giants have stood on my shoulders."
    -- V. Guhan.  [with apologies to Newton, Sir Isaac.]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.