day 4 prolog
This commit is contained in:
parent
211b1f13d8
commit
db07808eb2
135
pl/04.1.pl
Normal file
135
pl/04.1.pl
Normal file
|
@ -0,0 +1,135 @@
|
|||
read_file(Stream, []) :-
|
||||
at_end_of_stream(Stream).
|
||||
read_file(Stream, [X|L]) :-
|
||||
\+ at_end_of_stream(Stream),
|
||||
read_line_to_codes(Stream, C),
|
||||
string_chars(X, C),
|
||||
read_file(Stream, L).
|
||||
|
||||
split1([], [], []).
|
||||
split1([""|As], [], As). % starts with "" -> [], seq end
|
||||
split1([A|As], [A|Bs], X) :-
|
||||
A \= "",
|
||||
split1(As, Bs, X).
|
||||
|
||||
split2([], []).
|
||||
split2([A|As], [B|Bs]) :-
|
||||
split1([A|As], B, C),
|
||||
split2(C, Bs).
|
||||
|
||||
remove_x(_, [], []).
|
||||
remove_x(X, [X|As], Bs) :-
|
||||
remove_x(X, As, Bs).
|
||||
remove_x(X, [A|As], [A|Bs]) :-
|
||||
A \= X,
|
||||
remove_x(X, As, Bs).
|
||||
|
||||
numbers_strings([], []).
|
||||
numbers_strings([A|As], [B|Bs]) :-
|
||||
number_string(A, B),
|
||||
numbers_strings(As, Bs).
|
||||
|
||||
strings_board([], []).
|
||||
strings_board([A|As], [B|Bs]) :-
|
||||
split_string(A, " ", "", C),
|
||||
remove_x("", C, D),
|
||||
numbers_strings(B, D),
|
||||
strings_board(As, Bs).
|
||||
|
||||
stringss_boards([], []).
|
||||
stringss_boards([A|As], [B|Bs]) :-
|
||||
strings_board(A, B),
|
||||
stringss_boards(As, Bs).
|
||||
|
||||
parse_boards(L, A) :-
|
||||
split2(L, B),
|
||||
remove_x([], B, C),
|
||||
stringss_boards(C, A).
|
||||
|
||||
parse_file([X|L], N, B) :-
|
||||
split_string(X, ",", "", A),
|
||||
numbers_strings(N, A),
|
||||
parse_boards(L, B).
|
||||
|
||||
main :-
|
||||
open('../input/04', read, Stream),
|
||||
read_file(Stream, Lines), !,
|
||||
close(Stream),
|
||||
|
||||
parse_file(Lines, A, B),
|
||||
step_first_board_win(A, B, C),
|
||||
print(C).
|
||||
|
||||
mark_nums_row(_, [], []).
|
||||
mark_nums_row(N, [R|Rs], [1|Xs]) :-
|
||||
append([_, [R], _], N),
|
||||
mark_nums_row(N, Rs, Xs).
|
||||
mark_nums_row(N, [R|Rs], [0|Xs]) :-
|
||||
\+ append([_, [R], _], N),
|
||||
mark_nums_row(N, Rs, Xs).
|
||||
|
||||
mark_nums_board(_, [], []).
|
||||
mark_nums_board(N, [B|Bs], [C|Cs]) :-
|
||||
mark_nums_row(N, B, C),
|
||||
mark_nums_board(N, Bs, Cs).
|
||||
|
||||
rows_win([R|Rs]) :-
|
||||
(R = [1,1,1,1,1]; rows_win(Rs)).
|
||||
|
||||
transpose([[]|_], []).
|
||||
transpose(A, [B|Bs]) :-
|
||||
first_column(A, B, C),
|
||||
transpose(C, Bs).
|
||||
|
||||
first_column([], [], []).
|
||||
first_column([[B|C]|As], [B|Bs], [C|Cs]) :-
|
||||
first_column(As, Bs, Cs).
|
||||
|
||||
marked_board_win(B) :-
|
||||
transpose(B, T),
|
||||
(rows_win(B); rows_win(T)).
|
||||
|
||||
unmarked_row_sum([], [], 0).
|
||||
unmarked_row_sum([_|As], [1|Ms], C) :-
|
||||
unmarked_row_sum(As, Ms, C).
|
||||
unmarked_row_sum([A|As], [0|Ms], C) :-
|
||||
unmarked_row_sum(As, Ms, C1),
|
||||
C is A + C1.
|
||||
|
||||
unmarked_board_sum([], [], 0).
|
||||
unmarked_board_sum([A|As], [B|Bs], C) :-
|
||||
unmarked_row_sum(A, B, C1),
|
||||
unmarked_board_sum(As, Bs, C2),
|
||||
C is C1 + C2.
|
||||
|
||||
last_num([R], R).
|
||||
last_num([_|Rs], X) :-
|
||||
last_num(Rs, X).
|
||||
|
||||
board_win(N, B, X) :-
|
||||
mark_nums_board(N, B, C),
|
||||
marked_board_win(C),
|
||||
unmarked_board_sum(B, C, Z),
|
||||
last_num(N, Y),
|
||||
X is Y * Z.
|
||||
|
||||
first_board_win(N, [B|_], C) :-
|
||||
board_win(N, B, C).
|
||||
|
||||
first_board_win(N, [B|Bs], C) :-
|
||||
\+ board_win(N, B, _),
|
||||
first_board_win(N, Bs, C).
|
||||
|
||||
step_first_board_win([A|As], [], B, C) :-
|
||||
step_first_board_win(As, [A], B, C).
|
||||
step_first_board_win([_|_], [N|Ns], B, C) :-
|
||||
first_board_win([N|Ns], B, C).
|
||||
step_first_board_win([A|As], [N|Ns], B, C) :-
|
||||
\+ first_board_win([N|Ns], B, _),
|
||||
append([N|Ns], [A], D),
|
||||
step_first_board_win(As, D, B, C).
|
||||
step_first_board_win([], N, B, C) :-
|
||||
first_board_win(N, B, C).
|
||||
|
||||
step_first_board_win(N, B, C) :-
|
||||
step_first_board_win(N, [], B, C).
|
141
pl/04.2.pl
Normal file
141
pl/04.2.pl
Normal file
|
@ -0,0 +1,141 @@
|
|||
read_file(Stream, []) :-
|
||||
at_end_of_stream(Stream).
|
||||
read_file(Stream, [X|L]) :-
|
||||
\+ at_end_of_stream(Stream),
|
||||
read_line_to_codes(Stream, C),
|
||||
string_chars(X, C),
|
||||
read_file(Stream, L).
|
||||
|
||||
split1([], [], []).
|
||||
split1([""|As], [], As). % starts with "" -> [], seq end
|
||||
split1([A|As], [A|Bs], X) :-
|
||||
A \= "",
|
||||
split1(As, Bs, X).
|
||||
|
||||
split2([], []).
|
||||
split2([A|As], [B|Bs]) :-
|
||||
split1([A|As], B, C),
|
||||
split2(C, Bs).
|
||||
|
||||
remove_x(_, [], []).
|
||||
remove_x(X, [X|As], Bs) :-
|
||||
remove_x(X, As, Bs).
|
||||
remove_x(X, [A|As], [A|Bs]) :-
|
||||
A \= X,
|
||||
remove_x(X, As, Bs).
|
||||
|
||||
numbers_strings([], []).
|
||||
numbers_strings([A|As], [B|Bs]) :-
|
||||
number_string(A, B),
|
||||
numbers_strings(As, Bs).
|
||||
|
||||
strings_board([], []).
|
||||
strings_board([A|As], [B|Bs]) :-
|
||||
split_string(A, " ", "", C),
|
||||
remove_x("", C, D),
|
||||
numbers_strings(B, D),
|
||||
strings_board(As, Bs).
|
||||
|
||||
stringss_boards([], []).
|
||||
stringss_boards([A|As], [B|Bs]) :-
|
||||
strings_board(A, B),
|
||||
stringss_boards(As, Bs).
|
||||
|
||||
parse_boards(L, A) :-
|
||||
split2(L, B),
|
||||
remove_x([], B, C),
|
||||
stringss_boards(C, A).
|
||||
|
||||
parse_file([X|L], N, B) :-
|
||||
split_string(X, ",", "", A),
|
||||
numbers_strings(N, A),
|
||||
parse_boards(L, B).
|
||||
|
||||
main :-
|
||||
open('../input/04', read, Stream),
|
||||
read_file(Stream, Lines), !,
|
||||
close(Stream),
|
||||
|
||||
parse_file(Lines, A, B),
|
||||
solve(A, B, C),
|
||||
print(C).
|
||||
|
||||
mark_nums_row(_, [], []).
|
||||
mark_nums_row(N, [R|Rs], [1|Xs]) :-
|
||||
append([_, [R], _], N),
|
||||
mark_nums_row(N, Rs, Xs).
|
||||
mark_nums_row(N, [R|Rs], [0|Xs]) :-
|
||||
\+ append([_, [R], _], N),
|
||||
mark_nums_row(N, Rs, Xs).
|
||||
|
||||
mark_nums_board(_, [], []).
|
||||
mark_nums_board(N, [B|Bs], [C|Cs]) :-
|
||||
mark_nums_row(N, B, C),
|
||||
mark_nums_board(N, Bs, Cs).
|
||||
|
||||
rows_win([R|Rs]) :-
|
||||
(R = [1,1,1,1,1]; rows_win(Rs)).
|
||||
|
||||
transpose([[]|_], []).
|
||||
transpose(A, [B|Bs]) :-
|
||||
first_column(A, B, C),
|
||||
transpose(C, Bs).
|
||||
|
||||
first_column([], [], []).
|
||||
first_column([[B|C]|As], [B|Bs], [C|Cs]) :-
|
||||
first_column(As, Bs, Cs).
|
||||
|
||||
marked_board_win(B) :-
|
||||
rows_win(B).
|
||||
marked_board_win(B) :-
|
||||
transpose(B, T),
|
||||
rows_win(T).
|
||||
|
||||
unmarked_row_sum([], [], 0).
|
||||
unmarked_row_sum([_|As], [1|Ms], C) :-
|
||||
unmarked_row_sum(As, Ms, C).
|
||||
unmarked_row_sum([A|As], [0|Ms], C) :-
|
||||
unmarked_row_sum(As, Ms, C1),
|
||||
C is A + C1.
|
||||
|
||||
unmarked_board_sum([], [], 0).
|
||||
unmarked_board_sum([A|As], [B|Bs], C) :-
|
||||
unmarked_row_sum(A, B, C1),
|
||||
unmarked_board_sum(As, Bs, C2),
|
||||
C is C1 + C2.
|
||||
|
||||
last_num([R], R).
|
||||
last_num([_|Rs], X) :-
|
||||
last_num(Rs, X).
|
||||
|
||||
board_win(N, B, X) :-
|
||||
mark_nums_board(N, B, C),
|
||||
marked_board_win(C),
|
||||
unmarked_board_sum(B, C, Z),
|
||||
last_num(N, Y),
|
||||
X is Y * Z.
|
||||
|
||||
win_order(_, [], [], []).
|
||||
win_order(N, [B|Bs], C, [B|Rs]) :-
|
||||
\+ board_win(N, B, _),
|
||||
win_order(N, Bs, C, Rs).
|
||||
win_order(N, [B|Bs], [C|Cs], R) :-
|
||||
board_win(N, B, C),
|
||||
win_order(N, Bs, Cs, R).
|
||||
|
||||
step_win_order(N, B, C) :-
|
||||
step_win_order(N, [], B, C).
|
||||
step_win_order(_, _, [], []).
|
||||
step_win_order([A|As], [], B, C) :-
|
||||
step_win_order(As, [A], B, C).
|
||||
step_win_order([A|As], [N|Ns], B, C) :-
|
||||
win_order([N|Ns], B, C0, R),
|
||||
append([N|Ns], [A], D),
|
||||
step_win_order(As, D, R, C1),
|
||||
append(C0, C1, C).
|
||||
step_win_order([], N, B, C) :-
|
||||
win_order(N, B, C, _).
|
||||
|
||||
solve(N, B, C) :-
|
||||
step_win_order(N, B, D),
|
||||
last_num(D, C).
|
Loading…
Reference in a new issue