[SPOILER] Solution for Quiz of the Week #23 : parens

Kevin Earls <[email protected]>
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
I was expecting my solution to be unique, but I see that Kester Allena,
and yves had the same thoughts of using binary numbers to represent the
output. Once your map 0 -> '(' and 1 -> ')' you realize you can count
from '0'x$N . '1'x$N .. '01'x$N (eg: N=4; 00001111 -> 01010101) and
print out any string that has the same number of '('s as ')'s which you
can count and replace with tr///.

This could probably be optimized more since the difference
between consecutive numbers create a repeating pattern.  But anyway,
here is my small, but somewhat slow for large values of N, solution.

~% /usr/local/bin/perl -v
This is perl, v5.6.1 built for sun4-solaris

~/bin% uname -a
SunOS landsraad 5.8 Generic_108528-29 sun4u sparc SUNW,Sun-Fire-480R

~% /usr/bin/time ./parens 10 > /dev/null
real        0.9
user        0.9
sys         0.0

~% /usr/bin/time ./parens 12 > /dev/null
real       15.2
user       15.0
sys         0.1

~% cat ./parens
#!/usr/local/bin/perl
my @out = ();
my $N = shift;
my $N2 = $N * 2;
my $i = oct("0b" . "0"x$N . "1"x$N);
my $e = oct("0b" . "01"x$N);
do {
    $_ = sprintf("%0*b",$N2,$i);
    push(@out,$_) if (tr/0/(/ == tr/1/)/);
    $i += 2;
} while ($i <= $e);
print join("\n",@out) . "\n";

__END__


-- 
Kevin Earls                    Email:  [email protected]
Unix System Administrator      Voice:  (903) 868-7208
Standard Linear & Logic        Pager:  (903) 620-2067
Texas Instruments                FAX:  (903) 868-5616
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.