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