简体   繁体   中英

Erlang Towers of Hanoi

Currently stuck on trying to implement the towers of hanoi using a collection. I am trying to follow the example in Java using stacks http://www.sanfoundry.com/java-program-implement-solve-tower-of-hanoi-using-stacks/ , but I am getting

-module(toh).
-export([begin/0]).
begin() -> 
  Pegs = 3,
  TowerA = createTowerA(N),
  TowerB = [],
  TowerC = [],
  move(Pegs, TowerA, TowerB, TowerC).

%fills Tower A with integers from Pegs to 1.
createTowerA(0) -> [];
createTowerA(N) when N > 0 ->
   [N] ++ createTowerA(N - 1).

%displays the towers
display(A, B, C) -> 
   io:format("~w\t~w\t~w~n", [A, B, C]).

move(Pegs, TowerA, TowerB, TowerC) -> 
  if Pegs > 0 ->
    move(Pegs, TowerA, TowerC, TowerB),
    Temp = lists:last(TowerA),
    NewTowerC = C ++ Temp,
    NewTowerA = lists:sublist(TowerA, length(TowerA) - 1),
    display(NewTowerA, B, NewTowerC),
    move(Pegs - 1, B, NewTowerA, NewTowerC);
  end

When I try running the code, I get this error.

{"init terminating in do_boot",{undef,[{toh,begin,[],[]},{init,begin_i
t,1,[{file,"init.erl"},{line,1057}]},{init,begin_em,1,[{file,"init.erl"},{line,1
037}]}]}}

Crash dump was written to: erl_crash.dump
init terminating in do_boot ()

Can someone see why this is not working? I'm just trying to follow the sanfoundry example.

This code cannot compile, at least the variable C in move/4 is unbound when used. So it seems that you didn't compile this file before trying to execute it.

Although Erlang used a virtual machine, it must be compiled before execution.

There are other problems than the C variable in this code: you call move/4 recursively in the first line of the if, without using any returned value, this cannot have any effect. Also you are using a if statement with a bad syntax. the correct syntax is:

if
    GuardSeq1 ->
        Body1;
    ...;
    GuardSeqN ->
        BodyN    % no semicolon at the end of the last body
end

if you intend to use this, beware that you must always have at least one guard that is true, otherwise the code will crash.

My version [edit: remove useless function, better print]:

-module (toh).

-export([start/1]).


start(N) ->
    Game = #{1 => lists:seq(1,N), 2 => [], 3 => []},
    display(Game,N),
    move(N,Game,1,3,N).

move(1,Game,From,To,Size) ->
    [H|NewFrom] = maps:get(From,Game),
    NewTo = [H|maps:get(To,Game)],
    NewGame = maps:update(From,NewFrom,maps:update(To,NewTo,Game)),
    display(NewGame,Size),
    NewGame;
move(N,Game,From,To,Size) ->
    Other = other(From,To),
    Game1 = move(N-1,Game,From,Other,Size),
    Game2 = move(1,Game1,From,To,Size),
    move(N-1,Game2,Other,To,Size).

display(#{1 := A, 2 := B, 3 := C},D) ->
    lists:foreach(fun(X) -> print(X,D) end,lists:zip3(complete(A,D),complete(B,D),complete(C,D))),
    io:format("~n~s~n~n",[lists:duplicate(6*D+5,$-)]).

complete(L,D) -> lists:duplicate(D-length(L),0) ++ L.

print({A,B,C},D) -> io:format("~s ~s ~s~n",[elem(A,D),elem(B,D),elem(C,D)]).

elem(I,D) -> lists:duplicate(D-I,$ ) ++ lists:duplicate(I,$_) ++ "|" ++ lists:duplicate(I,$_) ++ lists:duplicate(D-I,$ ).

other(I,J) -> 6-I-J.

In the shell:

Eshell V6.1  (abort with ^G)
1> c(toh).
{ok,toh}
2> toh:start(3).
  _|_      |       |   
 __|__     |       |   
___|___    |       |   

-----------------------

   |       |       |   
 __|__     |       |   
___|___    |      _|_  

-----------------------

   |       |       |   
   |       |       |   
___|___  __|__    _|_  

-----------------------

   |       |       |   
   |      _|_      |   
___|___  __|__     |   

-----------------------

   |       |       |   
   |      _|_      |   
   |     __|__  ___|___

-----------------------

   |       |       |   
   |       |       |   
  _|_    __|__  ___|___

-----------------------

   |       |       |   
   |       |     __|__ 
  _|_      |    ___|___

-----------------------

   |       |      _|_  
   |       |     __|__ 
   |       |    ___|___

-----------------------

#{1 => [],2 => [],3 => [1,2,3]}
3>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM