mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 05:49:52 +01:00
74 lines
2.6 KiB
Haskell
74 lines
2.6 KiB
Haskell
module Y2020.Day12 (y20day12) where
|
|
|
|
data Instruction =
|
|
GoNorth Int |
|
|
GoSouth Int |
|
|
GoWest Int |
|
|
GoEast Int |
|
|
TurnLeft |
|
|
TurnRight |
|
|
TurnAround |
|
|
Forward Int deriving (Show)
|
|
|
|
-- Orientations
|
|
-- Right = 0
|
|
-- Bottom = 1
|
|
-- Left = 2
|
|
-- Top = 3
|
|
data State = State {
|
|
pos :: (Int, Int)
|
|
, turn :: Int
|
|
} deriving (Show)
|
|
|
|
data StateP2 = StateP2 {
|
|
shipPos :: (Int, Int)
|
|
, waypointPos :: (Int, Int)
|
|
} deriving (Show)
|
|
|
|
parseInput :: String -> Instruction
|
|
parseInput ('N':n) = GoNorth (read n)
|
|
parseInput ('S':n) = GoSouth (read n)
|
|
parseInput ('W':n) = GoWest (read n)
|
|
parseInput ('E':n) = GoEast (read n)
|
|
parseInput ('F':n) = Forward (read n)
|
|
parseInput "L90" = TurnLeft
|
|
parseInput "L270" = TurnRight
|
|
parseInput "R90" = TurnRight
|
|
parseInput "R270" = TurnLeft
|
|
parseInput (_:"180") = TurnAround
|
|
parseInput _ = error "Wrong instruction"
|
|
|
|
applyInstruction :: State -> Instruction -> State
|
|
applyInstruction (State (x, y) t) (GoNorth n) = State (x, y + n) t
|
|
applyInstruction (State (x, y) t) (GoSouth n) = State (x, y -n) t
|
|
applyInstruction (State (x, y) t) (GoWest n) = State (x - n, y) t
|
|
applyInstruction (State (x, y) t) (GoEast n) = State (x + n, y) t
|
|
applyInstruction (State p t) TurnRight = State p $ (t + 1) `mod` 4
|
|
applyInstruction (State p t) TurnAround = State p $ (t + 2) `mod` 4
|
|
applyInstruction (State p t) TurnLeft = State p $ (t + 3) `mod` 4
|
|
applyInstruction (State (x, y) t) (Forward n) = State (moveForward t) t
|
|
where moveForward 0 = (x + n, y)
|
|
moveForward 1 = (x, y - n)
|
|
moveForward 2 = (x - n, y)
|
|
moveForward 3 = (x, y + n)
|
|
|
|
applyInstructionP2 :: StateP2 -> Instruction -> StateP2
|
|
applyInstructionP2 (StateP2 sp (x, y)) (GoNorth n) = StateP2 sp (x, y + n)
|
|
applyInstructionP2 (StateP2 sp (x, y)) (GoSouth n) = StateP2 sp (x, y - n)
|
|
applyInstructionP2 (StateP2 sp (x, y)) (GoWest n) = StateP2 sp (x - n, y)
|
|
applyInstructionP2 (StateP2 sp (x, y)) (GoEast n) = StateP2 sp (x + n, y)
|
|
applyInstructionP2 (StateP2 sp (x, y)) TurnLeft = StateP2 sp (-y, x)
|
|
applyInstructionP2 (StateP2 sp (x, y)) TurnRight = StateP2 sp (y, -x)
|
|
applyInstructionP2 (StateP2 sp (x, y)) TurnAround = StateP2 sp (-x, -y)
|
|
applyInstructionP2 (StateP2 (x, y) wp@(x', y')) (Forward n) = StateP2 (x + (n * x'), y + (n * y')) wp
|
|
|
|
y20day12 :: [String] -> (String, String)
|
|
y20day12 input = (part1, part2)
|
|
where part1 = show $ sum $ map abs $ [fst endposP1, snd endposP1]
|
|
part2 = show $ sum $ map abs $ [fst endposP2, snd endposP2]
|
|
start = State (0, 0) 0
|
|
startP2 = StateP2 (0, 0) (10, 1)
|
|
journey = map parseInput input
|
|
(State endposP1 _) = foldl applyInstruction start journey
|
|
(StateP2 endposP2 _) = foldl applyInstructionP2 startP2 journey
|