【问题标题】:How to compile and run this code without using erlang shell如何在不使用 erlang shell 的情况下编译和运行此代码
【发布时间】:2013-11-17 07:32:29
【问题描述】:

如何在不使用 erlang shell 的情况下编译和运行这段代码

我在 erlang 中有以下代码,它为 n-queens 问题提供了解决方案。它以皇后的数量作为参数。该程序在 erl shell 上成功运行。但是我需要在 linux 终端上不带 shell 运行这个程序,这样我就可以使用 'time' 命令来测量程序的执行时间。

    -module(queen).
-export([queen/1]).

queen(N) ->
    IJ = [{I, J} || I <- lists:seq(1, N), J <- lists:seq(1, N)],
    lists:foreach(fun({I, J}) -> put_data(I, J, true) end, IJ),
    solve(N, 1, [], 0).

solve(N, J, Board, Count) when N < J ->
    print(N, Board),
    Count + 1;
solve(N, J, Board, Count) ->
    F = fun(I, Cnt) ->
            case get_data(I, J) of
                true  ->
                    put_data(I, J, false),
                    Cnt2 = solve(N, J+1, [I|Board], Cnt),
                    put_data(I, J, true),
                    Cnt2;
                false -> Cnt
            end
        end,
    lists:foldl(F, Count, lists:seq(1, N)).

put_data(I, J, Bool) ->
    put({row, I  }, Bool),
    put({add, I+J}, Bool),
    put({sub, I-J}, Bool).

get_data(I, J) ->
    get({row, I}) andalso get({add, I+J}) andalso get({sub, I-J}).

print(N, Board) ->
    Frame = "+-" ++ string:copies("--", N) ++ "+",
    io:format("~s~n", [Frame]),
    lists:foreach(fun(I) -> print_line(N, I) end, Board),
    io:format("~s~n", [Frame]).

print_line(N, I) ->
    F = fun(X, S) when X == I -> "Q " ++ S;
           (_, S)             -> ". " ++ S
        end,
    Line = lists:foldl(F, "", lists:seq(1, N)),
    io:format("| ~s|~n", [Line]).

【问题讨论】:

    标签: shell compilation erlang erlang-shell


    【解决方案1】:

    您可以使用timer 模块检查执行速度:

    {Time, Value} = timer:tc(queen, queen, [N])
    

    或者您可以将代码转换为 escript:

    #!/usr/bin/env escript
    
    -mode(native). %% to fun faster
    
    main([NStr]) ->
        N = list_to_integer(NStr),
        IJ = [{I, J} || I <- lists:seq(1, N), J <- lists:seq(1, N)],
        lists:foreach(fun({I, J}) -> put_data(I, J, true) end, IJ),
        solve(N, 1, [], 0).
    
    solve(N, J, Board, Count) when N < J ->
        print(N, Board),
        Count + 1;
    solve(N, J, Board, Count) ->
        F = fun(I, Cnt) ->
                case get_data(I, J) of
                    true  ->
                        put_data(I, J, false),
                        Cnt2 = solve(N, J+1, [I|Board], Cnt),
                        put_data(I, J, true),
                        Cnt2;
                    false -> Cnt
                end
            end,
        lists:foldl(F, Count, lists:seq(1, N)).
    
    put_data(I, J, Bool) ->
        put({row, I  }, Bool),
        put({add, I+J}, Bool),
        put({sub, I-J}, Bool).
    
    get_data(I, J) ->
        get({row, I}) andalso get({add, I+J}) andalso get({sub, I-J}).
    
    print(N, Board) ->
        Frame = "+-" ++ string:copies("--", N) ++ "+",
        io:format("~s~n", [Frame]),
        lists:foreach(fun(I) -> print_line(N, I) end, Board),
        io:format("~s~n", [Frame]).
    
    print_line(N, I) ->
        F = fun(X, S) when X == I -> "Q " ++ S;
               (_, S)             -> ". " ++ S
            end,
        Line = lists:foldl(F, "", lists:seq(1, N)),
        io:format("| ~s|~n", [Line]).
    

    并使其在 linux shell 中可执行:

    chmod +x queue
    

    然后使用命令./queuetime ./queue 从 linux shell 运行它

    【讨论】:

    • 当然测量的时间包括启动erlang和编译代码的时间,以及运行实际代码的时间。
    • 感谢您的回复。我更喜欢使用 escript 的第二种方法。但由于以下错误,我无法在本机模式下运行它:警告:此系统未配置为本机代码编译。 escript:异常错误:在从 escript:start/1 (escript. erl,第 277 行) init:start_it/1 调用 init:start_em/1 如何配置我的系统以在本机模式下运行?
    • 也许你应该创建新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 2017-10-31
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多