{-# Language ImportQualifiedPost #-}
module Main (main) where
import Advent.Coord (Coord(..), below, right)
import Advent.Input (getInputMap)
import Data.Map (Map)
import Data.Map qualified as Map
main :: IO ()
IO ()
main =
do Map Coord Char
inp <- Int -> Int -> IO (Map Coord Char)
getInputMap Int
2021 Int
25
let C Int
ny Int
nx = Coord
1 Coord -> Coord -> Coord
forall a. Num a => a -> a -> a
+ [Coord] -> Coord
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum (Map Coord Char -> [Coord]
forall k a. Map k a -> [k]
Map.keys Map Coord Char
inp)
let inp' :: Map Coord Char
inp' = (Char -> Bool) -> Map Coord Char -> Map Coord Char
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char]
">v") Map Coord Char
inp
let steps :: [Map Coord Char]
steps = (Map Coord Char -> Map Coord Char)
-> Map Coord Char -> [Map Coord Char]
forall a. (a -> a) -> a -> [a]
iterate (Int -> Int -> Map Coord Char -> Map Coord Char
step Int
ny Int
nx) Map Coord Char
inp'
Int -> IO ()
forall a. Show a => a -> IO ()
print ([Map Coord Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Map Coord Char] -> [Map Coord Char]
forall a. Eq a => [a] -> [a]
evolution [Map Coord Char]
steps))
evolution :: Eq a => [a] -> [a]
evolution :: forall a. Eq a => [a] -> [a]
evolution (a
x:a
y:[a]
_) | a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y = [a
x]
evolution (a
x:[a]
xs) = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
forall a. Eq a => [a] -> [a]
evolution [a]
xs
evolution [] = []
step :: Int -> Int -> Map Coord Char -> Map Coord Char
step :: Int -> Int -> Map Coord Char -> Map Coord Char
step Int
ny Int
nx = Int
-> Int
-> Char
-> (Coord -> Coord)
-> Map Coord Char
-> Map Coord Char
step1 Int
ny Int
nx Char
'v' Coord -> Coord
below (Map Coord Char -> Map Coord Char)
-> (Map Coord Char -> Map Coord Char)
-> Map Coord Char
-> Map Coord Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int
-> Int
-> Char
-> (Coord -> Coord)
-> Map Coord Char
-> Map Coord Char
step1 Int
ny Int
nx Char
'>' Coord -> Coord
right
step1 :: Int -> Int -> Char -> (Coord -> Coord) -> Map Coord Char -> Map Coord Char
step1 :: Int
-> Int
-> Char
-> (Coord -> Coord)
-> Map Coord Char
-> Map Coord Char
step1 Int
ny Int
nx Char
c Coord -> Coord
f Map Coord Char
inp =
[(Coord, Char)] -> Map Coord Char
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [
(if Char
v Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
c Bool -> Bool -> Bool
&& Coord -> Map Coord Char -> Bool
forall k a. Ord k => k -> Map k a -> Bool
Map.notMember Coord
k' Map Coord Char
inp then Coord
k' else Coord
k, Char
v)
| (Coord
k, Char
v) <- Map Coord Char -> [(Coord, Char)]
forall k a. Map k a -> [(k, a)]
Map.toList Map Coord Char
inp
, let k' :: Coord
k' = Coord -> Coord
fixup (Coord -> Coord
f Coord
k)
]
where
fixup :: Coord -> Coord
fixup (C Int
y Int
x) = Int -> Int -> Coord
C (Int
y Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
ny) (Int
x Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
nx)