Day 5

The problem asks us to convert a binary representation of the row number and seat number into its actual number. We can choose to over represent the data as follows.

data Row = F | B
data Seat = L | R
data BoardingPass = BoardingPass [Row] [Seat]

class BS a where
  bs :: a -> Bool

instance Read Row where
  readPrec =
    get >>= \case
      'F' -> pure F
      'B' -> pure B
      _   -> pfail

instance Read Seat where
  readPrec =
    get >>= \case
      'L' -> pure L
      'R' -> pure R
      _   -> pfail

instance BS Row where
  bs F = False
  bs B = True

instance BS Seat where
  bs L = False
  bs R = True

instance Read BoardingPass where
  readPrec = BoardingPass <$> many readPrec <*> many readPrec

search :: BS a => [a] -> Int
search = foldl' (\a b-> 2 * a + b) 0 . fmap (fromEnum . bs)

The reason for using this BS typeclass is so that the search function may be more correct. If search had the type Enum a => [a] -> Int it would not make much sense for [a] to be representing bits.

The search function is just your standard function for converting a bit array into a binary integer. We can just ask for maximum ids for part A. For part B, though, we can take advantage that there are only around 1000 ids so we can find the missing id with sum [minimum ids .. maximum ids] - sum ids.