# [erlang-questions] Maze alternate example for Rosetta Code

Richard Carlsson <>
Fri Aug 26 14:55:18 CEST 2016

```Couldn't resist - last time I did one of these was using Sinclair Basic in
1985. Aiming for compact rather than maintainable, I get the following (36
lines); however, making it pretty would only add maybe a dozen lines:

%%% @author Richard Carlsson <>
%%% @copyright (C) 2016, Richard Carlsson

-module(maze).

-export([print/2, build/2]).

print(W, H) ->
M = build(W, H),
io:put_chars([[[array:get(R*(W*2+1)+C, M) || C <- lists:seq(0,W*2)],
\$\n]
|| R <- lists:seq(0,H*2)]).

build(W, H) when is_integer(W), is_integer(H), W > 0, H > 0 ->
M = array:new((W*2+1)*(H*2+1), {default,\$X}),
build(rand:uniform(W)*2-1, rand:uniform(H)*2-1, (W*2+1), (H*2+1), M).

build(X, Y, W, H, M) ->
move([D || {_,D} <- lists:sort(lists:zip([rand:uniform() || _<-"...."],
[{0,-2},{0,2},{2,0},{-2,0}]))],
X, Y, W, H, array:set(Y*W+X, \$\s, M)).

move([{Dx,Dy}|Ds], X, Y, W, H, M) ->
X1 = X + Dx, Y1 = Y + Dy,
move(Ds, X, Y, W, H,
if X1 > 0, X1 < W, Y1 > 0, Y1 < H ->
case array:get(Y1*W+X1, M) of
\$\s -> M;
_   -> build(X1, Y1, W, H,
array:set(((Y+Y1) div 2)*W + (X+X1) div 2,
\$\s, M))
end;
true -> M
end);
move([], _X, _Y, _W, _H, M) ->
M.

/Richard

2016-08-26 7:03 GMT+02:00 Richard A. O'Keefe <>:

> How large should Erlang code for the Rosetta "maze generation"
> task be?  I don't know, but here's a data point.  I did it in
> my Smalltalk.
> - roughly 90 lines
> - 12 lines of comments
> - 25 lines are devoted to generating the output,
>   including terminal ESC sequences.
> - I used the algorithm described in the task page.
> - I wrote shamelessly compact code instead of well
>   documented stuff.  Maintainability shmaintainability.
> - I proudly avoided creating any objects other than one
>   mutable 2D array of bytes.
> - It would have been better to copy the F# code.  Sigh.
>
> Here's another data point: it's going to be hard to beat
> Haskell (67 lines).  The J answer manages it because J is
> particularly expressive (if you can call it that...) with
> arrays, like its ancestor APL.  Erlang is not.
>
> If you can write *maintainable* Erlang code for this problem
> in 120 lines, you deserve some sort of prize.  (I do not call
>
> You could, of course, cheat a bit by copying the F# version
> and using the process dictionary to hold the maze.
> E.g.,
> let removeWallBetween (x1,y1) (x2,y2) =
>     if x1 <> x2 then
>        horizWalls.[min x1 x2, y1] <- false
>     else
>        vertWalsl.[x1, min y1 y2] <- false
> =>
>     remove_wall_between(X, Y1, X, Y2) ->
>         put({v,X,min(Y1,Y2)}, false);
>     remove_wall_between(X1, Y, X2, Y) ->
>         put({h,min(X1,X2),Y}, false).
>
> Not a thing I'd normally recommend, but if this is in its
> own process, you might get away with it.
>
> _______________________________________________
> erlang-questions mailing list
>
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160826/fc16b630/attachment.html>
```