AoC/2019/day11/day11.hs

72 lines
1.9 KiB
Haskell
Raw Normal View History

2019-12-12 20:45:35 +01:00
module Main where
2019-12-12 22:06:32 +01:00
import Data.List
2019-12-12 20:45:35 +01:00
import Data.List.Split
import qualified Data.Map.Strict as M
import qualified Data.Vector as V
2019-12-12 22:06:32 +01:00
import Intcode
2019-12-12 20:45:35 +01:00
import Linear.V2
import Control.Lens
2019-12-12 20:45:35 +01:00
data RoboState =
RoboState
{ hull :: M.Map (V2 Int) Integer
, position :: V2 Int
, direction :: V2 Int
2019-12-12 22:06:32 +01:00
}
deriving (Show)
2019-12-12 20:45:35 +01:00
main :: IO ()
main = do
content <- readFile "input"
let program = V.fromList $ concatMap (map read . splitOn ",") (lines content)
let run x =
runIntcode
2019-12-12 22:06:32 +01:00
( TM
{ tape = tapePreprocess program
, pointer = 0
, pointerOffset = 0
, output = []
, input = Just x
, state = Continue
}
, RoboState {hull = M.empty, position = V2 0 0, direction = V2 0 1})
2019-12-12 20:45:35 +01:00
print $ length $ hull $ snd $ run 0
putStrLn $ drawHull $ M.filter (==1) $ hull $ snd $ run 1
2019-12-12 22:06:32 +01:00
drawHull :: M.Map (V2 Int) Integer -> String
drawHull m =
intercalate "\n" $
transpose $
map reverse $
chunksOf
10
2019-12-12 22:06:32 +01:00
[ case M.findWithDefault 0 (V2 x y) m of
1 -> '•'
_ -> ' '
| x <- [(-5) .. 44]
, y <- [(-5) .. 4]
2019-12-12 22:06:32 +01:00
]
2019-12-12 20:45:35 +01:00
runIntcode :: (TuringMachine, RoboState) -> (TuringMachine, RoboState)
2019-12-12 22:06:32 +01:00
runIntcode (tm, rb) =
2019-12-12 20:45:35 +01:00
case state tmNew of
2019-12-12 22:06:32 +01:00
Continue -> runIntcode (tmNew, rb)
AwaitInput -> runIntcode $ updateState (tmNew, rb)
_ -> (tmNew, rb)
2019-12-12 20:45:35 +01:00
where
tmNew = execSteps tm
updateState :: (TuringMachine, RoboState) -> (TuringMachine, RoboState)
updateState (tm, rb) = (tmNew, rbNew)
2019-12-12 22:06:32 +01:00
where
hullNew = M.insert (position rb) (output tm !! 1) (hull rb)
dirNew =
if head (output tm) == 0
then perp $ direction rb
else iterate perp (direction rb) !! 3
posNew = position rb + dirNew
floorNext = M.findWithDefault 0 posNew (hull rb)
rbNew = rb {hull = hullNew, position = posNew, direction = dirNew}
tmNew = tm {input = Just floorNext, output = []}