Day 5
2020-01-24
This problem really suits logic programming. Decoding the binary-encoded seat pass was straightforward. I enjoyed how simple it is to define the search as a series of rules. I’ve gotten the hang of adding predicates as embedded unit tests in the code. I don’t think I’ll ever use Prolog in a production environment, so I can live with the inefficiencies of this since it’s so easy to test. I can just run true.
in the query window to evaluate whether these tests pass.
Solution
search([], _, _, R, R, R).
% Lower Character, Upper Character, Lower bound, Upper bound
search([X|Xs], LC, UC, L, U, ID):-
X = LC,
U2 is L + ((U - L) // 2),
search(Xs, LC, UC, L, U2, ID).
search([X|Xs], LC, UC, L, U, ID):-
X = UC,
L2 is L + ((U - L) // 2) + 1,
search(Xs, LC, UC, L2, U, ID).
:- string_chars("RRR", X), search(X, 'L', 'R', 0, 7, 7).
:- string_chars("RLL", X), search(X, 'L', 'R', 0, 7, 4).
:- string_chars("LLL", X), search(X, 'L', 'R', 0, 7, 0).
searchRow(X, ID):- search(X, 'F', 'B', 0, 127, ID).
searchColumn(X, ID):- search(X, 'L', 'R', 0, 7, ID).
decode(Pass, Seat):-
string_chars(Pass, X),
append(RowData, ColData, X),
length(ColData, 3),
searchRow(RowData, Row),
searchColumn(ColData, Col),
Seat is Row * 8 + Col.
:- decode("BFFFBBFRRR", 567).
:- decode("FFFBBBFRRR", 119).
:- decode("BBFFBBFRLL", 820).
main(Input, Output):-
split_string(Input, '\n', '\n', Lines),
maplist(decode, Lines, Decoded),
max_list(Decoded, Output).
findSeat([A, B|_], Y):-
B is A + 2,
Y is A + 1.
findSeat([A, B|Xs], Y):-
B is A + 1,
findSeat([B|Xs], Y).
:- findSeat([1, 3], 2).
:- findSeat([1, 2, 4], 3).
main2(Input, Output):-
split_string(Input, '\n', '\n', Lines),
maplist(decode, Lines, Decoded),
sort(Decoded, Sorted),
findSeat(Sorted, Output).