Hi all, first time poster etc etc.  I'm a lurker on london pm and play
around on the obfu forum of perlmonks from time to time (as
teamster_jr)...

anyway.  I've just finished this, i hope y'all like it:

@m=((31,(15)x8)x8,(31)x9);$m[$c]|=16,!(@a=grep/-?./&!(16+$|*$'&$m[$c+$&]
),-18,11,94,-92)[EMAIL PROTECTED]:[EMAIL PROTECTED];s/-?.//;[EMAIL 
PROTECTED],$c;$m[$c]&=~8/$
_;++$u-64?$m[$c+=$&]&=~$_:map$_&=15,@m,$c=$|=1},$|&&9x9999999,print"\ec"
,map$_%9?($_-$c?$m[$_]&2?_:$":o).($m[$_]&8?"|":_):$/,1..72until$c>70&$|

apologies if someone else has done it before...

which whilst i'm glad to have finished (thanks to some peeps on perlmonks
- especially mtve)  - ie get down to <288 chars (it started off as two 4
line sigs - one to generate and one to solve), i'm not entirely happy with
it - i had to make lots of concessions to get it to that size (including
an utterly horrible hack to replace a select timing call - 9x999999 which
takes ~.1 s on my machine but YMMV if it works at all (i think it works by
just packing out the code, but i'm not sure!).

so i was wondering if you guys could have a look at the original code and
see if there's a way of golfing it down whilst keeping some more of the
features...

@m=((31,(15)x15)x10,(31)x16);$m[$c]|=16,!(@a=grep!($m[$c+$$_[0]]&16+$s*$
$_[1]),[-1,8],[1,1],[16,4],[-16,2])[EMAIL PROTECTED]:${($i,$j)[EMAIL PROTECTED]@a]};$m[
$c]&=~8/$j;[EMAIL PROTECTED],$c;$m[$c+=$i]&=~$j;++$u-150||map$_&=15,@m,$c=$s=1},$s&
&select$x,$x,$x,.1*print"\ec",(_)x31,map$_%16?($_-$c?$m[$_]&2?_:$":o).($
m[$_]&8?"|":_):"$/|",0..160until$c>158&$s


and here's some commented unpacked code:

#!/usr/bin/perl
# this uses depth first search to generate and solve maze.
#   4           16 = visited
# 8   1
#   2

# m is array of 5 bit numbers:
# bit 1= right
# 2= down
# 3= up
# 4= left
# 5= visited

# search is looking for where visited and
# (direction & s - second pass flag) are unset

# set up maze - border is set as visited. all direction bits set.
@m=((31,(15)x15)x10,(31)x16);

# we now start an until loop - which continues till end of second pass

# set visited bit on current square
$m[$c]|=16,

!(
# search for available options (first part is direction difference,
# second is direction bit

@a=grep!($m[$c+$$_[0]]&16+$s*$$_[1]),
[-1,8],[1,1],[16,4],[-16,2]
)?

# if it's none available then go back
[EMAIL PROTECTED]:
${
# otherwise chose random direction
($i,$j)[EMAIL PROTECTED]@a]};

# unset the current bit with the direction
$m[$c]&=~8/$j;
# add current position to stack
[EMAIL PROTECTED],$c;

# unset next square's direction bit
$m[$c+=$i]&=~$j;

# if we've visited all the squares, then unset visited bit,
# reset position and set flag for second pass (ie turn on
# direction checking in search func).

++$u-150||map$_&=15,@m,$c=$s=1

},

# if we're on second pass draw it (with pause between draws)
 $s&&
select$x,$x,$x,.1*print"\ec",
(_)x31,

map$_%16?
($_-$c?$m[$_]&2?_:$":o).
($m[$_]&8?"|":_):
"$/|",

0..160
# until we get to bottom right.
until$c>158&$s

## end code

well, if you've got this far.  Thanks a lot.

Alex

Reply via email to