Skip to content

Instantly share code, notes, and snippets.

@HumanEquivalentUnit
Last active December 2, 2024 00:09
Show Gist options
  • Save HumanEquivalentUnit/264ede23f4f1159f7dc02f2b29196854 to your computer and use it in GitHub Desktop.
Save HumanEquivalentUnit/264ede23f4f1159f7dc02f2b29196854 to your computer and use it in GitHub Desktop.
Advent of Code 2024 Day 01 SWI Prolog
:- set_prolog_flag(double_quotes, codes).
:- use_module(library(dcg/basics)).
:- use_module(library(pio)).
% edit this to your input path
inputPath('C:/inputs/day01.txt').
% A line has two numbers separated by whitespace.
line(Left, Right) -->
number(Left),
whites,
number(Right),
eol. % end of line.
% The arrays are the two numbers from all lines.
arrays([L|Lefts], [R|Rights]) -->
line(L, R),
arrays(Lefts, Rights).
arrays([], []) -->
[], eos. % end of stream.
read_input(Lefts, Rights) :-
inputPath(Path),
once(phrase_from_file(arrays(Lefts, Rights), Path)).
% Part 1: sort, pair giving L-R, abs() evals that as minus, sum.
part1(Answer) :-
read_input(Ls, Rs),
maplist(sort(0, @=<), [Ls, Rs], [Lss, Rss]),
pairs_keys_values(Pairs, Lss, Rss),
maplist(abs, Pairs, Cardinals),
sum_list(Cardinals, Answer).
% Part 2: (sort, clumped) counts occurences in right list.
% helper folds over left list, picking out those counts from right,
% multiply-add into a running total if found, else total unchanged.
part2_fold(RCounts, L, Prev, Next) :-
(memberchk(L-Count, RCounts)
-> Next is Prev + (L * Count)
; Next = Prev).
part2(Answer) :-
read_input(Ls, Rs),
sort(0, @=<, Rs, Rss),
clumped(Rss, RCounts),
foldl(part2_fold(RCounts), Ls, 0, Answer).
%-- run this
go :-
part1(Answer1),
writeln(Answer1),
part2(Answer2),
writeln(Answer2).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment