aoc2025

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

Matrix.hs (1360B)


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