aoc2025

Advent of Code 2025
git clone git://git.rr3.xyz/aoc2025
Log | Files | Refs | Submodules

Matrix.hs (1395B)


      1 module Matrix (Matrix, nrows, ncols, generate, fromList, (!?), count) where
      2 
      3 import Data.Vector (Vector)
      4 import Data.Vector qualified as V
      5 
      6 --------------------------------------------------------------------------------
      7 -- Util
      8 
      9 consensus :: (Eq a) => [a] -> Maybe a
     10 consensus [] = Nothing
     11 consensus (x : xs) = if all (== x) xs then Just x else Nothing
     12 
     13 --------------------------------------------------------------------------------
     14 -- Matrix
     15 
     16 data Matrix a = Matrix Int Int (Vector a) deriving (Eq, Show)
     17 
     18 instance Functor Matrix where
     19     fmap f (Matrix nr nc vs) = Matrix nr nc (f <$> vs)
     20 
     21 nrows :: Matrix a -> Int
     22 nrows (Matrix nr _ _) = nr
     23 
     24 ncols :: Matrix a -> Int
     25 ncols (Matrix _ nc _) = nc
     26 
     27 valuesRowMajor :: Matrix a -> Vector a
     28 valuesRowMajor (Matrix _ _ vs) = vs
     29 
     30 generate :: Int -> Int -> ((Int, Int) -> a) -> Matrix a
     31 generate nr nc f = Matrix nr nc (V.generate (nr * nc) (f . (`divMod` nc)))
     32 
     33 fromList :: [[a]] -> Maybe (Matrix a)
     34 fromList [] = Just $ Matrix 0 0 V.empty
     35 fromList l = do
     36     let nr = length l
     37     nc <- consensus (length <$> l)
     38     let vs = V.concat (V.fromList <$> l)
     39     Just $ Matrix nr nc vs
     40 
     41 (!?) :: Matrix a -> (Int, Int) -> Maybe a
     42 Matrix nr nc vs !? (i, j) =
     43     if 0 <= i && i < nr && 0 <= j && j < nc
     44         then Just $ vs V.! (i * nc + j)
     45         else Nothing
     46 
     47 count :: (a -> Bool) -> Matrix a -> Int
     48 count p = V.length . V.filter p . valuesRowMajor