89 lines
2.2 KiB
Haskell
89 lines
2.2 KiB
Haskell
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
|
|
|
|
module Day14
|
|
( day14_1,
|
|
day14_2,
|
|
)
|
|
where
|
|
|
|
import Data.Char (isDigit)
|
|
import Data.List (nub)
|
|
import Data.List.Split (splitOn)
|
|
|
|
type Position = (Int, Int)
|
|
|
|
type Velocity = (Int, Int)
|
|
|
|
type Robot = (Position, Velocity)
|
|
|
|
readRobot :: String -> Robot
|
|
readRobot s =
|
|
let [ps, vs] = splitOn " " s
|
|
[px, py] = map read . splitOn "," $ filter (\x -> isDigit x || x == ',' || x == '-') ps
|
|
[vx, vy] = map read . splitOn "," $ filter (\x -> isDigit x || x == ',' || x == '-') vs
|
|
in ((px, py), (vx, vy))
|
|
|
|
moveRobot :: Int -> Robot -> Robot
|
|
moveRobot 0 r = r
|
|
moveRobot n r =
|
|
let (px, py) = fst r
|
|
(vx, vy) = snd r
|
|
in moveRobot (n - 1) (((px + vx) `mod` 101, (py + vy) `mod` 103), (vx, vy))
|
|
|
|
moveRobot' :: Robot -> Robot
|
|
moveRobot' r =
|
|
let (px, py) = fst r
|
|
(vx, vy) = snd r
|
|
in (((px + vx) `mod` 101, (py + vy) `mod` 103), (vx, vy))
|
|
|
|
quadrant :: Robot -> Int
|
|
quadrant r
|
|
| fst p `elem` [0 .. 49]
|
|
&& snd p `elem` [0 .. 50] =
|
|
0
|
|
| fst p `elem` [51 .. 100]
|
|
&& snd p `elem` [0 .. 50] =
|
|
1
|
|
| fst p `elem` [0 .. 49]
|
|
&& snd p `elem` [52 .. 102] =
|
|
2
|
|
| fst p `elem` [51 .. 100]
|
|
&& snd p `elem` [52 .. 102] =
|
|
3
|
|
| otherwise = -1
|
|
where
|
|
p = fst r
|
|
|
|
findChristmasTree :: Int -> [Robot] -> Int
|
|
findChristmasTree n rs =
|
|
let rs' = map moveRobot' rs
|
|
positions = map fst rs'
|
|
in if positions == nub positions
|
|
then n
|
|
else findChristmasTree (n + 1) rs'
|
|
|
|
parseInput :: IO [Robot]
|
|
parseInput = do
|
|
contents <- lines <$> readFile "input/day14.txt"
|
|
let robots = map readRobot contents
|
|
return robots
|
|
|
|
day14_1 :: IO ()
|
|
day14_1 = do
|
|
robots <- parseInput
|
|
let robots' = map (moveRobot 100) robots
|
|
firstQ = length $ filter (\r -> quadrant r == 0) robots'
|
|
secondQ = length $ filter (\r -> quadrant r == 1) robots'
|
|
thirdQ = length $ filter (\r -> quadrant r == 2) robots'
|
|
fourthQ = length $ filter (\r -> quadrant r == 3) robots'
|
|
putStrLn $
|
|
"Day 14, Puzzle 1 solution: "
|
|
++ show (firstQ * secondQ * thirdQ * fourthQ)
|
|
|
|
day14_2 :: IO ()
|
|
day14_2 = do
|
|
robots <- parseInput
|
|
putStrLn $
|
|
"Day 14, Puzzle 2 solution: "
|
|
++ show (findChristmasTree 1 robots)
|