{-# Language QuasiQuotes, TemplateHaskell, ImportQualifiedPost #-}
module Main where
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Maybe (fromMaybe)
import Advent (format, maximumMaybe, stageTH)
data C = Cinc | Cdec deriving Int -> C -> ShowS
[C] -> ShowS
C -> String
(Int -> C -> ShowS) -> (C -> String) -> ([C] -> ShowS) -> Show C
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> C -> ShowS
showsPrec :: Int -> C -> ShowS
$cshow :: C -> String
show :: C -> String
$cshowList :: [C] -> ShowS
showList :: [C] -> ShowS
Show
data O = O_LT | O_GT | O_BANG_EQ | O_EQ_EQ | O_LT_EQ | O_GT_EQ
stageTH
main :: IO ()
IO ()
main =
do input <- [format|2017 8 (%s @C %d if %s @O %d%n)*|]
let regmaxes = (Map String Int -> Int) -> [Map String Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int)
-> (Map String Int -> Maybe Int) -> Map String Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map String Int -> Maybe Int
forall (f :: * -> *) a. (Foldable f, Ord a) => f a -> Maybe a
maximumMaybe) ((Map String Int
-> (String, C, Int, String, O, Int) -> Map String Int)
-> Map String Int
-> [(String, C, Int, String, O, Int)]
-> [Map String Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Map String Int
-> (String, C, Int, String, O, Int) -> Map String Int
interpret Map String Int
forall a. Monoid a => a
mempty [(String, C, Int, String, O, Int)]
input)
print (last regmaxes)
print (maximum regmaxes)
interpret ::
Map String Int ->
(String, C, Int, String, O, Int) ->
Map String Int
interpret :: Map String Int
-> (String, C, Int, String, O, Int) -> Map String Int
interpret Map String Int
regs (String
r1,C
op1,Int
n1,String
r2,O
op2,Int
n2)
| O -> Int -> Int -> Bool
toCompare O
op2 (Int -> String -> Map String Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
0 String
r2 Map String Int
regs) Int
n2 =
(Maybe Int -> Maybe Int)
-> String -> Map String Int -> Map String Int
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
Map.alter (Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> (Maybe Int -> Int) -> Maybe Int -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. C -> Int -> Int -> Int
toArith C
op1 Int
n1 (Int -> Int) -> (Maybe Int -> Int) -> Maybe Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0) String
r1 Map String Int
regs
| Bool
otherwise = Map String Int
regs
toCompare :: O -> Int -> Int -> Bool
toCompare :: O -> Int -> Int -> Bool
toCompare O
O_LT = (< )
toCompare O
O_GT = (> )
toCompare O
O_GT_EQ = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>=)
toCompare O
O_LT_EQ = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<=)
toCompare O
O_BANG_EQ = Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(/=)
toCompare O
O_EQ_EQ = Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==)
toArith :: C -> Int -> Int -> Int
toArith :: C -> Int -> Int -> Int
toArith C
Cinc = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)
toArith C
Cdec = Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract