day 14: use deviation instead of connected components
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
		
							
								
								
									
										33
									
								
								src/Day14.hs
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/Day14.hs
									
									
									
									
									
								
							@@ -41,28 +41,12 @@ part1 robots = length q1 * length q2 * length q3 * length q4
 | 
				
			|||||||
    q3 = [r | r@(x, y) <- moved, x < width `div` 2, y > height `div` 2]
 | 
					    q3 = [r | r@(x, y) <- moved, x < width `div` 2, y > height `div` 2]
 | 
				
			||||||
    q4 = [r | r@(x, y) <- moved, x > width `div` 2, y > height `div` 2]
 | 
					    q4 = [r | r@(x, y) <- moved, x > width `div` 2, y > height `div` 2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- number of connected components
 | 
					 | 
				
			||||||
regions :: S.Set Vec -> Int
 | 
					 | 
				
			||||||
regions s
 | 
					 | 
				
			||||||
  | Just c <- S.lookupMin s =
 | 
					 | 
				
			||||||
      let r = go c S.empty
 | 
					 | 
				
			||||||
       in 1 + regions (S.difference s r)
 | 
					 | 
				
			||||||
  | otherwise = 0
 | 
					 | 
				
			||||||
  where
 | 
					 | 
				
			||||||
    -- depth first search
 | 
					 | 
				
			||||||
    go :: Vec -> S.Set Vec -> S.Set Vec
 | 
					 | 
				
			||||||
    go c@(x, y) r
 | 
					 | 
				
			||||||
      | c `S.member` r = r
 | 
					 | 
				
			||||||
      | otherwise =
 | 
					 | 
				
			||||||
          let r' = S.insert c r
 | 
					 | 
				
			||||||
              nexts = [n | n <- [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)], n `S.member` s]
 | 
					 | 
				
			||||||
           in foldr go r' nexts
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
part2 :: [Robot] -> Int -> IO ()
 | 
					part2 :: [Robot] -> Int -> IO ()
 | 
				
			||||||
part2 robots n = do
 | 
					part2 robots n = do
 | 
				
			||||||
  let moved = map (`moveN` n) robots
 | 
					  let moved = map (`moveN` n) robots
 | 
				
			||||||
      s = S.fromList moved
 | 
					      s = S.fromList moved
 | 
				
			||||||
      cc = regions s
 | 
					      d = map (\(x, y) -> sqrt (fromIntegral x ^ 2 + fromIntegral y ^ 2)) moved
 | 
				
			||||||
 | 
					      deviation = sd d $ mean d
 | 
				
			||||||
      rows =
 | 
					      rows =
 | 
				
			||||||
        [ [ if (x, y) `S.member` s then '#' else '.'
 | 
					        [ [ if (x, y) `S.member` s then '#' else '.'
 | 
				
			||||||
            | x <- [0 .. width - 1]
 | 
					            | x <- [0 .. width - 1]
 | 
				
			||||||
@@ -70,10 +54,15 @@ part2 robots n = do
 | 
				
			|||||||
          | y <- [0 .. height - 1]
 | 
					          | y <- [0 .. height - 1]
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  when (cc < 250) $ do
 | 
					  when (deviation < 20) $ do
 | 
				
			||||||
    putStrLn $ "After " ++ show n ++ " seconds, " ++ show cc ++ " CCs:"
 | 
					 | 
				
			||||||
    mapM_ putStrLn rows
 | 
					 | 
				
			||||||
    putStr "Part 2: " >> print n
 | 
					    putStr "Part 2: " >> print n
 | 
				
			||||||
 | 
					    putStrLn $ "After " ++ show n ++ " seconds:"
 | 
				
			||||||
 | 
					    mapM_ putStrLn rows
 | 
				
			||||||
 | 
					  where
 | 
				
			||||||
 | 
					    mean :: [Float] -> Float
 | 
				
			||||||
 | 
					    mean = (/) <$> sum <*> fromIntegral . length
 | 
				
			||||||
 | 
					    sd :: [Float] -> Float -> Float
 | 
				
			||||||
 | 
					    sd xs m = sqrt $ sum [(x - m) ^ 2 | x <- xs] / fromIntegral (length xs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
main :: IO ()
 | 
					main :: IO ()
 | 
				
			||||||
main =
 | 
					main =
 | 
				
			||||||
@@ -83,4 +72,4 @@ main =
 | 
				
			|||||||
    let robots = A.extract $ parse parseRobots "" raw
 | 
					    let robots = A.extract $ parse parseRobots "" raw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    putStr "Part 1: " >> print (part1 robots)
 | 
					    putStr "Part 1: " >> print (part1 robots)
 | 
				
			||||||
    mapM_ (part2 robots) [0..10000]
 | 
					    mapM_ (part2 robots) [0 .. 10000]
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user