RosettaCodeData/Task/Matrix-arithmetic/Haskell/matrix-arithmetic.hs

60 lines
1.4 KiB
Haskell
Raw Permalink Normal View History

2017-09-23 10:01:46 +02:00
sPermutations :: [a] -> [([a], Int)]
sPermutations = flip zip (cycle [1, -1]) . foldl aux [[]]
where
aux items x = do
(f, item) <- zip (cycle [reverse, id]) items
f (insertEv x item)
insertEv x [] = [[x]]
insertEv x l@(y:ys) = (x : l) : ((y :) <$>) (insertEv x ys)
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
elemPos :: [[a]] -> Int -> Int -> a
2016-12-05 22:15:40 +01:00
elemPos ms i j = (ms !! i) !! j
2017-09-23 10:01:46 +02:00
prod
:: Num a
=> ([[a]] -> Int -> Int -> a) -> [[a]] -> [Int] -> a
prod f ms = product . zipWith (f ms) [0 ..]
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
sDeterminant
:: Num a
=> ([[a]] -> Int -> Int -> a) -> [[a]] -> [([Int], Int)] -> a
sDeterminant f ms = sum . fmap (\(is, s) -> fromIntegral s * prod f ms is)
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
determinant
:: Num a
=> [[a]] -> a
determinant ms =
sDeterminant elemPos ms . sPermutations $ [0 .. pred . length $ ms]
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
permanent
:: Num a
=> [[a]] -> a
permanent ms =
sum . fmap (prod elemPos ms . fst) . sPermutations $ [0 .. pred . length $ ms]
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
-- TEST -----------------------------------------------------------------------
result
:: (Num a, Show a)
=> [[a]] -> String
result ms =
unlines
[ "Matrix:"
, unlines (show <$> ms)
, "Determinant:"
, show (determinant ms)
, "Permanent:"
, show (permanent ms)
]
2016-12-05 22:15:40 +01:00
2017-09-23 10:01:46 +02:00
main :: IO ()
main =
mapM_
(putStrLn . result)
[ [[5]]
, [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
, [[0, 0, 1], [0, 1, 0], [1, 0, 0]]
, [[4, 3], [2, 5]]
, [[2, 5], [4, 3]]
, [[4, 4], [2, 2]]
]