My boggle solution
"Terje Kristensen" <[email protected]>
| Newsgroups | gmane.comp.lang.perl.golf |
|---|---|
| Message-ID | <[email protected]> |
I'll follow up the new trend of explaining my solution. It's not as advanced as the others so far, but i think it's quite clever :)
my solution is quite straight forward. the only thing that a few have missed is the way to find if the next letter is "adjacent" to the current one.
if you see the boggle playing field like this :
0123
abcd 0
efgh 1
ijkl 2
mnop 3
then two letters with coordinates (x,y) and (X,Y) are "adjacent" if abs(x-X) <= 1 and abs(y-Y) <= 1.
Here is a runthrough of my solution.
sub r{
my$i;
map{$_=$l++,r($i-1),$_=$b[--$l]
if(abs$i-"@_"<6&abs$i++%4-"@_"%4<2|!$l)&$b[$l]eq$_}@ARGV;
$f|=$l==@b
}
@b=/./g,r&&print,$f=0for<STDIN>
in my mail loop i run through <STDIN>, split $_ into an array (@b), call the sub "r", and if the returnvalue from r is true, i print $_.
Then i clean $f which i use to mark that a solution have been found for each word.
@b=/./g,r&&print,$f=0for<STDIN>
in the sub "r", i use a counter $i to register the position in @ARGV. I use $l to count my recursive debth, which is also the position in the @b array.
i loop through @ARGV, and for each value in @ARGV ($ARGV[$i] which is infact $_) i test if it matches the current value in @b ($b[$l]) and that it is
adjacent with the previous letter in @b, or if there is no previous because it's the first letter ($l==0).
if all test tests are true, then i effectively empty $ARGV[$i], increment $l, call "r" with $i as a parameter, decrement $l and then restore $ARGV[$i].
i guess i dont really empty $ARGV[$i] but doing $ARGV[$i]=$l is basicly the same thing since $l is a number and will never match a letter.
the reason that i use r($i-1) is that i increment $i too early, in the comparison, so i have to subtract 1.
map{$_=$l++,r($i-1),$_=$b[--$l]if(abs$i-"@_"<6&abs$i++%4-"@_"%4<2|!$l)&$b[$l]eq$_}@ARGV;
at last i test if my recursive depth matches the number of letters in @b. if it does i have found a solution.
$f|=$l==@b
my "adjacent letter" test have been golfed a bit, so i'll run throught that as well.
since i use $i as a counter i dont have a $x or a $y, so i use $i%4 as $x and $i/4 as $y, and $_[0]%4 as $X and $_[0]/4 as $Y.
as most probably golfers know, when used in an number comparison $_[0] can be written "@_".
abs(int($x/4)-int($X/4)) <= 1 => abs(int(($x-$X)/4)) <= 1
i had to try a bit to remove the int but
abs($x-$X) < 6 worked.
I hope that made sense.
Terje
--
____________________________________________
http://www.operamail.com
Get OperaMail Premium today - USD 29.99/year
Powered by Outblaze