# 2020 Advent Of Code Day 9

Prolog. Developed and tested with SWI-Prolog 8.0.3.

```check_and_read(10, [] ,_):-
!.
!.
!.
!.
get_code(Stream, NextChar),

at_end_of_stream(Stream).
\+ at_end_of_stream(Stream),
get_code(Stream, Char),
atom_codes(X, Chars),

get_n(N, List, ListN):-
get_n(N, List, 0, [], ListN).
get_n(N, [_|_], N, ListN, ListN).
get_n(N, [H|T], Counter, ListAccum, ListN):-
C is Counter + 1,
get_n(N, T, C, [H|ListAccum], ListN).

check_sum(X, List):-
member(A, List),
member(B, List),
atom_number(A, N0),
atom_number(B, N1),
A \== B,
X is N0 + N1.

check_sum_list(X, List, Sum):-
check_sum_list(X, List, 0, Sum).
check_sum_list(_, [], Sum, Sum).
check_sum_list(X, [H|T], SumAccum, Sum):-
atom_number(H, H0),
S is H0 + SumAccum,
check_sum_list(X, T, S, Sum).

first_not_sum(Records, FirstNotSum):-
get_n(5, Records, Preamble),
first_not_sum(Preamble, 0, 25, Records, [], FirstNotSum).
first_not_sum(_, _, _, _, [-1], _).
first_not_sum(Preamble, Counter, Ignore, [H|T], Seen, FirstNotSum):-
Counter >= Ignore,
C is Counter + 1,
atom_number(H, X),
\+ check_sum(X, Seen),
FirstNotSum is X,
first_not_sum(Preamble, C, Ignore, T, [-1], FirstNotSum).
first_not_sum(Preamble, Counter, Ignore, [H|T], Seen, FirstNotSum):-
Counter < Ignore,
C is Counter + 1,
append(Seen, [H], Seent),
first_not_sum(Preamble, C, Ignore, T, Seent, FirstNotSum).
first_not_sum(Preamble, Counter, Ignore, [H|T], [_|ST], FirstNotSum):-
append(ST, [H], STH),
first_not_sum(Preamble, Counter, Ignore, T, STH, FirstNotSum).

sum_to_missing(Missing, Records, SumToMissing):-
sum_to_missing(Missing, Records, Records, [], SumToMissing).
sum_to_missing(_, [], _, SumToMissing, SumToMissing).
sum_to_missing(Missing, [H|T], Records, SumToMissingAccum, SumToMissing):-
check_sum_list(Missing, SumToMissingAccum, Sum),
Sum < Missing,
append(SumToMissingAccum, [H], S0),
sum_to_missing(Missing, T, Records, S0, SumToMissing).
sum_to_missing(Missing, _, Records, SumToMissingAccum, SumToMissing):-
check_sum_list(Missing, SumToMissingAccum, Sum),
Sum == Missing,
sum_to_missing(Missing, [], Records, SumToMissingAccum, SumToMissing).
sum_to_missing(Missing, [H|T], Records, SumToMissingAccum, SumToMissing):-
check_sum_list(Missing, SumToMissingAccum, Sum),
Sum > Missing,
[_|TAccum] = SumToMissingAccum,
sum_to_missing(Missing, [H|T], Records, TAccum, SumToMissing).

main:-
close(Stream),
first_not_sum(Records, FirstNotSum),
format("The first number not a sum of two previous numbers: ~d.~n",[FirstNotSum]),
sum_to_missing(FirstNotSum, Records, SumToMissing),
sort(SumToMissing, SumToMissingSorted),
[L, S|_] = SumToMissingSorted,
atom_number(S, Smallest),
atom_number(L, Largest),
SmallestLargestSum is Smallest + Largest,
format("The sum of the smallest and largest of the list of numbers that sum to ~d ([~d, ~d]): ~d.~n",[FirstNotSum, Smallest, Largest, SmallestLargestSum]).
```

### Recent Posts from This Journal

• #### A Simple Binary Tree in Perl

This Binary Tree implementation uses Class::Struct and only defines find() and insert() operations, along with a simple print function for…

• #### The Weekly Challenge 127: Conflict Intervals (C++ Solutions)

Part 2 of The Weekly Challenge 127: You are given two sets with unique numbers. Write a script to figure out if they are disjoint. #include

• #### The Weekly Challenge 127: Disjoint Lists (C++ Solutions)

Part 1 of The Weekly Challenge 127: You are given two sets with unique numbers. Write a script to figure out if they are disjoint. #include

Comments for this post were disabled by the author