adamcrussell (adamcrussell) wrote,
adamcrussell
adamcrussell

2020 Advent Of Code Day 5

Prolog. Developed and tested with SWI-Prolog 8.0.3.

check_and_read(10, [] ,_):- 
    !.
check_and_read(13, [], _):-
    !.
check_and_read(32, [], _):-
    !.
check_and_read(end_of_file, [], _):-
    !.
check_and_read(Char, [Char|Chars], Stream):-
    get_code(Stream, NextChar),
    check_and_read(NextChar, Chars, Stream).

read_data(Stream, []):-
    at_end_of_stream(Stream).
read_data(Stream, [X|L]):-
    \+ at_end_of_stream(Stream),
    get_code(Stream, Char),
    check_and_read(Char, Chars, Stream),
    atom_codes(X, Chars),
    read_data(Stream, L).

compute_pass(X, Y, Z, Last, F, _, ProcessedPass):-
    Last == 70,
    compute_column([X, Y, Z], [L, R]),
    ((
         Z == 76,
         ProcessedPass is F * 8 + L
     );
     (
         Z  == 82,
         ProcessedPass is F * 8 + R
    )).
compute_pass(X, Y, Z, Last, _, B, ProcessedPass):-
    Last == 66,
    compute_column([X, Y, Z], [L, R]),
    ((
         Z == 76,
         ProcessedPass is B * 8 + L
     );
     (
         Z == 82,
         ProcessedPass is B * 8 + R
    )).  

compute_column(LR, Column):-
    compute_column(LR, [0, 7], Column).
compute_column([], Column, Column).
compute_column([H|T], [L, R], Column):-
    H == 76,
    Delta is R - L,
    DeltaHalf is div(Delta, 2),
    R0 is L + DeltaHalf,
    compute_column(T, [L, R0], Column).
compute_column([H|T], [L, R], Column):-
    H == 82,
    Delta is R - L,
    DeltaHalf is div(Delta, 2),
    L0 is L + DeltaHalf + 1,
    compute_column(T, [L0, R], Column). 
    
process_pass(Pass, ProcessedPass):-
    process_pass(Pass, [0, 127], ProcessedPass).
process_pass([], ProcessedPass, ProcessedPass).
process_pass([H|T], [F, B], ProcessedPass):-
    H == 70,
    Delta is B - F,
    DeltaHalf is div(Delta, 2),
    B0 is F + DeltaHalf,
    process_pass(T, [F, B0], ProcessedPass).
process_pass([H|T], [F, B], ProcessedPass):-
    H == 66,
    Delta is B - F,
    DeltaHalf is div(Delta, 2),
    F0 is F + DeltaHalf + 1,
    process_pass(T, [F0, B], ProcessedPass). 

process_passes(Passes, ProcessedPasses):-
    process_passes(Passes, [], ProcessedPasses).
process_passes([], ProcessedPasses, ProcessedPasses).
process_passes([H|T], ProcessedAccum, ProcessedPasses):-
    atom_codes(H, [C0, C1, C2, C3, C4, C5, C6, C7, C8, C9]),
    process_pass([C0, C1, C2, C3, C4, C5, C6], [F, B]),
    append([C6], [F, B], [Last, F, B]),
    compute_pass(C7, C8, C9, Last, F, B, ProcessedPass),
    process_passes(T, [ProcessedPass|ProcessedAccum], ProcessedPasses).

seat(Seats, Seat):-
    member(S0, Seats),
    S1 is S0 + 2,
    member(S1, Seats),
    Seat is S0 + 1,
    \+ member(Seat, Seats).

main:-
    open('data', read, Stream),
    read_data(Stream, Records),
    close(Stream),
    process_passes(Records, Processed),
    sort(Processed, Sorted),
    append(_, [Last], Sorted),
    format("Highest seat ID is ~d.~n", [Last]),
    seat(Sorted, Seat),
    format("Seat ID is ~d.~n", [Seat]).
Tags: advent of code, logic programming, prolog, prolog programming
Subscribe

Recent Posts from This Journal

Comments for this post were disabled by the author