chars_digits([], []). chars_digits([A|As], [B|Bs]) :- char_type(A, digit(B)), chars_digits(As, Bs). read_file(Stream, []) :- at_end_of_stream(Stream). read_file(Stream, [X|Xs]) :- \+ at_end_of_stream(Stream), read_line_to_codes(Stream, C), chars_digits(C, X), read_file(Stream, Xs). main :- open('../input/09', read, Stream), read_file(Stream, Lines), !, close(Stream), low_points(Lines, Res), point_sum(Lines, Res, N), print(N). %print(Res). point_sum(_, [], 0). point_sum(A, [[X, Y]|Ps], S) :- point_sum(A, Ps, S0), nth0(Y, A, Row), nth0(X, Row, P), S is S0 + P + 1. low_point([[A,B|_]|[[C|_]|_]], 0, 0) :- A < B, A < C. low_point([A|As], X, 0) :- X > 0, nth0(X, A, R0), X0 is X - 1, X1 is X + 1, nth0(X0, A, R1), R0 < R1, ( (length(A, X1), length([A|As], 1)); (length([A|As], 1), nth0(X1, A, R2), R0 < R2); (length(A, X1), nth0(1, [A|As], E), nth0(X, E, E0), R0 < E0); (nth0(X1, A, R2), R0 < R2, nth0(1, [A|As], E), nth0(X, E, E0), R0 < E0) ). low_point(A, 0, Y) :- Y > 0, nth0(Y, A, [R0,R1|_]), R0 < R1, Y0 is Y - 1, Y1 is Y + 1, nth0(Y0, A, [T0|_]), R0 < T0, ( length(A, Y1); (nth0(Y1, A, [E0|_]), R0 < E0) ). low_point(A, X, Y) :- Y > 0, X > 0, nth0(Y, A, R), nth0(X, R, R0), X0 is X - 1, Y0 is Y - 1, X1 is X + 1, Y1 is Y + 1, nth0(X0, R, R1), R0 < R1, nth0(Y0, A, E), nth0(X, E, E0), R0 < E0, ( (length(A, Y1), length(R, X1)); (length(A, Y1), nth0(X1, R, R2), R0 < R2); (length(R, X1), nth0(Y1, A, T), nth0(X, T, T0), R0 < T0); (nth0(X1, R, R2), R0 < R2, nth0(Y1, A, T), nth0(X, T, T0), R0 < T0) ). low_points([A|As], Ret) :- length([A|As], Y), length(A, X), X0 is X - 1, Y0 is Y - 1, low_points([A|As], X0, Y0, Ret). low_points(A, 0, 0, [[0, 0]]) :- low_point(A, 0, 0). low_points(A, 0, 0, []) :- \+ low_point(A, 0, 0). low_points(A, X, Y, [[X, Y]|Rs]) :- X > 0, low_point(A, X, Y), X0 is X - 1, low_points(A, X0, Y, Rs). low_points(A, X, Y, Rs) :- X > 0, \+ low_point(A, X, Y), X0 is X - 1, low_points(A, X0, Y, Rs). low_points([A|As], 0, Y, [[0, Y]|Rs]) :- Y > 0, length(A, Len), low_point([A|As], 0, Y), Y0 is Y - 1, X0 is Len - 1, low_points([A|As], X0, Y0, Rs). low_points([A|As], 0, Y, Rs) :- Y > 0, length(A, Len), \+ low_point([A|As], 0, Y), Y0 is Y - 1, X0 is Len - 1, low_points([A|As], X0, Y0, Rs).