With some approximation
This commit is contained in:
EEva (JPotier) 2020-12-13 17:33:04 +02:00
parent c15d4ee29d
commit 538fba7063
1 changed files with 39 additions and 9 deletions

View File

@ -33,6 +33,10 @@ data Ship = Ship { position :: V2 Double, orientation :: V2 Double }
ship0 :: Ship
ship0 = Ship (pure 0) (V2 1 0)
-- At first, ship is at (0,0) facing East
ship1 :: Ship
ship1 = Ship (pure 0) (V2 10 1)
-- instance Semigroup Ship
-- where
-- (<>) s1 s2 = Ship (getSum <$> ((Sum <$> (position s1)) <> (Sum <$> (position s2))))
@ -73,20 +77,43 @@ parseIns e = trace ("Unknown instruction: "<>show e) undefined
-- 1 rad = 180/PI deg
-- PI/180 rad = 1 deg
runIns :: Ship -> Instruction -> Ship
runIns s (InsMoveForward n) = s { position = (position s) + (pure n) * (orientation s) }
runIns s (InsMoveNorth n) = s { position = (position s) + (pure n) * V2 0 1 }
runIns s (InsMoveSouth n) = s { position = (position s) + (pure n) * V2 0 (-1) }
runIns s (InsMoveEast n) = s { position = (position s) + (pure n) * V2 1 0 }
runIns s (InsMoveWest n) = s { position = (position s) + (pure n) * V2 (-1) 0 }
runIns s (InsTurnL n) = s { orientation = angle ((unangle (orientation s)) + n * pi / 180) }
runIns s (InsTurnR n) = s { orientation = angle ((unangle (orientation s)) - n * pi / 180) }
runIns1 :: Ship -> Instruction -> Ship
runIns1 s (InsMoveForward n) = s { position = (position s) + (pure n) * (orientation s) }
runIns1 s (InsMoveNorth n) = s { position = (position s) + (pure n) * V2 0 1 }
runIns1 s (InsMoveSouth n) = s { position = (position s) + (pure n) * V2 0 (-1) }
runIns1 s (InsMoveEast n) = s { position = (position s) + (pure n) * V2 1 0 }
runIns1 s (InsMoveWest n) = s { position = (position s) + (pure n) * V2 (-1) 0 }
runIns1 s (InsTurnL n) = s { orientation = angle ((unangle (orientation s)) + n * pi / 180) }
runIns1 s (InsTurnR n) = s { orientation = angle ((unangle (orientation s)) - n * pi / 180) }
manhattanV2 :: (Num a) => V2 a -> a
manhattanV2 (V2 x y) = (abs x) + (abs y)
solvePart1 :: [String] -> Double
solvePart1 = manhattanV2 . position . foldl runIns ship0 . map parseIns
solvePart1 = manhattanV2 . position . foldl runIns1 ship0 . map parseIns
--------------------------------------------------------------------------------
runIns2 :: Ship -> Instruction -> Ship
runIns2 s (InsMoveForward n) = s { position = (position s) + (pure n) * (orientation s) }
runIns2 s (InsMoveNorth n) = s { orientation = (orientation s) + V2 0 n }
runIns2 s (InsMoveSouth n) = s { orientation = (orientation s) + V2 0 (-n) }
runIns2 s (InsMoveEast n) = s { orientation = (orientation s) + V2 n 0 }
runIns2 s (InsMoveWest n) = s { orientation = (orientation s) + V2 (-n) 0 }
runIns2 s (InsTurnL n) = s { orientation = rotV2By (orientation s) n }
runIns2 s (InsTurnR n) = s { orientation = rotV2By (orientation s) (-n) }
rotV2By :: (Num a, Floating a) => V2 a -> a -> V2 a
rotV2By (V2 x1 y1) n = V2 x y
where
x = cos a * x1 - sin a * y1
y = sin a * x1 + cos a * y1
a = n * pi / 180
solvePart2 :: [String] -> Double
solvePart2 = manhattanV2 . position . foldl runIns2 ship1 . map parseIns
main :: IO ()
main = do
@ -98,3 +125,6 @@ main = do
putStrLn ":: Day 12 - Part 1"
pPrint $ solvePart1 exampleData
pPrint $ solvePart1 input
putStrLn ":: Day 12 - Part 2"
pPrint $ solvePart2 exampleData
pPrint $ solvePart2 input