Solution for Quiz of the Week #23 : parenths

Coleman Tom <[email protected]>
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <CD5D56CF7254014C84D1A61A3D464CB203DCD7ED@iqhs000e.ww005.siemens.net>
hello qotw discussers,

so I created all the possible combinations,
then had some fun with "eval" to see what was valid.

is "( ) ) ( ( )" ok? find out by $@ after:
eval "\$a = ( 1 ) * 1 ) * 1 * ( 1 * ( 1 );";

thanks for the puzzle,
tom

>> start of code >>

# parens.pl
#

use strict;
use warnings;

unless( $ARGV[0] )
{
    $ARGV[0] = 5;
}

my $size = $ARGV[0] * 2;
my $start_line = '(' x ($size/2) . ')' x ($size/2);

my %patterns;

#####
# mix things up and store.
# 
# mix them up by exchanging two letters
# there must be a better way.

for my $left_pos ( 1..$size - 2 )
{
    for my $right_pos ( 1..$size - 2 )
    {
        my $swapped = $start_line;
        $swapped = swap_two_letters( $swapped, $left_pos, $right_pos );

        $patterns{ $swapped } = 1;

        for my $left_pos_b ( 1..$size - 2 )
        {
            $swapped = swap_two_letters( $swapped, $left_pos_b, $right_pos
);
            $patterns{ $swapped } = 1;

            for my $right_pos_b ( 1..$size - 2 )
            {
                $swapped = swap_two_letters( $swapped, $left_pos_b,
$right_pos_b );
                $patterns{ $swapped } = 1;
            }
        }
    }
}

# print "\n\n****************\n\n";

my $total_count = 0;
my $pass_count = 0;

my %solution = find_valid_code( \%patterns );


##### show the results
###

my $need_count = 1;
my $size_in = $size / 2;
for( 1 .. $size/2 )
{
    $need_count *= $_;
}
$need_count -= 1;

$need_count = "????";

# print "\n\n******* all possible ******** \n\n";

for my $out ( sort( %patterns ) )
{
    last if( $out eq '1' );

#    print "$out\n";
}

print "\n\n******* solution ******** \n\n";

for my $out ( sort( %solution ) )
{
    last if( $out eq '1' );

    print "$out\n";
}

print "total possible patterns: $total_count\n";
print "total that ran as code : $pass_count\n";
print "total sought  ( for $size_in ): $need_count\n";




exit( 0 );

##########################################################

sub swap_two_letters
{
    my $string = shift;
    my $pos_A = shift;
    my $pos_B = shift;

    my $letter_left = substr( $string, $pos_A, 1 );
    my $letter_right = substr( $string, $pos_B, 1 );

    substr( $string, $pos_A, 1 ) = $letter_right;
    substr( $string, $pos_B, 1 ) = $letter_left;

    return $string;
}

# find_valid_code
#
# some are not valid.
# try to run them as code to filter out bad ones.
# use eval to see what works.
#
# prepare code by inserting 1 and * characters
#
# ((())) becomes $a = ( 1 * ( 1 * ( 1 ) * 1 ) * 1 ); and passes
# ()()() becomes $a = ( 1 ) * 1 * ( 1 ) * 1 * ( 1 ); and passes 
# ())(() becomes $a = ( 1 ) * 1 ) * 1 * ( 1 * ( 1 ); and fails

sub find_valid_code
{
    my $pattern_hash_ref = shift;
    my %solution;

    for my $out ( sort( %$pattern_hash_ref ) )
    {
        last if( $out eq '1' );

        $total_count ++;

        my $code = '$a = (';

        for my $pos( 1..length( $out )-1 )
        {
            my $last = substr( $out, $pos-1, 1 );
            my $next = substr( $out, $pos, 1 );
            my $add  = "1";

            if( $last eq ')' )  #  ) 1  ->  ) * 1
            {
                $add = '*' . $add;
            }

            if( $next eq '(' )  #  1 (  ->  1 * (
            {
                $add .= '*';
            }
                                #  ( )  ->  ( 1 )
            $add = '1' if( $last eq '(' and $next eq ')' );

            $code .= $add . substr( $out, $pos, 1 );
        }

        $code .= ';';

        my $a;
        eval( "$code" );
        if( $@ )
        {
#            print "gave an error: $code\n";
        }
        else
        {
#            print "code ran ok  : $code\n";
            $solution{ $out } = 1;
            $pass_count++;
        }
    }

    return %solution
}



-------------------------------------------------------------------------------
This message and any included attachments are from Siemens Medical Solutions 
USA, Inc. and are intended only for the addressee(s).  
The information contained herein may include trade secrets or privileged or 
otherwise confidential information.  Unauthorized review, forwarding, printing, 
copying, distributing, or using such information is strictly prohibited and may 
be unlawful.  If you received this message in error, or have reason to believe 
you are not authorized to receive it, please promptly delete this message and 
notify the sender by e-mail with a copy to Central.SecurityOffice-/v/[email protected] 

Thank you
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.