1 bb300da9 2025-12-04 lh parse_input(File) :-
2 bb300da9 2025-12-04 lh read_file_to_string(File, Content, []),
3 bb300da9 2025-12-04 lh split_string(Content, "\n", "", Lines0),
4 bb300da9 2025-12-04 lh exclude(=(""), Lines0, Lines),
5 bb300da9 2025-12-04 lh length(Lines, Length),
6 bb300da9 2025-12-04 lh numlist(1, Length, Ys),
7 bb300da9 2025-12-04 lh maplist(assert_line, Lines, Ys).
9 bb300da9 2025-12-04 lh assert_line(Line, Y) :-
10 bb300da9 2025-12-04 lh string_chars(Line, Chars),
11 bb300da9 2025-12-04 lh assert_chars(Chars, 1, Y).
13 bb300da9 2025-12-04 lh assert_chars([], _, _).
14 bb300da9 2025-12-04 lh assert_chars([C|Rest], X, Y) :-
15 bb300da9 2025-12-04 lh assert_field(C, X, Y),
17 bb300da9 2025-12-04 lh assert_chars(Rest, X2, Y).
19 bb300da9 2025-12-04 lh assert_field('@', X, Y) :-
20 bb300da9 2025-12-04 lh assertz(roll(X, Y)).
21 bb300da9 2025-12-04 lh assert_field(_, _, _).
23 bb300da9 2025-12-04 lh forklift_access(X, Y) :-
25 bb300da9 2025-12-04 lh neighbour_count(X, Y, N),
28 bb300da9 2025-12-04 lh neighbour_offset(DX, DY) :-
29 bb300da9 2025-12-04 lh between(-1, 1, DX),
30 bb300da9 2025-12-04 lh between(-1, 1, DY),
31 bb300da9 2025-12-04 lh \+ (DX = 0, DY = 0).
33 bb300da9 2025-12-04 lh has_neighbour(X, Y, DX, DY) :-
34 bb300da9 2025-12-04 lh neighbour_offset(DX, DY),
39 bb300da9 2025-12-04 lh neighbour_count(X, Y, N) :-
40 bb300da9 2025-12-04 lh aggregate_all(count, has_neighbour(X, Y, _, _), N).
43 bb300da9 2025-12-04 lh aggregate_all(count, forklift_access(_, _), N).
45 bb300da9 2025-12-04 lh task2_(C0, Total) :-
46 bb300da9 2025-12-04 lh findall(roll(X, Y), forklift_access(X, Y), List),
47 bb300da9 2025-12-04 lh maplist(retract, List),
48 bb300da9 2025-12-04 lh length(List, C1),
49 bb300da9 2025-12-04 lh C3 is C0 + C1,
51 bb300da9 2025-12-04 lh -> Total is C3
52 bb300da9 2025-12-04 lh ; task2_(C3, Total)
59 bb300da9 2025-12-04 lh parse_input("input/04.txt"),
62 bb300da9 2025-12-04 lh format("~d ~d~n", [Task1, Task2]).