Bit more tidying
[advent-of-code-20.git] / advent12 / src / advent12.hs
1 -- import Debug.Trace
2
3 import Data.Text (Text)
4 -- import qualified Data.Text as T
5 import qualified Data.Text.IO as TIO
6
7 import Data.Attoparsec.Text
8 -- import Data.Attoparsec.Combinator
9 -- import Control.Applicative
10
11
12 data Direction = North | East | South | West
13 deriving (Show, Eq, Ord, Enum, Bounded)
14
15 type Position = (Int, Int) -- (x, y)
16
17 data Action a = N a | S a | E a | W a | L a | R a | F a
18 deriving (Show, Eq, Ord)
19
20 -- data Ship = Ship { direction :: Direction, position :: Position }
21 -- deriving (Show, Eq, Ord)
22
23 data Ship = Ship { position :: Position
24 , direction :: Direction
25 , waypoint :: Position
26 }
27 deriving (Show, Eq, Ord)
28
29
30
31 main :: IO ()
32 main =
33 do text <- TIO.readFile "data/advent12.txt"
34 let actions = successfulParse text
35 -- print actions
36 print $ part1 actions
37 print $ part2 actions
38
39
40 part1 actions = manhattan (position ship1) start
41 where start = (0, 0)
42 ship0 = Ship {position = start, direction = East, waypoint = (10, 1)}
43 ship1 = foldl act ship0 actions
44
45 part2 actions = manhattan (position ship1) start
46 where start = (0, 0)
47 ship0 = Ship {position = start, direction = East, waypoint = (10, 1)}
48 ship1 = foldl actW ship0 actions
49
50 -- apAc actions = ship1
51 -- where start = (0, 0)
52 -- ship0 = Ship {position = start, direction = East }
53 -- ship1 = foldl act ship0 actions
54
55 -- apAcW actions = ship1
56 -- where start = (0, 0)
57 -- ship0 = ShipW {positionW = start, waypoint = (10, 1) }
58 -- ship1 = foldl actW ship0 actions
59
60 act :: Ship -> Action Int -> Ship
61 act Ship{..} (N d) = Ship { position = dDelta d North position, ..}
62 act Ship{..} (S d) = Ship { position = dDelta d South position, ..}
63 act Ship{..} (W d) = Ship { position = dDelta d West position, ..}
64 act Ship{..} (E d) = Ship { position = dDelta d East position, ..}
65 act Ship{..} (L a) = Ship { direction = d, ..} where d = (iterate predW direction) !! (a `div` 90)
66 act Ship{..} (R a) = Ship { direction = d, ..} where d = (iterate succW direction) !! (a `div` 90)
67 act Ship{..} (F d) = Ship { position = dDelta d direction position, ..}
68
69
70 actW :: Ship -> Action Int -> Ship
71 actW Ship{..} (N d) = Ship { waypoint = dDelta d North waypoint, ..}
72 actW Ship{..} (S d) = Ship { waypoint = dDelta d South waypoint, ..}
73 actW Ship{..} (W d) = Ship { waypoint = dDelta d West waypoint, ..}
74 actW Ship{..} (E d) = Ship { waypoint = dDelta d East waypoint, ..}
75 actW Ship{..} (L a) = Ship { waypoint = d, ..} where d = (iterate rotL waypoint) !! (a `div` 90)
76 actW Ship{..} (R a) = Ship { waypoint = d, ..} where d = (iterate rotR waypoint) !! (a `div` 90)
77 actW Ship{..} (F d) = Ship { position = p', ..}
78 where (x, y) = position
79 (dx, dy) = waypoint
80 p' = (x + (d * dx), y + (d * dy))
81
82 rotL (x, y) = (-y, x)
83 rotR (x, y) = (y, -x)
84
85 delta North = ( 0, 1)
86 delta South = ( 0, -1)
87 delta East = ( 1, 0)
88 delta West = (-1, 0)
89
90 dDelta dist dir (x, y) = (x + (dist * dx), y + (dist * dy))
91 where (dx, dy) = delta dir
92
93 manhattan (x1, y1) (x2, y2) = abs (x1 - x2) + abs (y1 - y2)
94
95
96 -- | a `succ` that wraps
97 succW :: (Bounded a, Enum a, Eq a) => a -> a
98 succW dir | dir == maxBound = minBound
99 | otherwise = succ dir
100
101 -- | a `pred` that wraps
102 predW :: (Bounded a, Enum a, Eq a) => a -> a
103 predW dir | dir == minBound = maxBound
104 | otherwise = pred dir
105
106 -- Parse the input file
107
108 actionsP = actionP `sepBy` endOfLine
109
110 actionP = choice [nP, sP, eP, wP, lP, rP, fP]
111
112 nP = N <$> ("N" *> decimal)
113 sP = S <$> ("S" *> decimal)
114 eP = E <$> ("E" *> decimal)
115 wP = W <$> ("W" *> decimal)
116 lP = L <$> ("L" *> decimal)
117 rP = R <$> ("R" *> decimal)
118 fP = F <$> ("F" *> decimal)
119
120 successfulParse :: Text -> [Action Int]
121 successfulParse input =
122 case parseOnly actionsP input of
123 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
124 Right actions -> actions