-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day11.hs
76 lines (65 loc) · 1.99 KB
/
Day11.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module Day11
( part1
, part2
) where
import Data.HashMap.Lazy as M (HashMap, findWithDefault, insert, keys,
singleton, size)
import Data.List.Split (chunksOf)
import Helpers.Graph (Pos)
import Intcode (Intcode, halted, initialise, runIntcode,
sendInput)
import Linear.V2 (V2 (..))
data State =
State Robot Hull Intcode
type Hull = HashMap Pos Int
type Robot = (Pos, Pos)
left :: Pos -> Pos
left (V2 x y) = V2 y (-x)
right :: Pos -> Pos
right (V2 x y) = V2 (-y) x
move :: State -> Hull
move (State (pos, dir) hull machine)
| halted machine = hull
| otherwise = move . State (newPos, newDir) newHull $ newMachine
where
input = findWithDefault 0 pos hull
(output, newMachine) = runIntcode . sendInput input $ machine
colour = output !! 1
direction = head output
newHull = insert pos colour hull
newDir
| direction == 0 = left dir
| direction == 1 = right dir
newPos = pos + newDir
makeState :: Int -> String -> State
makeState startPos code = State (newDir, newDir) hull machine
where
(firstOutput, machine) = runIntcode . sendInput startPos . initialise $ code
colour = firstOutput !! 1
direction = head firstOutput
hull = singleton (V2 0 0) colour
newDir
| direction == 0 = left (V2 0 (-1))
| direction == 1 = right (V2 0 (-1))
render :: Hull -> String
render hull =
unlines . chunksOf width $
[ charify . findWithDefault 0 (V2 x y) $ hull
| y <- [my .. mY]
, x <- [mx .. mX]
]
where
painted = keys hull
xs = map (\(V2 x _) -> x) painted
ys = map (\(V2 _ y) -> y) painted
mx = minimum xs
mX = maximum xs
my = minimum ys
mY = maximum ys
width = mX - mx + 1
charify 1 = '#'
charify 0 = ' '
part1 :: Bool -> String -> String
part1 _ = show . size . move . makeState 0
part2 :: Bool -> String -> String
part2 _ = render . move . makeState 1