Erlang - Lista 3.

Zadanie 1.

Wersja 1. (drx)

l3-zad1.erl
-module(zad1).
 
-export([amicable/1, rozklad/1]).
 
rozklad(N) -> rozklad(N, 2, []).
 
addfactor(F, Fs) ->
    T = lists:keyfind(F, 1, Fs),
    if
        T == false -> lists:keystore(F, 1, Fs, {F, 1});
        true ->
            {F, N} = T,
            lists:keyreplace(F, 1, Fs, {F, N+1})
    end.
 
rozklad(N, F, Fs) ->
    M = N rem F,
    if
        F > N -> Fs;
        M =:= 0 -> rozklad(N div F, 2, addfactor(F, Fs));
        M =/= 0 -> rozklad(N, F+1, Fs)
    end.
 
divisors(N) -> divisors(N, 1, []).
 
divisors(N, N, Ds) -> Ds;
divisors(N, D, Ds) ->
    if
        N rem D =:= 0 -> divisors(N, D+1, [D|Ds]);
        true -> divisors(N, D+1, Ds)
    end.
 
amicable(A,B) ->
    (lists:sum(divisors(A)) =:= B)
    and
    (lists:sum(divisors(B)) =:= A).
 
 
amicable(N) -> 
    [ {A,B} ||
        A <- lists:seq(1,N),
        B <- lists:seq(A+1,N),
        amicable(A,B)
    ].

Wersja 2. (dude)

l2z1.erl
-module(l2z1).
-export([zaprzyjaznione/1, rozklad/1]).
 
divisors(N) ->          divisors(N, 1, []).
divisors(N, N, L) ->    L;
divisors(N, M, L) ->    if      N rem M =:= 0 -> divisors(N, M+1, [M|L]);
                                true -> divisors(N, M+1, L)
                        end.
 
divs(N) ->              [lists:sum(divisors(X)) || X <- lists:seq(1, N)].
zaprzyjaznione(N) ->    L = divs(N),
                        [ {A, B} ||
                                A <- lists:seq(1, N-1),
                                B <- lists:seq(A+1, N),
                                lists:nth(A, L) =:= B,
                                lists:nth(B, L) =:= A
                        ].
 
 
group([], _) ->         [];
group([H,H|T], N) ->    group([H|T], N+1);
group([H|T], N) ->      [{H, N} | group(T, 1)].
 
rozklad(N) ->           group(rozklad(N, [2|lists:seq(3,round(math:sqrt(N)), 2)]), 1).
rozklad(_, []) ->       [];
rozklad(N, [H|T]) ->    if
                                N rem H =:= 0 -> [H|rozklad(N div H, [H|T])];
                                true -> rozklad(N, T)
                        end.

Zadanie 2. (dude)

kurwa mac

l2z2.erl
-module(l2z2).
-export([format/2]).
 
format(Width, Indent) ->        Input = lists:map(fun (X) -> string:tokens(string:strip(join(lists:reverse(X))), "      ") end, readl()),
                                Output = lists:reverse(lists:map(fun (X) -> justify(Width - Indent, Width, X) end, Input)),
                                print(Output).
 
print([]) ->    ok;
print([H]) ->   print2(H);
print([H|T]) -> print2(H),
                io:format("~n"),
                print(T).
 
print2([]) ->           ok;
print2([H|T]) ->        io:format("~s~n", [H]),
                        print2(T).
 
justify(I, W, S) ->     First = take(I, S),
                        [string:concat(string:copies(" ", W - I), pad(I, First)) | justify(W, lists:nthtail(length(First), S))].
 
justify(_, []) ->       [];
justify(W, S) ->        Line = take(W, S),
                        Ls = length(S),
                        Ll = length(Line),
                        if
                                Ls == Ll -> [nopad(S)];
                                true -> [pad(W, Line) | justify(W, lists:nthtail(length(Line), S))]
                        end.
 
pad(W, []) ->           "";
pad(W, L) ->    
                        Spaces  = length(L) - 1,
                        if
                                Spaces =:= 0 -> [H|_] = L,
                                                H;
                                true ->
                                        Strlen  = lists:foldl(fun(X, Sum) -> X + Sum end, 0, lists:map(fun (X) -> length(X) end, L)),
                                        Topad   = W - Strlen,
                                        Bspace  = ceiling(Topad / Spaces),
                                        Sspaces = Bspace * Spaces - Topad,
                                        Sspace  = Bspace - 1,
                                        Bspaces = Spaces - Sspaces,
                                        Big =   lists:duplicate(Bspaces, string:copies(" ", Bspace)),
                                        Small = lists:duplicate(Sspaces, string:copies(" ", Sspace)),
                                        interleave(lists:append(Big, Small), L)
                        end.
 
