import Control.Parallel.Strategies
import qualified Data.Vector.Unboxed as V
import Data.Maybe
import Data.Int
type Row = V.Vector Int8
x :: Row -> [Row] -> Integer -> Int -> Integer
x p (v:vs) m c = let c' = c - 1
r = if c>0 then parTuple2 rseq rseq else r0
(a,b) = ( x p vs m c' ,
x (V.zipWith(-) p v) vs (-m) c' )
`using` r
in a+b
x p _ m _ = prod m * prod p
prod :: Integer -> Row -> Integer
prod p = fromMaybea 0p $| V.foldM'null (\ap b -> if b==0 then Nothing else= a
| V.head p == 0 = 0
| otherwise Just= $prod (a * fromIntegral b(V.head p)) 1(V.tail p)
p, pt :: [Row] -> Integer
p (v:vs) = x (foldl (V.zipWith (+)) v vs) (map (V.map (2*)) vs) 1 11
`div` 2^(length vs)
p [] = 1 -- handle 0x0 matrices too :-)
pt (v:vs) | even (length vs) = p ((V.map (2*) v) : vs ) `div` 2
pt mat = p mat
main = getContents >>= print . pt . map V.fromList . read
Compile with ghc -O2 -threaded -fllvm -feager-blackholing -o <name> <name>.hs
. To run with parallelisation, give it runtime parameters like this: ./<name> +RTS -N
. Input is from stdin with nested comma separated lists in brackets like [[1,2],[3,4]]
as in the last example (newlines allowed everywhere).