day 3
This commit is contained in:
parent
601ade63d1
commit
d5b2222586
6 changed files with 78 additions and 11 deletions
59
day3.m
Normal file
59
day3.m
Normal file
|
@ -0,0 +1,59 @@
|
|||
:- module day3.
|
||||
:- interface.
|
||||
:- import_module basics.
|
||||
:- import_module list.
|
||||
:- import_module univ.
|
||||
|
||||
:- pred run(part::in, list(string)::in, univ::out) is cc_multi.
|
||||
|
||||
:- implementation.
|
||||
:- import_module int.
|
||||
:- import_module char.
|
||||
:- import_module string.
|
||||
:- import_module exception.
|
||||
|
||||
:- pred split(chars::in, chars::out, chars::out) is semidet.
|
||||
split(X, L, H) :-
|
||||
Len = length(X), even(Len),
|
||||
split_list(Len / 2, X, L, H).
|
||||
|
||||
:- pred common(list(chars)::in, char::out) is nondet.
|
||||
common([S | Ss], C) :- member(C, S), (Ss = [] ; common(Ss, C)).
|
||||
|
||||
:- func score(char) = int.
|
||||
score(C) = I :-
|
||||
if is_lower(C) then
|
||||
I = to_int(C) - to_int('a') + 1
|
||||
else
|
||||
I = to_int(C) - to_int('A') + 27.
|
||||
|
||||
:- pred threes(list(T)::in, list(list(T))::out) is semidet.
|
||||
threes([], []).
|
||||
threes([X, Y, Z | Rest], [[X, Y, Z] | Groups]) :- threes(Rest, Groups).
|
||||
|
||||
|
||||
:- pred go1(string::in, int::out) is cc_multi.
|
||||
go1(Line, Out) :-
|
||||
if split(to_char_list(Line), Fst, Snd),
|
||||
common([Fst, Snd], C)
|
||||
then
|
||||
Out = score(C)
|
||||
else
|
||||
die("invalid line: ""%s""", [s(Line)]).
|
||||
|
||||
|
||||
:- pred go2(list(string)::in, int::out) is cc_multi.
|
||||
go2(Lines, Score) :-
|
||||
if common(map(to_char_list, Lines), C) then
|
||||
Score = score(C)
|
||||
else
|
||||
die("no item in common").
|
||||
|
||||
|
||||
run(one, Lines, univ(sum(Scores))) :-
|
||||
map(go1, Lines, Scores).
|
||||
run(two, Lines, univ(sum(Scores))) :-
|
||||
if threes(Lines, Groups) then
|
||||
map(go2, Groups, Scores)
|
||||
else
|
||||
die("not a multiple of three lines").
|
Loading…
Add table
Add a link
Reference in a new issue