golf help needed (apologies if double post)

[email protected]
Newsgroups gmane.comp.lang.perl.fun
Message-ID <[email protected]>
First up, apologies if this is a double post, sent earlier, but don't
think i was subscribed....  here it is again (maybe):

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)?$c=pop@p:${$_=$a[rand@a];s/-?.//;push@p,$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])?$c=pop@p:${($i,$j)=@{$a[rand@a]};$m[
$c]&=~8/$j;push@p,$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
$c=pop@p:
${
# otherwise chose random direction
($i,$j)=@{$a[rand@a]};

# unset the current bit with the direction
$m[$c]&=~8/$j;
# add current position to stack
push@p,$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
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.