[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
> the Haskell answer particularly readable.)
>
> 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>


More information about the erlang-questions mailing list