diff --git a/21.hs b/21.hs new file mode 100644 index 0000000..538dde9 --- /dev/null +++ b/21.hs @@ -0,0 +1,77 @@ +import Data.List (transpose) +import Data.List.Split (splitOn, chunksOf) +import Data.Map.Strict (Map, insert, empty, (!)) + +type Rules = Map String String +squareRoot = floor . sqrt . fromIntegral + +validTwos = [ + [0..3], + [0, 2, 1, 3], + [1, 0, 3, 2], + [1, 3, 0, 2], + [2, 0, 3, 1], + [2, 3, 0, 1], + [3, 1, 2, 0], + [3,2..0] + ] + +validThrees = [ + [0..8], + [0, 3, 6, 1, 4, 7, 2, 5, 8], + [2, 1, 0, 5, 4, 3, 8, 7, 6], + [2, 5, 8, 1, 4, 7, 0, 3, 6], + [6, 3, 0, 7, 4, 1, 8, 5, 2], + [6, 7, 8, 3, 4, 5, 0, 1, 2], + [8, 5, 2, 7, 4, 1, 6, 3, 0], + [8,7..0] + ] + +valids :: String -> [String] +valids str = case length str of + 4 -> map (map (str !!)) validTwos + 9 -> map (map (str !!)) validThrees + +row :: Int -> Int -> String -> [String] +row multiple size str = + map concat . transpose . map (chunksOf multiple) . chunksOf size $ str + +derow :: Int -> [String] -> String +derow multiple sbsq = + concat . concat . transpose . map (chunksOf multiple) $ sbsq + +chunk :: String -> [[String]] +chunk str = + let size = squareRoot $ length str + multiple = if even size then 2 else 3 + rows = chunksOf (size * multiple) str + in map (row multiple size) rows + +dechunk :: [[String]] -> String +dechunk rows = + let multiple = squareRoot . length . head . head $ rows + in concat $ map (derow multiple) rows + +enhance :: Rules -> String -> String +enhance rules grid = + dechunk . map (map (rules !)) . chunk $ grid + +addRules :: [String] -> String -> Rules -> Rules +addRules keys value rules = foldr (\key currRules -> insert key value currRules) rules keys + +countOn :: String -> Int +countOn grids = length . filter (== '#') $ grids + +parseLine :: String -> Rules -> Rules +parseLine line rules = + let inputStr : outputStr : [] = splitOn " => " line + input = splitOn "/" inputStr + output = splitOn "/" outputStr + in addRules (valids $ concat input) (concat output) rules + +main :: IO () +main = do + rules <- foldr parseLine empty . lines <$> readFile "21.txt" + let iterations = map countOn $ iterate (enhance rules) ".#...####" + print $ iterations !! 5 + print $ iterations !! 18 \ No newline at end of file diff --git a/21.txt b/21.txt new file mode 100644 index 0000000..b16ed3e --- /dev/null +++ b/21.txt @@ -0,0 +1,108 @@ +../.. => .#./.#./### +#./.. => .#./.#./##. +##/.. => #../.##/.#. +.#/#. => #.#/#../..# +##/#. => ###/##./#.# +##/## => .../.../.#. +.../.../... => #.#./.###/..##/#.## +#../.../... => #.#./#.##/#..#/#..# +.#./.../... => #.#./###./#.#./..#. +##./.../... => ##../###./##.#/...# +#.#/.../... => ..../..#./####/..#. +###/.../... => ##../..../#.../#... +.#./#../... => .#../..##/#..#/.#.# +##./#../... => ####/.###/.###/.### +..#/#../... => .#.#/.##./...#/##.. +#.#/#../... => #.##/#.##/#.##/.#.. +.##/#../... => .#../...#/..#./.##. +###/#../... => .##./.###/#..#/##.# +.../.#./... => .#../.#.#/.#../#.## +#../.#./... => ...#/##../####/##.. +.#./.#./... => ###./#..#/..#./...# +##./.#./... => #.##/..#./#.#./..#. +#.#/.#./... => .#.#/...#/..../#.## +###/.#./... => ..##/##.#/#.##/###. +.#./##./... => .##./####/##../#### +##./##./... => .###/..../####/#... +..#/##./... => ..../##.#/.###/.##. +#.#/##./... => #.#./###./..../###. +.##/##./... => ###./.###/.#../##.# +###/##./... => #.##/#.#./..../##.# +.../#.#/... => ###./#.##/.###/#.## +#../#.#/... => ##.#/..../..../.#.# +.#./#.#/... => .#.#/..##/.#../.##. +##./#.#/... => .##./..#./...#/#... +#.#/#.#/... => ..../###./..#./.#.# +###/#.#/... => ..##/.##./###./#.## +.../###/... => .#../####/.##./..#. +#../###/... => ..##/#.#./...#/##.. +.#./###/... => ..#./####/##../#.## +##./###/... => .##./##.#/####/.#.# +#.#/###/... => .###/#.##/####/.##. +###/###/... => #.../#.../##../.##. +..#/.../#.. => ..##/#.#./#.../#.#. +#.#/.../#.. => ###./##.#/..#./##.# +.##/.../#.. => ..#./..../##../.#.# +###/.../#.. => ####/.#.#/.#.#/#### +.##/#../#.. => ####/####/...#/.#.# +###/#../#.. => ..##/..#./.##./##.. +..#/.#./#.. => ####/...#/####/#..# +#.#/.#./#.. => ..#./.###/#.#./##.# +.##/.#./#.. => .###/.#.#/#..#/..#. +###/.#./#.. => ..../##../.#.#/.#.. +.##/##./#.. => ###./####/..../#... +###/##./#.. => ####/#..#/##.#/##.# +#../..#/#.. => ####/##.#/..../.### +.#./..#/#.. => ..../.#../..#./..#. +##./..#/#.. => .#.#/...#/#.##/..#. +#.#/..#/#.. => #.#./#.##/#..#/#### +.##/..#/#.. => ..#./##../####/.#.. +###/..#/#.. => #.../##.#/###./.#.# +#../#.#/#.. => ..../.#.#/..#./#.#. +.#./#.#/#.. => #.##/...#/.##./.#.. +##./#.#/#.. => .###/##.#/##.#/#### +..#/#.#/#.. => ..../..../...#/##.# +#.#/#.#/#.. => ##.#/.#../###./..#. +.##/#.#/#.. => ###./..../...#/.##. +###/#.#/#.. => .###/#..#/.##./.### +#../.##/#.. => ##../.#.#/.##./.##. +.#./.##/#.. => .###/.###/..##/.#.. +##./.##/#.. => ..##/###./...#/#... +#.#/.##/#.. => ..#./###./...#/##.. +.##/.##/#.. => ####/###./#.#./##.. +###/.##/#.. => ..##/.##./#.../..## +#../###/#.. => ####/.#../.###/.#.# +.#./###/#.. => .##./##.#/..##/##.. +##./###/#.. => ..##/##.#/##../.#.# +..#/###/#.. => ##../..../.#.#/#..# +#.#/###/#.. => ..#./###./####/..## +.##/###/#.. => ##../##../..##/.##. +###/###/#.. => ###./...#/#..#/..#. +.#./#.#/.#. => ..../.###/.###/#... +##./#.#/.#. => .###/..#./..../#... +#.#/#.#/.#. => #..#/.##./#.##/..#. +###/#.#/.#. => ####/##../####/.... +.#./###/.#. => ..../.###/..../###. +##./###/.#. => ###./.#../#.#./.#.. +#.#/###/.#. => ..../..##/..##/.... +###/###/.#. => ###./...#/#.../..#. +#.#/..#/##. => ###./.##./.#../.... +###/..#/##. => ####/...#/##../#..# +.##/#.#/##. => ..../...#/##.#/#.## +###/#.#/##. => .#.#/.###/..../#... +#.#/.##/##. => .#.#/#.#./...#/#... +###/.##/##. => .##./...#/#.../..#. +.##/###/##. => .#.#/.##./.##./##.. +###/###/##. => #.#./##../##../...# +#.#/.../#.# => #.#./##.#/##.#/#### +###/.../#.# => .#../.#.#/.##./#.## +###/#../#.# => ###./##../..##/##.. +#.#/.#./#.# => ####/#.#./###./.##. +###/.#./#.# => ..#./.##./..../#... +###/##./#.# => #..#/##.#/.##./.#.. +#.#/#.#/#.# => .#../###./##.#/.#.. +###/#.#/#.# => .#../#.##/##.#/..#. +#.#/###/#.# => ##.#/.###/..##/.#.. +###/###/#.# => .#../.###/..#./#... +###/#.#/### => ###./####/.###/#.## +###/###/### => #..#/.#../#.../...# diff --git a/README.md b/README.md index daceb24..1117226 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,10 @@ These are the runtimes of only one trial but the variances are fairly small and | 18 | 0.118 | | 19 | 0.026 | | 20 | 0.168 | +| 21 | 4.013 | Problems that should be optimized further: 15 -Problems that could use some work: 05, 14 +Problems that could use some work: 05, 14, 21 Problems that are good enough with optimizations: 17, 13