Part 2
With some approximation
This commit is contained in:
parent
c15d4ee29d
commit
538fba7063
1 changed files with 39 additions and 9 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue