:- use_module(library(dcg/basics)). :- use_module(library(clpfd)). row([1]) --> "B". row([1|Ls]) --> "B", row(Ls). row([0]) --> "F". row([0|Ls]) --> "F", row(Ls). col([1]) --> "R". col([1|Ls]) --> "R", col(Ls). col([0]) --> "L". col([0|Ls]) --> "L", col(Ls). position([Row,Col]) --> row(Row), col(Col). seating([S]) --> position(S), blanks. seating([S|Seats]) --> position(S), blanks, seating(Seats). restrict(0, L-U0, L-U) :- U #= U0 - ((U0 - L) // 2) - 1. restrict(1, L0-U, L-U) :- L #= L0 + ((U - L0) // 2) + 1. seat([X, Y], Id) :- foldl(restrict, X, 0-127, Row-Row), foldl(restrict, Y, 0-7, Col-Col), Id #= Row * 8 + Col. hole([A, B | _], Missing) :- 2 #= B - A, Missing #= A + 1. hole([_|Seats], Missing) :- hole(Seats, Missing). main(Part1, Part2) :- phrase_from_file(seating(Seating), 'advent_5_inp.txt'), maplist(seat, Seating, Ids), !, max_list(Ids, Part1), sort(Ids, Sorted), hole(Sorted, Part2).