Up

Maze - evolution of a sig

You might also want to see "let's go to the movies" here

This page, like everything else here is organised in a confusing fashion - It's designed to be read bottom to top, cos that made sense in my mind....

The basic way this sig works is depth first search, basically you:

9 - everything i want (but 14 over - 11 real chars, but wrapping probs)

@m=((31,(15)x15)x10,(31)x16);$m[$c]|=16,!(@a=grep/.$/&!($m[$c+$`]&16+$|*
$&),-18,11,164,-162)?$c=pop@p:${$a[rand@a]=~/.$/;push@p,$c;$m[$c]&=~8/$&
;$m[$c+=$`]&=15-$&;++$u-150||map$_&=15,@m,$c=$|=1},$|&&9x2e6&print"\ec",
(_)x31,map$_%16?($_-$c?$m[$_]&2?_:$":o).($m[$_]&8?"|":_):"$/|",0..159   
until$c>158&$|

This has everything i want - a border, a large maze, bar as a wall. but doesn't fit.... Work goes on. If you want to have a go this script is useful.

8 - shorter timer & different wall char (fits!)

@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]=~/.$/;push@p,$c;$m[$c]&=~8/$&;$m[$
c+=$`]&=15-$&;++$u-64||map$_&=15,@m,$c=$|=1},$|&&9x4e7,print"\ec",(_)x17
,map$_%9?($_-$c?$m[$_]&2?_:$":o).($m[$_]&8?l:_):$/.l,0..71until$c>70&$|

the timer can be compressed to 9x4e7. also by using l (ell) instead of | (pipe) we save on having to quote it (as it's in a map). This is the final released version( so far) - however i don't think the small maze and the delimiter look that good, so version 9 will solve that.

7 - remove outer wall (fits!)

@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&$|

so to make it fit i removed the outer wall, passed a single argument to grep and use regext to grab the different parts, and also found a new way of pausing. instead of using select$q,$q,$q,0.1 which is many chars I started thinking of using a complex maths equation that takes a long time. This didn't work, but what if i did it a lot? After some iterations I found that the left hand side didn't matter, just the number of times you do it. This resulted in 9x9999999 - which takes ~0.1 seconds on my machine (YMMV!). I think this works by mallocing into memory repeatedly then throwing it away. (either that or the repetition of the x operator - solutions to me!)

this is also the first time i don't have the dodgy last square problem.

6 - make maze smaller (!) (31 over)

@m=((31,(15)x8)x9,(31)x9);$m[$c]|=16,!(@a=grep!($m[$c+$$_[0]]&16+$s*$$_[
1]),[-1,8],[1,1],[9,4],[-9,2])?$c=pop@p:${($i,$j)=@{$a[rand@a]};$m[$c]&=
~8/$j;push@p,$c;++$u-72?$m[$c+=$i]&=~$j:map$_&=15,@m,$c=$s=1},$s&&select
$x,$x,$x,.1*print"\ec",(_)x17,map$_%9?($_-$c?$m[$_]&2?_:$":o).($m[$_]&8?
"|":_):"$/|",0..81until$c>79&$s

Because there are many instances of the size of the maze, making it 9x9 (and making some optimisations) saves 11 chars

5 - single unless (42 over)

@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

13 saved by making whole thing half a single unless string see source)

4 - Grep function passed 2 part array not 3 (55 over)

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

So i've saved 22 by making this change (explained in source code).

3 - Moved to bits (77 over)

@m=((16,(15)x15)x10,(16)x16);{$m[$c]|=16;(@a=grep!($m[$c+@$_[$l=0]]&(16|
$s*@$_[2])),[-1,1,2],[1,2,1],[-16,4,8],[16,8,4])?${($i,$j,$k)=@{$a[rand@
a]},push@p,$c;$m[$c]&=~$j;$m[$c+=$i]&=~$k;map{$_==16?$p:$_&=15}@m,$c=$s=
1if++$v==150}:($c=pop@p) ;select$q,$q,$q,(print"\ec",(_)x30,map{$l++%16?
($l-1==$c?o:$_&8?_:$").($_&2?"|":_):"$/|"}@m[0..160])/9if$s;$c>158&$s?0:

So this optimisation has saved almost a whole line (65 chars).

Now each square is represented by a single 5 bit value in an array.

2 - a single large sig (142 over)

$p=1;{@a=grep!$v{$_}&$_>47&$_<751,($p-1)%47&&$m[$p-1]ne"|"?$p-2:0,($p+2)
%47&&$m[$p+1]ne"|"?$p+2:0,$m[$p]ne _?$p+47:0,$m[$p-47]ne _?$p-47:0;$m[$p
]||=_;if($l){print$_?$_%47?$p-$_?$m[$_]:o:"$/|":"\e[H"for 0..750;$p>749?
exit:select$q,$q,$q,.1}@a?(($r=$a[rand@a])-$p)**2>4?$m[$r>$p?$p:$r]=$":(
$m[$r>$p?$r-1:$r+1]=_):($p=pop@v,redo);push@v,$v{$p=$r}=$p;if(keys%v>344
&!$l){$m[$_]||=$_<47|$_==$p?_:"|"for 0..750;%v=$p=$l=print"\ec"}redo}

This is obviously far too long for a sig. There's been a tiny bit of optimisation, but very little.

1 - a pair of sigs (42 over)

See also (this)
# Generator
@m=(_,"|")x345;{my@a;!$v{$_}&$_>0&$_<346?push@a,$_:0for($p-1)%23?$p-1:0,
$p%23?$p+1:0,$p+23,$p-23;$p=pop@v,redo if!@a;(($r=$a[@a*rand])-$p)**2>1?
$m[$r>$p?2*$p-2:2*$r-2]=$":($m[$r>$p?2*$p-1:$r*2-1]=_);push@v,$p;$v{$p}=
$p=$r;keys%v<345&&redo}print$l?"":"\ec"."_"x47,$l++%46?"":"$/|",$_ for@m
# Solver
$|=print"\ec",@m=map{s#\ec##;split//}<>;{$v{$p=$r||50}=1;@a=grep!$v{$_}&
$_>0&$_<767,$m[$p-2]eq _?$p-2:0,$m[$p]eq _?$p+2:0,$m[$p-1]ne _?$p+48:0,$
m[$p-49]ne _?$p-48:0;select$q,$q,$q,.1;printf"\e[%d;%dH",1+$p/48,$p%48;$
p>765?exit:1;$r=!@a?pop@v:$a[@a*rand];push@v,$p if@a;redo}

Since they use the same function for generation and solving (and share a lot of code) it seemed likely that this can fit in 1 4 line sig.

I hope you like these, do what you want with them, just remember where you got 'em yeah?

Ta, Alex