Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Solving 24 puzzles

by tigervamp (Friar)
on May 20, 2001 at 21:36 UTC ( #81856=perlquestion: print w/replies, xml ) Need Help??
tigervamp has asked for the wisdom of the Perl Monks concerning the following question:

Out of extreme boredom, I wrote the following code to solve 24 puzzles. For those of you that have never played the game 24, you must make the number 24 out of 4 other non-zero numbers using the basic 4 arithmetic operations. For example, the numbers 5, 5, 8, 8 can be made to equal 24 bacause 5*5-8/8=24. With that in mind, the following code solves 24 puzzles by basically trying every possible combination of operations on the four numbers (I think), and then displaying the unique solutions or an error message if no solutions are found. I use a regular expression to introduce parentheses into the expressions to be evaluated to account for solutions that should be evaluated against the order of operations. My two questions are:

1. As you can see in the beginning of my program, I use an array called @optimize_me to store the different orders that numbers will be evaluated. I want to be able to easily convert this program to solve 5, 6, or more numbers. Is there an easier way to to go about this besides the array method I used? Maybe a way to dynamically create such an array?

2. The other problem with solving with more than 4 numbers is that the regular expression that inserts parantheses quickly gets unwieldly. Is the a better way to go about this step or a way to create a regular esxpression that will work for all cases? Here is my code:

#!/usr/bin/perl while (<>) { undef %results; chop; s/ //g; (/^quit$/i) && exit(0); ((/^(?:\d+:){3}\d+$/) && (@given1=split(/:/,$_))) || ((/^\d{4}$/) && ( +@given1=split('',$_))) || (print ("format error: $_\n"),next); @func=('+','*','-','/'); @optimize_me=('0123','0132','0213','0231','0312','0321','1023','1032', +'1203','1230','1302','1320','2013','2031','2103','2130','2301','2310' +,'3012','3021','3102','3120','3201','3210'); while (@optimize_me) { $must=shift(@optimize_me); @select=split('',$must); @given=($given1[$select[0]],$given1[$select[1]],$given1[$select[2]],$g +iven1[$select[3]]); for ($var1=0;$var1<4;$var1++) { for ($var2=0;$var2<4;$var2++) { for ($var3=0;$var3<4;$var3++) { $expression=$given[0].$func[$var1].$given[1].$func[$var2]. +$given[2].$func[$var3].$given[3]; $trans1=$trans2=$trans3=$expression; $trans1=~s/(\d+[\+-]\d+)/\($1\)/; $trans3=~s/(\d+[\+\-\*\/])(\d+[\+-]\d+)/$1\($2\)/; $trans2=~s/((\d+[\+-])+\d+)/\($1\)/g; $tempt=eval($expression); $tempt1=eval($trans1); $tempt2=eval($trans2); $tempt3=eval($trans3); ($tempt==24 && print("$expression\n") && ($results{$expres +sion}=1)) unless $results{$expression}; ($tempt1==24 && print("$trans1\n") && ($results{$trans1}=1 +)) unless $results{$trans1}; ($tempt2==24 && print("$trans2\n") && ($results{$trans2}=1 +)) unless $results{$trans2}; ($tempt3==24 && print("$trans3\n") && ($results{$trans3}=1 +)) unless $results{$trans3}; } } } } (%results) ? print "Found ",$dumb1=keys(%results)," different ways to +form 24 from @given\n" : print "Could not find any ways to make 24 fr +om @given1\n"; }

Any help or comments of any kind are greatly appreciated.

Thanks for your time,


Replies are listed 'Best First'.
Re: Solving 24 puzzles
by MeowChow (Vicar) on May 21, 2001 at 01:51 UTC
    This is a great puzzle which spectacularly combines two previous golf outings. I took the route of least resistance -- instead of bothering with parenthesis, I used reverse-polish notation expressions. This significantly simplified things:
    sub c {@r='';@r=map{$c=$_;map"$c $_",@r}@_ for 1..shift;@r} sub puzzle { ($x,$q,@l)=@_;@l=c$q,@l;@o=c$q-1,qw'+ - / *'; map{$n=$_;map{$t=$n.$_;{$t=~s!(\S+)\s+(\S+)\s*([-+*/])!"$1$3 $2"!ee& +&redo}; $t eq"$x "?$n.$_:()}@o}@l } ## example usage: puzzle ($total, $size, @numbers) ## print join $/, puzzle(24, 4, 6, 9); 6 6 6 6 + + + 6 6 6 9 / * * 6 6 9 6 - * + 6 6 9 6 / / * 6 9 6 6 * / /
    That code is somewhat golfed, and damn messy, so I'm sure it can be significantly improved upon.
                   s aamecha.s a..a\u$&owag.print
Re: Solving 24 puzzles
by Masem (Monsignor) on May 20, 2001 at 21:55 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://81856]
Approved by root
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (13)
As of 2018-06-18 18:19 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (110 votes). Check out past polls.