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
.