{-# 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
stageTH
main :: IO ()
IO ()
main =
do [(String, C, Int, String, String, Int)]
input <- [format|2017 8 (%s @C %d if %s %s %d%n)*|]
let regmaxes :: [Int]
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, String, Int) -> Map String Int)
-> Map String Int
-> [(String, C, Int, String, String, Int)]
-> [Map String Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Map String Int
-> (String, C, Int, String, String, Int) -> Map String Int
interpret Map String Int
forall a. Monoid a => a
mempty [(String, C, Int, String, String, Int)]
input)
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. HasCallStack => [a] -> a
last [Int]
regmaxes)
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]
regmaxes)
interpret ::
Map String Int ->
(String, C, Int, String, String, Int) ->
Map String Int
interpret :: Map String Int
-> (String, C, Int, String, String, Int) -> Map String Int
interpret Map String Int
regs (String
r1,C
op1,Int
n1,String
r2,String
op2,Int
n2)
| String -> Int -> Int -> Bool
toCompare String
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 ::
String ->
(Int -> Int -> Bool)
toCompare :: String -> Int -> Int -> Bool
toCompare String
"<" = (< )
toCompare String
">" = (> )
toCompare String
">=" = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>=)
toCompare String
"<=" = Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(<=)
toCompare String
"!=" = Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(/=)
toCompare String
"==" = Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==)
toCompare String
name = String -> Int -> Int -> Bool
forall a. HasCallStack => String -> a
error (String
"Bad comparison function: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
name)
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