aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuchen Pei <me@ypei.me>2017-12-23 10:41:50 +0100
committerYuchen Pei <me@ypei.me>2017-12-23 10:41:50 +0100
commit15d597662b7cd5eb950ecf30ddb452cd1f247bf8 (patch)
tree2ad9277feb5d1eb8132e9bcd7baf36d9777bad48
parentfa1b1202d3ed019620137d8c802232d957d7bee8 (diff)
finished Day 22
-rwxr-xr-xPuzzle22bin0 -> 44336 bytes
-rw-r--r--Puzzle22.hibin0 -> 12425 bytes
-rw-r--r--Puzzle22.hs92
-rw-r--r--Puzzle22.obin0 -> 37832 bytes
4 files changed, 92 insertions, 0 deletions
diff --git a/Puzzle22 b/Puzzle22
new file mode 100755
index 0000000..4543a80
--- /dev/null
+++ b/Puzzle22
Binary files differ
diff --git a/Puzzle22.hi b/Puzzle22.hi
new file mode 100644
index 0000000..2f8e170
--- /dev/null
+++ b/Puzzle22.hi
Binary files differ
diff --git a/Puzzle22.hs b/Puzzle22.hs
new file mode 100644
index 0000000..0b9df4d
--- /dev/null
+++ b/Puzzle22.hs
@@ -0,0 +1,92 @@
+{-# LANGUAGE BangPatterns #-}
+
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+data Direction = U | R | D | L
+data Status = Infected | Clean | Weakened | Flagged deriving Eq
+
+step :: Int -> Int -> Map (Int, Int) Bool -> (Int, Int) -> Direction -> Int
+step n m cluster (x, y) dir
+ | n == 0 = m
+ | otherwise = step (n - 1) (m + (if infected then 0 else 1)) (Map.insert (x, y) (not infected) cluster) (x', y') dir'
+ where infected = Map.findWithDefault False (x, y) cluster
+ dir' = f infected dir
+ (x', y') = g (x, y) dir'
+
+step' :: Int -> Int -> Map (Int, Int) Status -> (Int, Int) -> Direction -> Int
+step' !n !m !cluster (!x, !y) !dir
+ | n == 0 = m
+ | otherwise = step' (n - 1) m' cluster' (x', y') dir'
+ where status = Map.findWithDefault Clean (x, y) cluster
+ dir' = f' status dir
+ status' = k status
+ cluster' = Map.insert (x, y) status' cluster
+ (x', y') = g (x, y) dir'
+ m' = if status' == Infected then m + 1 else m
+
+f :: Bool -> Direction -> Direction
+f True U = R
+f True R = D
+f True D = L
+f True L = U
+f False U = L
+f False L = D
+f False D = R
+f False R = U
+
+f' Infected U = R
+f' Infected R = D
+f' Infected D = L
+f' Infected L = U
+f' Clean U = L
+f' Clean L = D
+f' Clean D = R
+f' Clean R = U
+f' Weakened x = x
+f' Flagged U = D
+f' Flagged L = R
+f' Flagged D = U
+f' Flagged R = L
+
+k Clean = Weakened
+k Weakened = Infected
+k Infected = Flagged
+k Flagged = Clean
+
+g :: (Int, Int) -> Direction -> (Int, Int)
+g (!x, !y) R = (x, y + 1)
+g (!x, !y) D = (x + 1, y)
+g (!x, !y) L = (x, y - 1)
+g (!x, !y) U = (x - 1, y)
+
+h :: Char -> Bool
+h '.' = False
+h '#' = True
+
+h' :: Char -> Status
+h' '.' = Clean
+h' '#' = Infected
+
+solve2 :: [Char] -> Int
+solve2 xs = step' 10000000 0 cluster initCoord U
+ where mat = (fmap h') <$> lines xs
+ cluster = mat2Map mat
+ initCoord = (length mat `div` 2, length (head mat) `div` 2)
+
+
+solve1 :: [Char] -> Int
+solve1 xs = step 10000 0 cluster initCoord U
+ where mat = (fmap h) <$> lines xs
+ cluster = mat2Map mat
+ initCoord = (length mat `div` 2, length (head mat) `div` 2)
+
+mat2Map :: [[a]] -> Map (Int, Int) a
+mat2Map xs = Map.fromList $ mconcat $ fmap j $ zipWith (,) [0 .. length xs - 1] xs
+ where j (x, ys) = zipWith (,) ((\y -> (x,y)) <$> [0 .. length ys]) ys
+
+input0 = "..#\n#..\n..."
+
+input = "...#.##.#.#.#.#..##.###.#\n......##.....#####..#.#.#\n#..####.######.#.#.##...#\n...##..####........#.#.#.\n.#.#####..#.....#######..\n.#...#.#.##.#.#.....#....\n.#.#.#.#.#####.#.#..#...#\n###..##.###.#.....#...#.#\n#####..#.....###.....####\n#.##............###.#.###\n#...###.....#.#.##.#..#.#\n.#.###.##..#####.....####\n.#...#..#..###.##..#....#\n##.##...###....##.###.##.\n#.##.###.#.#........#.#..\n##......#..###.#######.##\n.#####.##..#..#....##.##.\n###..#...#..#.##..#.....#\n##..#.###.###.#...##...#.\n##..##..##.###..#.##..#..\n...#.#.###..#....##.##.#.\n##.##..####..##.##.##.##.\n#...####.######.#...##...\n.###..##.##..##.####....#\n#.##....#.#.#..#.###..##."
+
+main = putStr $ show $ solve2 input
diff --git a/Puzzle22.o b/Puzzle22.o
new file mode 100644
index 0000000..53453b1
--- /dev/null
+++ b/Puzzle22.o
Binary files differ