The trick today is to squint and see binary coding for what it is, and decode it as such instead of getting lost in implementation. This post is literate Haskell, and one of the rare where there is no header of imports and extensions.
Seats are numbered from front to back, then left to right,1 so the decoding for instructions is as follows.
toBit :: Char -> Int
'F' = 0
toBit 'B' = 1
toBit 'L' = 0
toBit 'R' = 1 toBit
I can then combine them all to a single seat number.
passToSeat :: String -> Int
= foldl1 (\a b -> 2*a + b) . map toBit passToSeat
And apply it to all tickets in input to find the maximum.
= do
main <- lines <$> readFile "day05.in"
passes let seatIds = map passToSeat passes
print $ maximum seatIds
For part 2, the most reliable way to proceed without doing it by hand is to simply transcribe the statement: I’m looking for a seat number that’s missing with its two neighbors2 being present.
let seatRange = [minimum seatIds..maximum seatIds]
print $ filter (\s -> s + 1 `elem` seatIds
&& s - 1 `elem` seatIds
&& s `notElem` seatIds) seatRange
This concludes today’s solution. See you soon!