interleave([], []) ->   [];
interleave([], [W]) ->  W;
interleave([S|Ss], [W|Ws]) -> string:concat(string:concat(W, S), interleave(Ss, Ws)).
 
nopad([X]) ->   X;
nopad([H|T]) -> string:concat(string:concat(H, " "), nopad(T)).
 
ceiling(X) ->   T = trunc(X),
                case (X - T) of
                        Neg when Neg < 0 -> T;
                        Pos when Pos > 0 -> T + 1;
                        _ -> T
                end.
 
 
take(N, []) ->          [];
take(N, [H|T]) ->       HLen = string:len(H),
                        if
                                (N < HLen) ->   [];
                                true ->         [H | take(N - length(H) - 1, T)]
                        end.
 
noempty([]) ->          [];
noempty([[]|T]) ->      noempty(T);
noempty([H|T]) ->       [H | noempty(T)].
 
join([]) ->             "";
join([H|T]) ->          lists:append([H, " ", join(T)]).
 
addtab(_, []) ->                [];
addtab(I, [[H|T]|TT]) ->        [[(lists:append(string:copies(" ", I), H)) | T] | addtab(I, TT)].
 
readl() -> noempty(readl([[]])).
readl([H|T]) -> 
                case io:get_line("") of
                        eof  -> [H|T];
                        Line ->
                                S = string:strip(Line),
                                SLine = string:substr(S, 1, length(S) - 1),
                                if
                                        SLine == [] -> readl([[] | [H|T]]);
                                        true -> readl([[SLine | H] | T])
                                end
                end.

Zadanie 3.

l3-zad3.erl
-module(zad3).
-export([new/1, singleton/2, insert/3, delete/2, search/2, split/2, join/2]).
 
% a test:
% (fun({ok,X,new})->zad3:delete(3, X) end)(zad3:new(lists:zip(lists:seq(1,10), lists:seq(501,510)))).
 
 
singleton(K, V) -> {K, V, leaf, leaf}.
 
new(L) ->
    lists:foldl(
        fun({K,V}, {ok, Acc, new})->insert(K, V, Acc) end,
        {ok, leaf, new},
        L
    ).
 
search(SK, T) -> 
    T2 = lookup(SK, T),
    case T2 of
        leaf -> {error, not_found};
        {K, V, _, _} -> if
            SK =:= K -> {ok, T2, V};
            true -> {error, not_found}
            end
        end.
 
lookup(_, leaf) -> leaf;
lookup(SK, T) ->
    {K, V, L, R} = T,
    if
        SK =:= K -> T;
        SK < K -> case lookup(SK, L) of
            leaf -> T;
            {K1, V1, L1, R1} -> {K1, V1, L1, {K, V, R1, R}}
            end;
        true -> case lookup(SK, R) of
            leaf -> T;
            {K1, V1, L1, R1} -> {K1, V1, {K, V, L, L1}, R1}
            end
    end.
 
insert(K, V, T) ->
    case lookup(K, T) of
        leaf -> {ok, singleton(K, V), new};
        {K1, V1, L, R} -> if
            K1 =:= K -> {ok, {K, V, L, R}, V1};
            K1 < K -> {ok, {K, V, {K1, V1, L, leaf}, R}, new};
            true -> {ok, {K, V, L, {K1, V1, leaf, R}, new}}
        end
    end.
 
delete(SK, T) -> case lookup(SK, T) of
    {SK, V, L, R} -> {ok, join(L, R), V};
    true -> {error, not_found}
end.
 
split(SK, T) -> case lookup(SK, T) of
    {SK, _, L, R} -> {ok, L, R};
    true -> {error, not_found}
end.
 
join(T1, T2) -> case splayRight(T1) of 
    {K, V, L, leaf} -> {K, V, L, T2};
    leaf -> T2
end.
 
splayRight(leaf) -> leaf;
splayRight({K, V, L, leaf}) -> {K, V, L, leaf};
splayRight({K1, V1, L1, {K2, V2, L2, R2}}) ->
    splayRight({K2, V2, {K1, V1, L1, L2}, R2}).
 
kurs_jezyka_erlang/10.lista03.txt · ostatnio zmienione: 2010/03/21 19:17 przez d
 
Wszystkie treści w tym wiki, którym nie przyporządkowano licencji, podlegają licencji:MIT License
Recent changes RSS feed