[erlang-questions] Maze alternate example for Rosetta Code
Richard Carlsson
carlsson.richard@REDACTED
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 <carlsson.richard@REDACTED>
%%% @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 <ok@REDACTED>:
> 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
> erlang-questions@REDACTED
> 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.htm>
More information about the erlang-questions
mailing list