aoc23/21/part1.pl
2023-12-20 23:28:45 -08:00

48 lines
1.5 KiB
Prolog

:- use_module(library(pio)).
:- use_module(library(dcg/basics)).
:- initialization(main, main).
main([FileName|_]) :-
input(FileName, Map, Starting),
nsteps(Map, 64, [Starting], Ends), length(Ends, Answer),
write(Answer), nl.
nsteps(Map, N, Starts, Reachables) :-
length(Range, N),
foldl({Map}/[_, SIn, SOut]>>(step(Map, SIn, SOut)), Range, Starts, Reachables).
step(Map, CurrentCells, NextCells) :-
maplist(neighbors(Map), CurrentCells, NeighborsOfCells),
foldl(
[Neighbors, SetIn, SetOut]>>(
list_to_ord_set(Neighbors, NeighborsSet),
ord_union(SetIn, NeighborsSet, SetOut)),
NeighborsOfCells, [], NextCells).
neighbors(Map, X-Y, Neighbors) :-
findall(X1-Y1, neighbor(Map, X-Y, X1-Y1), Neighbors).
neighbor(Map, X-Y, X1-Y1) :-
( X1 is X, Y1 is Y+1; X1 is X, Y1 is Y-1;
X1 is X+1, Y1 is Y; X1 is X-1, Y1 is Y ),
nth0(X1, Map, Row), nth0(Y1, Row, '.').
replace(I, List, E, NewList) :- nth0(I, List, _, R), nth0(I, NewList, E, R).
% input parsing stuff below
input(FileName, Map, StartX-StartY) :-
phrase_from_file(lines(MapS), FileName),
nth0(StartX, MapS, Row), nth0(StartY, Row, s),
select(s, Row, '.', NewRow), replace(StartX, MapS, NewRow, Map).
lines([]) --> eos, !.
lines([Line|Lines]) --> line(Line), lines(Lines).
line([]) --> "\n"; eos.
line([s|Chars]) --> "S", line(Chars).
line(['.'|Chars]) --> ".", line(Chars).
line(['#'|Chars]) --> "#", line(Chars).
% Debug stuff
print(Map) :- maplist([X]>>(atomics_to_string(X, XStr), write(XStr), nl), Map).