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