{-# Language ImportQualifiedPost, QuasiQuotes #-}
module Main (main) where
import Advent.Format (format)
import Advent.Coord (Coord, turnLeft, turnRight, origin, north, drawPicture)
import Data.Map (Map)
import Data.Map qualified as Map
import Intcode (Effect(..), run, new)
main :: IO ()
IO ()
main =
do [Int]
inp <- [format|2019 11 %d&,%n|]
let start :: Map Coord Int -> Map Coord Int
start = Coord -> Coord -> Effect -> Map Coord Int -> Map Coord Int
robot Coord
origin Coord
north (Machine -> Effect
run ([Int] -> Machine
new [Int]
inp))
run1 :: Map Coord Int
run1 = Map Coord Int -> Map Coord Int
start Map Coord Int
forall k a. Map k a
Map.empty
run2 :: Map Coord Int
run2 = Map Coord Int -> Map Coord Int
start (Coord -> Int -> Map Coord Int
forall k a. k -> a -> Map k a
Map.singleton Coord
origin Int
1)
render :: Map Coord Int -> IO ()
render = String -> IO ()
putStr (String -> IO ())
-> (Map Coord Int -> String) -> Map Coord Int -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Coord Char -> String
drawPicture (Map Coord Char -> String)
-> (Map Coord Int -> Map Coord Char) -> Map Coord Int -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Char) -> Map Coord Int -> Map Coord Char
forall a b. (a -> b) -> Map Coord a -> Map Coord b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Char
paintChar
Int -> IO ()
forall a. Show a => a -> IO ()
print (Map Coord Int -> Int
forall a. Map Coord a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Map Coord Int
run1)
Map Coord Int -> IO ()
render Map Coord Int
run2
robot ::
Coord ->
Coord ->
Effect ->
Map Coord Int ->
Map Coord Int
robot :: Coord -> Coord -> Effect -> Map Coord Int -> Map Coord Int
robot Coord
here Coord
dir Effect
effect Map Coord Int
paint =
case Effect
effect of
Effect
Halt -> Map Coord Int
paint
Input Int -> Effect
f -> Coord -> Coord -> Effect -> Map Coord Int -> Map Coord Int
robot Coord
here Coord
dir Effect
effect' Map Coord Int
paint
where
color :: Int
color = Int -> Coord -> Map Coord Int -> Int
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Int
0 Coord
here Map Coord Int
paint
effect' :: Effect
effect' = Int -> Effect
f Int
color
Output Int
color (Output Int
turn Effect
effect') -> Coord -> Coord -> Effect -> Map Coord Int -> Map Coord Int
robot Coord
here' Coord
dir' Effect
effect' Map Coord Int
paint'
where
paint' :: Map Coord Int
paint' = Coord -> Int -> Map Coord Int -> Map Coord Int
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Coord
here Int
color Map Coord Int
paint
dir' :: Coord
dir' = Int -> Coord -> Coord
turnFn Int
turn Coord
dir
here' :: Coord
here' = Coord
here Coord -> Coord -> Coord
forall a. Num a => a -> a -> a
+ Coord
dir'
Effect
_ -> String -> Map Coord Int
forall a. HasCallStack => String -> a
error String
"Bad program"
turnFn :: Int -> Coord -> Coord
turnFn :: Int -> Coord -> Coord
turnFn Int
0 = Coord -> Coord
turnLeft
turnFn Int
1 = Coord -> Coord
turnRight
turnFn Int
x = String -> Coord -> Coord
forall a. HasCallStack => String -> a
error (String
"Unexpected turn command: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
x)
paintChar :: Int -> Char
paintChar :: Int -> Char
paintChar Int
0 = Char
'░'
paintChar Int
1 = Char
'█'
paintChar Int
x = String -> Char
forall a. HasCallStack => String -> a
error (String
"Unexpected paint color: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
x)