14
\$\begingroup\$

Write a program or function that takes in a positive integer N (via stdin/command line/function arg) and prints or returns a string representation of a two dimensional random walk that is N steps long, drawn out of slashes: / \ (plus spaces and newlines for spacing).

A 2D random walk starts at the origin of an infinite integer lattice. Then N times repeatedly, a cardinal direction (up, down, left, right) is chosen uniformly at random and the walker moves one unit in that direction. The resulting path taken is the random walk.

Here is a random walk for N = 6. Notice that it traverses back on itself when it reaches (-1, 3).

N = 6 random walk example

To draw this with slashes we essentially need to rotate the entire thing 45° clockwise. The axes and start and end points are not drawn in the slash version.

/
\
 \
 /\

A more complex walk like this (N = 20, though there's no way to tell):

N = 20 random walk example

Would become this:

     /
/\/ /\
\/\/
/\/
\/

Your program needs to generate these type of slash versions of random walks. You must randomly choose each new direction the walk takes, so every running of the program for a certain N will almost definitely produce a different walk. (Pseudorandomness is fine.)

There should never be any empty lines above or below the lowest and highest slashes (except for one optional trailing newline), and there should never be empty columns of spaces before or after the leftmost and rightmost slashes.

So for N = 1, the output is always / or \, but never something like:

   
 / 

Trailing spaces are allowed as long as they don't go past the column of the rightmost slash.

The submission with the fewest bytes wins. Here's a handy byte counter.

\$\endgroup\$
  • \$\begingroup\$ so it's possible (although rare) that the output could be a single slash even when N = 20? \$\endgroup\$ – DaveAlger Apr 1 '15 at 1:39
  • 2
    \$\begingroup\$ @DaveAlger Sure. Though if your program does that a lot I'd expect something is very wrong. \$\endgroup\$ – Calvin's Hobbies Apr 1 '15 at 1:40
3
\$\begingroup\$

Pyth, 74 bytes

K0VQJO2=GO2 XH,-ZJ-KG@"\/"xJG-=ZtyJ-=KtyG;=YmrhSdheSdCHjbclhYsmh@XkH\ k.xY

An even more optimized translation of Uri Zarfaty's answer.

\$\endgroup\$
  • 1
    \$\begingroup\$ I've got a better Pyth solution: "\ - of course, there's no randomness, but it's a valid walk every time! \$\endgroup\$ – theonlygusti Apr 5 '15 at 17:44
  • \$\begingroup\$ @theonlygusti Then I have an ever better solution: \\. \$\endgroup\$ – orlp Apr 5 '15 at 17:46
  • \$\begingroup\$ Don't get it... \$\endgroup\$ – theonlygusti Apr 5 '15 at 17:52
  • \$\begingroup\$ @theonlygusti Backslash in Pyth starts a 1 character constant. Oh wait, nevermind, isn't shorter xD \$\endgroup\$ – orlp Apr 5 '15 at 18:41
5
\$\begingroup\$

Python 2, 300 285 257 246 236 bytes

Something to kick things off. It should be possible to shrink this down further. Thanks @Maltysen for shaving 10 bytes.

from random import*
N=input()
x=y=0;G={}
exec'n=randrange(4);l=n<2;u=n&1;G[(x-l,y-u)]="\\/"[l^u];x-=2*l-1;y-=2*u-1;'*N
f=lambda i:range(min(x[i]for x in G),max(x[i]for x in G)+1)
for i in f(0):print"".join(G.get((i,j)," ")for j in f(1))

Generates the walk output into a dictionary G of visited (x,y) tuples, updating our location as we go. Each random step n is both either u/d (u) and l/r (l).

\$\endgroup\$
  • 3
    \$\begingroup\$ Neat. N = 100000, font size 1. \$\endgroup\$ – Calvin's Hobbies Apr 1 '15 at 2:51
  • 1
    \$\begingroup\$ You can save a lot with "".join at the j in f(1) loop and printing directly. \$\endgroup\$ – Maltysen Apr 1 '15 at 21:07
1
\$\begingroup\$

PHP 5.5 - 209 bytes

<?for(;$X[]=$x+=1-2*$l,$Y[]=$y+=1-2*$u,$i++<$argv[1];){$m[$y-$u=$n&1][$x-$l=($n=rand(0,3))<2]='\\/'[$u^$l];}for($y=min($Y);$y<max($Y);$y++){for($x=min($X);$x<max($X);$x++)$s.=$m[$y][$x]?:' ';$s.="\n";}echo$s;

Ungolfed:

<?
for (; $X[] = $x += 1 - 2 * $l, $Y[] = $y += 1 - 2 * $u, $i++ < $argv[1];) {
    $m[$y - $u = $n & 1][$x - $l = ($n = rand(0, 3)) < 2] = '\\/'[$u ^ $l];
}
for ($y = min($Y); $y < max($Y); $y++) {
    for ($x = min($X); $x < max($X); $x++) {
        $s .= $m[$y][$x] ? : ' ';
    }
    $s .= "\n";
}
echo $s;

Began working on a PHP answer from scratch, but the final code too much resembled the work of @Uri Zarfaty so I really did not have the nerve to to post it. Ended up porting said answer with a few modifications instead. Pushes x/y values into $X and $Y arrays to determine min/max in output loop.

Usage:

php golf.php 200
\$\endgroup\$
1
\$\begingroup\$

Pyth - 89

This is basically a translation on Uri Zarfaty's answer, though I did make some optimizations.

KZVQJO4=G<J2=b.&J1 XH,-KG-Zb@"\\/".|Gb-=KtyG-=Ztyb)LrhSm@dbHheSm@kbHFNy0jkm?@H,Nb},NbHdy1

Explanation coming soon.

Try it here.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.