%! SWI-Prolog version 8.3.29 for x86_64-linux
%! swipl -s 04.pl -g "sol1(Ans), writeln(Ans)." -t "halt."
%! swipl -s 04.pl -g "sol2(Ans), writeln(Ans)." -t "halt."

sol1(Answer) :-
  read_file(String),
  parse_file(String, Lines),
  length(Lines, Answer).

read_file(String) :- read_file_to_string("04.txt", String, []).

parse_file(String, Sequences) :-
  split_string(String, "\n", "", Lines),
  include(sat, Lines, Sequences).

parse_range(Start, End, String) :-
  split_string(String, "-", "", [StartStr, EndStr]),
  number_string(Start, StartStr),
  number_string(End, EndStr).

range(Set, Start, End) :- setof(A, between(Start, End, A), Set).

meets(A, _, I) :- =(A, I).
meets(_, B, I) :- =(B, I).

fully_contained(A1, A2, B1, B2) :-
  range(RangeA, A1, A2),
  range(RangeB, B1, B2),
  intersection(RangeA, RangeB, Intersection),
  meets(RangeA, RangeB, Intersection).

sat(Line) :-
  split_string(Line, ",", "", [FirstRange, SecondRange]),
  parse_range(FirstStart, FirstEnd, FirstRange),
  parse_range(SecondStart, SecondEnd, SecondRange),
  fully_contained(FirstStart, FirstEnd, SecondStart, SecondEnd).

%%%%%%%%

sol2(Answer) :-
  read_file(String),
  parse_file2(String, Lines),
  length(Lines, Answer).

parse_file2(String, Sequences) :-
  split_string(String, "\n", "", Lines),
  include(sat2, Lines, Sequences).

partially_contained(A1, A2, B1, B2) :-
  range(RangeA, A1, A2),
  range(RangeB, B1, B2),
  intersection(RangeA, RangeB, Intersection),
  not(Intersection == []).

sat2(Line) :-
  split_string(Line, ",", "", [FirstRange, SecondRange]),
  parse_range(FirstStart, FirstEnd, FirstRange),
  parse_range(SecondStart, SecondEnd, SecondRange),
  partially_contained(FirstStart, FirstEnd, SecondStart, SecondEnd).


%! vim: set ft=prolog :