Skip to content

Commit fb24ab8

Browse files
committed
Day14
1 parent aa25e7f commit fb24ab8

File tree

2 files changed

+569
-0
lines changed

2 files changed

+569
-0
lines changed

Day14.hs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
module Day14 where
2+
3+
import Data.List
4+
import qualified Data.Set as S
5+
import Control.Monad
6+
7+
type Pos = (Int,Int)
8+
data Robot = Robot {pos :: Pos, vel :: Pos}
9+
deriving (Show, Eq, Ord)
10+
11+
parseRobot l = Robot (read $ "(" ++ spos ++ ")") (read $ "(" ++ svel ++ ")")
12+
where [wpos,wvel] = words l
13+
Just spos = stripPrefix "p=" wpos
14+
Just svel = stripPrefix "v=" wvel
15+
16+
slurp = map parseRobot . lines <$> readFile "input-14"
17+
18+
(a,b) <+> (c,d) = (a+c,b+d)
19+
20+
wrap (w,h) (x,y) = (mod x w, mod y h)
21+
22+
tick :: (Int,Int) -> Robot -> Robot
23+
tick (w,h) (Robot p v) = Robot (wrap (w,h) $ p <+> v) v
24+
25+
quadrant :: (Int,Int) -> Pos -> Int
26+
quadrant (w,h) (x,y)
27+
| x < xmid && y < ymid = 1
28+
| x < xmid && y > ymid = 2
29+
| x > xmid && y < ymid = 3
30+
| x > xmid && y > ymid = 4
31+
| otherwise = 0
32+
where xmid = div w 2
33+
ymid = div h 2
34+
35+
bigLimits = (101,103)
36+
37+
safetyScore :: (Int,Int) -> [Robot] -> Int
38+
safetyScore limits rs = product [ length [ r | r <- rs, quadrant limits (pos r) == q ]
39+
| q <- [1..4] ]
40+
41+
part1 inp = safetyScore bigLimits $ iterate (map (tick bigLimits)) inp !! 100
42+
43+
heuristic1 rs = abs (left-right)
44+
where left = length $ filter ((`elem` [1,2]).quadrant bigLimits.pos) rs
45+
right = length $ filter ((`elem` [3,4]).quadrant bigLimits.pos) rs
46+
47+
heuristic2 rs = length rs - S.size (S.fromList (map pos rs))
48+
49+
heuristic = heuristic2
50+
51+
visualize :: (Int,Int) -> [Robot] -> IO ()
52+
visualize (w,h) rs = putStrLn $ unlines ls
53+
where coords = S.fromList (map pos rs)
54+
ls = [ [ if S.member (x,y) coords then '#' else '.' | x <- [0..w-1] ] | y<-[0..h-1] ]
55+
56+
part2 inp = forM_ (take 100 minimums) $ \(i,rs) -> do
57+
putStrLn "--"
58+
visualize bigLimits rs
59+
print (heuristic rs)
60+
print i
61+
where evolution = zip [0..] $ iterate (map (tick bigLimits)) inp
62+
minimums = go (length inp) evolution
63+
go best ((i,r):rest)
64+
| heuristic r < best = (i,r):go (heuristic r) rest
65+
| otherwise = go best rest
66+
67+
main = do
68+
--print . part1 =<< slurp
69+
part2 =<< slurp

0 commit comments

Comments
 (0)