day4
This commit is contained in:
parent
b1bc7ef4b6
commit
3c76445fcc
2 changed files with 56 additions and 0 deletions
2
aoc.m
2
aoc.m
|
@ -35,6 +35,8 @@ solution(1, day1.run).
|
||||||
solution(2, day2.run).
|
solution(2, day2.run).
|
||||||
:- import_module day3.
|
:- import_module day3.
|
||||||
solution(3, day3.run).
|
solution(3, day3.run).
|
||||||
|
:- import_module day4.
|
||||||
|
solution(4, day4.run).
|
||||||
|
|
||||||
:- pred run_day(int, part, list(string), univ).
|
:- pred run_day(int, part, list(string), univ).
|
||||||
:- mode run_day(in, in, in, out) is cc_multi.
|
:- mode run_day(in, in, in, out) is cc_multi.
|
||||||
|
|
54
day4.m
Normal file
54
day4.m
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
:- module day4.
|
||||||
|
:- 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.
|
||||||
|
|
||||||
|
:- type ranges ---> r(int, int, int, int).
|
||||||
|
|
||||||
|
:- pred number(int::out, chars::in, chars::out) is semidet.
|
||||||
|
number(N) --> digits(S), {to_int(from_char_list(S), N)}.
|
||||||
|
|
||||||
|
:- pred digits(chars::out, chars::in, chars::out) is semidet.
|
||||||
|
digits([C | Cs]) -->
|
||||||
|
[C], {is_digit(C)},
|
||||||
|
(if digits(Cs2) then {Cs = Cs2} else {Cs = []}).
|
||||||
|
|
||||||
|
|
||||||
|
:- pred int_pair(int::out, int::out, chars::in, chars::out) is semidet.
|
||||||
|
int_pair(A, B) --> number(A), ['-'], number(B).
|
||||||
|
|
||||||
|
:- pred ranges(ranges::out, chars::in, chars::out) is semidet.
|
||||||
|
ranges(r(A, B, C, D)) --> int_pair(A, B), [','], int_pair(C, D).
|
||||||
|
|
||||||
|
:- pred ranges(string::in, ranges::out) is det.
|
||||||
|
ranges(Str, R) :-
|
||||||
|
if ranges(R2, to_char_list(Str), []) then R = R2
|
||||||
|
else die("invalid line: ""%s""", [s(Str)]).
|
||||||
|
|
||||||
|
|
||||||
|
:- pred all_overlap(ranges::in) is semidet.
|
||||||
|
all_overlap(r(A, B, C, D)) :- C >= A, D =< B ; D >= B, C =< A.
|
||||||
|
|
||||||
|
:- pred any_overlap(ranges::in) is semidet.
|
||||||
|
any_overlap(r(A, B, C, D)) :- A =< C, B >= C ; C =< A, D >= A.
|
||||||
|
|
||||||
|
|
||||||
|
:- pred go(pred(ranges)::(pred(in) is semidet),
|
||||||
|
list(string)::in, int::out) is det.
|
||||||
|
go(P, Lines, Out) :-
|
||||||
|
map(ranges, Lines, Ranges),
|
||||||
|
filter(P, Ranges, Overlaps),
|
||||||
|
length(Overlaps, Out).
|
||||||
|
|
||||||
|
|
||||||
|
:- pragma no_determinism_warning(run/3).
|
||||||
|
run(one, Lines, univ(Out)) :- go(all_overlap, Lines, Out).
|
||||||
|
run(two, Lines, univ(Out)) :- go(any_overlap, Lines, Out).
|
Loading…
Reference in a new issue