Makistos
1/16/2015 - 1:51 PM

Pairs example written in Erlang (see Haskell version as well) #erlang

Pairs example written in Erlang (see Haskell version as well) #erlang

-module(pairs).
-export([main/0]).

%%%% 
%% Counting characters in strings
%%%%

%% Count number of occurences of C in X.
count_char_in_string(C, X) -> length([Ch || Ch <- X,
				      Ch == C]).

%% Return a list containing the count of each character in Chars for a single name.
count_chars(_, []) ->
    [0];
count_chars([], _) ->
    [0];
count_chars(Chars, Str) ->
    [count_char_in_string(string:to_upper(C), string:to_upper(Str)) || C <- Chars].

%% Count how many occurences of each character in Ch is for every name in the list.
count(_, []) ->
    [];
count(Ch, [H|T]) ->
    [count_chars(Ch, H)] ++ count(Ch, T).

%%%% 
%% Doing calculations
%%%%

%% Creates a list by summing every pair, e.g.
%% [1,2,3,4] -> [3,5,7].
sum_by_pairs([Head|Tail]) ->
    sum_by_pairs(Head, Tail).
sum_by_pairs(_, []) ->
    [];
sum_by_pairs(Head, [TailFirst|Rest]) ->
    [case Head+TailFirst<10 of
	 true -> Head + TailFirst;
	 false -> Head + TailFirst - 9 end] ++ sum_by_pairs([TailFirst|Rest]).
    
%% Counts value for a single name pair.

count_one([]) ->
    0;
count_one([_]) ->
    0;
count_one([Head, Tail]) ->
    Head * 10 + Tail;
count_one([Head|Tail]) ->
    count_one(sum_by_pairs([Head|Tail])).

%% Counts all the values for a the first name on the list.
count_for_one(_, []) ->
    [];
count_for_one(Head, [Second|Rest]) ->
    V = [count_one(lists:zipwith(fun(X,Y) -> X + Y end, Head, Second))],
    V ++ count_for_one(Head, Rest).

%% Goes through all the name combinations.
count_for_all([]) ->
    [];
count_for_all([Head|Tail]) ->
    [count_for_one(Head, Tail)] ++ count_for_all(Tail).

%%%%
%% Main logic
%%%%

%% Calculate how many of the pairs have a percentage greater or equal to Filt.
get_count(Filt, Chs, Lst) ->
    Char_counts = count(Chs, Lst),
    V = lists:filter(fun(X) -> X >= Filt end, lists:flatten([X || X <- count_for_all(Char_counts)])),
    length(V).

main() ->
    R = get_count(99, "pairs", readlines("nimet.txt")),
    io:fwrite("~w~n", [R]).


%%%%
%% File management
%%%%

%% Open a file and return a list of all of the lines in it 
%% in a list.
readlines(Filename) ->
    {ok, Device} = file:open(Filename, [read]),
    get_all_lines(Device, []).

get_all_lines(Device, Accum) ->
    case io:get_line(Device, "") of
	eof -> file:close(Device), Accum;
	Line -> get_all_lines(Device, Accum ++ [Line])
    end.