aoc2021/pl/03.2.pl
2021-12-09 01:41:52 +07:00

90 lines
1.8 KiB
Prolog

chars_digits([], []).
chars_digits([C|Cs], [D|Ds]) :-
char_type(C, digit(D)),
chars_digits(Cs, Ds).
read_file(Stream, []) :-
at_end_of_stream(Stream).
read_file(Stream, [X|L]) :-
\+ at_end_of_stream(Stream),
read_line_to_codes(Stream, C),
chars_digits(C, X),
read_file(Stream, L).
main :-
open('../input/03', read, Stream),
read_file(Stream, Lines), !,
close(Stream),
most_solve(Lines, A),
least_solve(Lines, B),
bin_dec(A, A1),
bin_dec(B, B1),
X is A1 * B1,
print([A1, B1, X]).
first_elements([], []).
first_elements([[X|_]|As], [B|Bs]) :-
first_elements(As, Bs),
B is X.
last_elements([], _, []).
last_elements([[X|Xs]|As], X, [Xs|Bs]) :-
last_elements(As, X, Bs).
last_elements([[X|_]|As], F, Bs) :-
F =\= X,
last_elements(As, F, Bs).
freq([], 0, 0).
freq([1|As], Z, O) :-
freq(As, Z, O1),
O is O1 + 1.
freq([0|As], Z, O) :-
freq(As, Z1, O),
Z is Z1 + 1.
most_common(A, 1) :-
freq(A, Z, O),
O >= Z.
most_common(A, 0) :-
freq(A, Z, O),
O < Z.
least_common(A, 0) :-
freq(A, Z, O),
Z > 0,
(O >= Z; O = 0).
least_common(A, 1) :-
freq(A, Z, O),
O > 0,
(O < Z; Z = 0).
first_elem([A|_], A).
most_solve(A, [B]) :-
first_elements(A, F),
most_common(F, B),
first_elem(A, N),
length(N, 1).
most_solve(A, [B|Bs]) :-
first_elements(A, F),
most_common(F, B),
last_elements(A, B, L),
most_solve(L, Bs).
least_solve(A, [B]) :-
first_elements(A, F),
least_common(F, B),
first_elem(A, N),
length(N, 1).
least_solve(A, [B|Bs]) :-
first_elements(A, F),
least_common(F, B),
last_elements(A, B, L),
least_solve(L, Bs).
bin_dec(B, X) :-
bin_dec(B, 0, X).
bin_dec([], X, X).
bin_dec([B|Bs], N, X) :-
M is N * 2 + B,
bin_dec(Bs, M, X).