Created
September 5, 2015 13:05
-
-
Save egobrain/6f6c23a248d5917da385 to your computer and use it in GitHub Desktop.
Ants fp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -module(ants). | |
| -export([main/1]). | |
| -mode(compile). | |
| readline_iterator(File) -> | |
| fun() -> | |
| case file:read_line(File) of | |
| {ok, Line} -> {ok, Line, readline_iterator(File)}; | |
| eof -> done; | |
| {error, _Reason} = Err -> Err | |
| end | |
| end. | |
| main([Filename]) -> | |
| {ok, File} = file:open(Filename, [read, {encoding,unicode}]), | |
| {ok, DotsP} = re:compile(":", [unicode]), | |
| {ok, RuleP} = re:compile("(?<n>\\d)+(?<rule>.{3})(?<l>.?)", [unicode]), | |
| foreach( | |
| fun(Line) -> | |
| Bin = unicode:characters_to_binary(Line), | |
| [Data, RuleStr] = re:split(Bin, DotsP, [{return, binary}]), | |
| {match, [PositionBin, Rule, Letter]} = | |
| re:run(RuleStr, RuleP, [{capture, [n,rule,l], binary}]), | |
| Position = binary_to_integer(PositionBin), | |
| DataList = [<<Ch/utf8>>||<<Ch/utf8>> <= Data], | |
| LettersI1 = from_list(DataList), | |
| LettersI2 = apply_rule({Position, Rule, Letter}, LettersI1), | |
| InfinitX = fun Loop() -> {ok, <<"Х"/utf8>>, Loop} end, | |
| InfLettersI1 = append(LettersI1, InfinitX), | |
| InfLettersI2 = append(LettersI2, InfinitX), | |
| N = 2, | |
| BothI = zip(by(N, InfLettersI1), by(N, InfLettersI2)), | |
| ResI = dropwhen( | |
| fun({[<<"Х"/utf8>>, <<"Х"/utf8>>], [<<"Х"/utf8>>,<<"Х"/utf8>>]}) -> true; | |
| (_) -> false | |
| end, BothI), | |
| {ok, Res} = fold(fun({A, B}, S) -> metrics(A,B) + S end, 0, ResI), | |
| io:format("~p\n", [Res]) | |
| end, | |
| readline_iterator(File)). | |
| apply_rule({Pos, <<"удл"/utf8>>, _}, I) -> | |
| drop(Pos, I); | |
| apply_rule({Pos, <<"изм"/utf8>>, L}, I) -> | |
| replace(Pos, L, I); | |
| apply_rule({Pos, <<"вст"/utf8>>, L}, I) -> | |
| add(Pos, L, I). | |
| metrics(A, B) -> | |
| case metrics_(A, B) of | |
| {ok, V} -> V; | |
| error -> | |
| case metrics_(B, A) of | |
| {ok, V} -> V; | |
| error -> 100 | |
| end | |
| end. | |
| metrics_(A, A) -> {ok, 0}; | |
| metrics_([<<"К"/utf8>>, <<"Л"/utf8>>], [<<"К"/utf8>>, <<"Х"/utf8>>]) -> {ok, 0}; | |
| metrics_([<<"Л"/utf8>>, <<"К"/utf8>>], [<<"Л"/utf8>>, <<"П"/utf8>>]) -> {ok, 0}; | |
| metrics_([<<"Л"/utf8>>, <<"Л"/utf8>>], [<<"Л"/utf8>>, <<"Х"/utf8>>]) -> {ok, 0}; | |
| metrics_([<<"П"/utf8>>, <<"К"/utf8>>], [<<"П"/utf8>>, <<"П"/utf8>>]) -> {ok, 0}; | |
| metrics_([<<"Х"/utf8>>, <<"К"/utf8>>], [<<"Х"/utf8>>, <<"Л"/utf8>>]) -> {ok, 5}; | |
| metrics_([<<"П"/utf8>>, <<"К"/utf8>>], [<<"К"/utf8>>, <<"П"/utf8>>]) -> {ok, 5}; | |
| metrics_([<<"П"/utf8>>, <<"П"/utf8>>], [<<"К"/utf8>>, <<"П"/utf8>>]) -> {ok, 5}; | |
| metrics_([<<"К"/utf8>>, <<"К"/utf8>>], [<<"Л"/utf8>>, <<"Л"/utf8>>]) -> {ok, 5}; | |
| metrics_([<<"К"/utf8>>, <<"К"/utf8>>], [<<"Л"/utf8>>, <<"Х"/utf8>>]) -> {ok, 5}; | |
| metrics_([<<"П"/utf8>>, <<"Л"/utf8>>], [<<"П"/utf8>>, <<"Х"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"П"/utf8>>, <<"Л"/utf8>>], [<<"К"/utf8>>, <<"Л"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"П"/utf8>>, <<"Л"/utf8>>], [<<"К"/utf8>>, <<"Х"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"П"/utf8>>, <<"Х"/utf8>>], [<<"К"/utf8>>, <<"Л"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"П"/utf8>>, <<"Х"/utf8>>], [<<"К"/utf8>>, <<"Х"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"Х"/utf8>>, <<"П"/utf8>>], [<<"П"/utf8>>, <<"Х"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"Х"/utf8>>, <<"П"/utf8>>], [<<"П"/utf8>>, <<"Л"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"Х"/utf8>>, <<"П"/utf8>>], [<<"К"/utf8>>, <<"Л"/utf8>>]) -> {ok, 25}; | |
| metrics_([<<"Х"/utf8>>, <<"П"/utf8>>], [<<"К"/utf8>>, <<"Х"/utf8>>]) -> {ok, 25}; | |
| metrics_(_, _) -> error. | |
| %% === Iterator ================================================================ | |
| empty() -> fun() -> done end. | |
| from_list(List) -> | |
| Loop = | |
| fun([]) -> done; | |
| ([H|T]) -> {ok, H, from_list(T)} | |
| end, | |
| fun() -> Loop(List) end. | |
| take(N, Iterator) when N > 0 -> | |
| take_(N, [], Iterator). | |
| take_(0, Acc, I) -> {ok, lists:reverse(Acc), I}; | |
| take_(C, Acc, I) -> | |
| case I() of | |
| {ok, Data, Next} -> take_(C-1, [Data|Acc], Next); | |
| done -> {ok, lists:reverse(Acc), empty()}; | |
| {error, _Reason} = Err -> Err | |
| end. | |
| fold(Fun, State, Iterator) -> | |
| case Iterator() of | |
| {ok, Data, Next} -> | |
| fold(Fun, Fun(Data, State), Next); | |
| done -> {ok, State}; | |
| {error, _Reason} = Err -> Err | |
| end. | |
| foreach(Fun, Iterator) -> | |
| case Iterator() of | |
| {ok, Data, Next} -> | |
| _ = Fun(Data), | |
| foreach(Fun, Next); | |
| done -> ok; | |
| {error, _Reason} = Err -> Err | |
| end. | |
| append(Iterator1, Iterator2) -> | |
| fun() -> | |
| case Iterator1() of | |
| {ok, Data, Next} -> {ok, Data, append(Next, Iterator2)}; | |
| done -> Iterator2(); | |
| {error, _Reason} = Err -> Err | |
| end | |
| end. | |
| dropwhen(Fun, Iterator) -> | |
| fun() -> | |
| case Iterator() of | |
| {ok, Data, Next} -> | |
| case Fun(Data) of | |
| true -> done; | |
| false -> {ok, Data, dropwhen(Fun, Next)} | |
| end; | |
| done -> done; | |
| {error, _Reason} = Err -> Err | |
| end | |
| end. | |
| zip(I1, I2) -> | |
| fun() -> | |
| {ok, D1, Next1} = I1(), | |
| {ok, D2, Next2} = I2(), | |
| {ok, {D1, D2}, zip(Next1, Next2)} | |
| end. | |
| by(N, I) -> | |
| fun() -> | |
| case take(N, I) of | |
| {ok, Data, Next} -> | |
| {ok, Data, by(N, Next)}; | |
| Other -> Other | |
| end | |
| end. | |
| drop(N, I) -> | |
| fun() -> | |
| case I() of | |
| {ok, Data, Next} -> | |
| case N =:= 1 of | |
| true -> Next(); | |
| false -> {ok, Data, drop(N-1, Next)} | |
| end; | |
| Other -> Other | |
| end | |
| end. | |
| replace(N, Value, I) -> | |
| fun() -> | |
| case I() of | |
| {ok, Data, Next} -> | |
| case N =:= 1 of | |
| true -> {ok, Value, Next}; | |
| false -> {ok, Data, replace(N-1, Value, Next)} | |
| end; | |
| Other -> Other | |
| end | |
| end. | |
| add(1, Value, I) -> | |
| fun() -> {ok, Value, I} end; | |
| add(N, Value, I) -> | |
| fun() -> | |
| case I() of | |
| {ok, Data, Next} -> | |
| {ok, Data, add(N-1, Value, Next)}; | |
| Other -> Other | |
| end | |
| end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment