Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Control.Applicative ((<$>))
- import Text.Printf (printf)
- type Solution = Maybe [Double]
- gauss :: [[Double]] -> Solution
- gauss [[a, b]] = return [b / a]
- gauss (h@(x : xs) : t) = do
- let minor = transform h t
- if any isNull minor
- then Nothing
- else do
- solutions <- gauss minor
- return $ (xs ^*^ (solutions ++ [-1.0])) / (negate x) : solutions
- isNull :: [Double] -> Bool
- isNull [x] = True
- isNull (x:xs) = if x == 0 then isNull xs else False
- transform :: [Double] -> [[Double]] -> [[Double]]
- transform row = map $ elliminate row
- where
- elliminate :: [Double] -> [Double] -> [Double]
- elliminate (x : xs) (y : ys) =
- let factor = negate (y / x) in
- zipWith (+) (map (* factor) xs) ys
- transpose :: Eq a => [[a]] -> [[a]]
- transpose xs
- | all (== []) xs = []
- | otherwise = let (col, rest) = multiHead xs in col : transpose rest
- multiHead :: [[a]] -> ([a], [[a]])
- multiHead = let splitHead (x:xs) = (x, xs) in unzip . map splitHead
- (^*^) :: Num a => [a] -> [a] -> a
- (^*^) xs ys = sum $ zipWith (*) xs ys
- makeSystem :: [[Double]] -> [[Double]]
- makeSystem vs =
- let makeEq n = let e = vs !! n in map (^*^ e) vs in
- let l = length vs - 1 in
- map makeEq [0 .. l-1]
- readNumList :: String -> [Double]
- readNumList = map read . words
- printSolution :: [Double] -> IO ()
- printSolution = putStrLn . unwords . map (printf "%.8f")
- main :: IO ()
- main = do
- [n, m] <- readNumList <$> getLine
- inp <- map readNumList <$> (sequence $ replicate (floor n) getLine)
- case gauss . makeSystem $ transpose inp of
- Just solutions -> printSolution solutions
- Nothing -> putStrLn "NO"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement