{-# Language TemplateHaskell, QuasiQuotes #-}
{-|
Module      : Main
Description : Day 5 solution
Copyright   : (c) Eric Mertens, 2020
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2020/day/5>

-}
module Main (main) where

import Advent (format, stageTH)
import Data.List (sort)

data H = HL | HR | HF | HB

stageTH

-- |
-- >>> :main
-- 951
-- 653
main :: IO ()
IO ()
main =
  do [[H]]
inp <- [format|2020 5 (@H*%n)*|]
     let seatIds :: [Int]
seatIds = ([H] -> Int) -> [[H]] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map [H] -> Int
seatId [[H]]
inp
     Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Int]
seatIds)
     Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
gap ([Int] -> [Int]
forall a. Ord a => [a] -> [a]
sort [Int]
seatIds))

gap :: [Int] -> Int
gap :: [Int] -> Int
gap (Int
x:Int
y:[Int]
_) | Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y = Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1
gap (Int
_:[Int]
xs) = [Int] -> Int
gap [Int]
xs
gap [] = String -> Int
forall a. HasCallStack => String -> a
error String
"couldn't find a gap"

seatId :: [H] -> Int
seatId :: [H] -> Int
seatId [H]
xs = let (Int
r,Int
c) = [H] -> (Int, Int)
seat [H]
xs in Int
8Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
c

seat :: [H] -> (Int,Int)
seat :: [H] -> (Int, Int)
seat = ((Int, Int) -> H -> (Int, Int)) -> (Int, Int) -> [H] -> (Int, Int)
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Int, Int) -> H -> (Int, Int)
forall {b} {a}. (Num b, Num a) => (a, b) -> H -> (a, b)
f (Int
0,Int
0)
  where
    f :: (a, b) -> H -> (a, b)
f (a
r,b
c) H
HL = (a
r,b
2b -> b -> b
forall a. Num a => a -> a -> a
*b
c  )
    f (a
r,b
c) H
HR = (a
r,b
2b -> b -> b
forall a. Num a => a -> a -> a
*b
cb -> b -> b
forall a. Num a => a -> a -> a
+b
1)
    f (a
r,b
c) H
HF = (a
2a -> a -> a
forall a. Num a => a -> a -> a
*a
r  ,b
c)
    f (a
r,b
c) H
HB = (a
2a -> a -> a
forall a. Num a => a -> a -> a
*a
ra -> a -> a
forall a. Num a => a -> a -> a
+a
1,b
c)