2014-10-17 62 views
0

目前停留在嘗試使用集合實現河內塔。我試圖按照使用堆棧http://www.sanfoundry.com/java-program-implement-solve-tower-of-hanoi-using-stacks/在Java中的例子,但我正在逐漸河內Erlang塔

-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 

當我嘗試運行代碼,我得到這個錯誤。

{"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() 

有人可以看到爲什麼這不起作用嗎?我只是想跟隨sanfoundry的例子。

回答

3

此代碼無法編譯,至少移動/ 4中的變量C在使用時未綁定。因此,在嘗試執行它之前,似乎沒有編譯該文件。

儘管Erlang使用虛擬機,但它必須在執行前進行編譯。

這段代碼中除了C變量還有其他一些問題:你在if的第一行遞歸地調用move/4,而不使用任何返回的值,這不會有任何效果。另外,您正在使用語法錯誤的if語句。正確的語法是:

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

如果你打算用這個,當心,你必須至少有一個後衛是真的,否則代碼會崩潰。

我的版本[編輯:刪除無用的功能,更好的打印]:

-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. 

在shell:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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