{-# OPTIONS -fno-spec-constr-count #-}
module Bench.Vector.Algo.AwShCC (awshcc) where

import Data.Vector.Unboxed as V

awshcc :: (Int, Vector Int, Vector Int) -> Vector Int
{-# NOINLINE awshcc #-}
awshcc :: (Int, Vector Int, Vector Int) -> Vector Int
awshcc (Int
n, Vector Int
es1, Vector Int
es2) = Vector Int -> Vector Int -> Vector Int -> Vector Int
concomp Vector Int
ds Vector Int
es1' Vector Int
es2'
    where
      ds :: Vector Int
ds = Int -> Int -> Vector Int
forall a. (Unbox a, Enum a) => a -> a -> Vector a
V.enumFromTo Int
0 (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector a -> Vector a
V.++ Int -> Int -> Vector Int
forall a. (Unbox a, Enum a) => a -> a -> Vector a
V.enumFromTo Int
0 (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
      es1' :: Vector Int
es1' = Vector Int
es1 Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector a -> Vector a
V.++ Vector Int
es2
      es2' :: Vector Int
es2' = Vector Int
es2 Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector a -> Vector a
V.++ Vector Int
es1

      starCheck :: Vector Int -> Vector Bool
starCheck Vector Int
ds = Vector Bool -> Vector Int -> Vector Bool
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Bool
st' Vector Int
gs
        where
          gs :: Vector Int
gs  = Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds Vector Int
ds
          st :: Vector Bool
st  = (Int -> Int -> Bool) -> Vector Int -> Vector Int -> Vector Bool
forall a b c.
(Unbox a, Unbox b, Unbox c) =>
(a -> b -> c) -> Vector a -> Vector b -> Vector c
V.zipWith Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) Vector Int
ds Vector Int
gs
          st' :: Vector Bool
st' = Vector Bool -> Vector (Int, Bool) -> Vector Bool
forall a. Unbox a => Vector a -> Vector (Int, a) -> Vector a
V.update Vector Bool
st (Vector (Int, Bool) -> Vector Bool)
-> (Vector (Int, Bool) -> Vector (Int, Bool))
-> Vector (Int, Bool)
-> Vector Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Bool) -> Bool) -> Vector (Int, Bool) -> Vector (Int, Bool)
forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (Bool -> Bool
not (Bool -> Bool) -> ((Int, Bool) -> Bool) -> (Int, Bool) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Bool) -> Bool
forall a b. (a, b) -> b
snd)
                            (Vector (Int, Bool) -> Vector Bool)
-> Vector (Int, Bool) -> Vector Bool
forall a b. (a -> b) -> a -> b
$ Vector Int -> Vector Bool -> Vector (Int, Bool)
forall a b.
(Unbox a, Unbox b) =>
Vector a -> Vector b -> Vector (a, b)
V.zip Vector Int
gs Vector Bool
st

      concomp :: Vector Int -> Vector Int -> Vector Int -> Vector Int
concomp Vector Int
ds Vector Int
es1 Vector Int
es2
        | Vector Bool -> Bool
V.and (Vector Int -> Vector Bool
starCheck Vector Int
ds'') = Vector Int
ds''
        | Bool
otherwise              = Vector Int -> Vector Int -> Vector Int -> Vector Int
concomp (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds'' Vector Int
ds'') Vector Int
es1 Vector Int
es2
        where
          ds' :: Vector Int
ds'  = Vector Int -> Vector (Int, Int) -> Vector Int
forall a. Unbox a => Vector a -> Vector (Int, a) -> Vector a
V.update Vector Int
ds
               (Vector (Int, Int) -> Vector Int)
-> (Vector (Int, Int, Int) -> Vector (Int, Int))
-> Vector (Int, Int, Int)
-> Vector Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int, Int) -> (Int, Int))
-> Vector (Int, Int, Int) -> Vector (Int, Int)
forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
V.map (\(Int
di, Int
dj, Int
gi) -> (Int
di, Int
dj))
               (Vector (Int, Int, Int) -> Vector (Int, Int))
-> (Vector (Int, Int, Int) -> Vector (Int, Int, Int))
-> Vector (Int, Int, Int)
-> Vector (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int, Int) -> Bool)
-> Vector (Int, Int, Int) -> Vector (Int, Int, Int)
forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (\(Int
di, Int
dj, Int
gi) -> Int
gi Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
di Bool -> Bool -> Bool
&& Int
di Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
dj)
               (Vector (Int, Int, Int) -> Vector Int)
-> Vector (Int, Int, Int) -> Vector Int
forall a b. (a -> b) -> a -> b
$ Vector Int -> Vector Int -> Vector Int -> Vector (Int, Int, Int)
forall a b c.
(Unbox a, Unbox b, Unbox c) =>
Vector a -> Vector b -> Vector c -> Vector (a, b, c)
V.zip3 (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds Vector Int
es1)
                        (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds Vector Int
es2)
                        (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds Vector Int
es1))

          ds'' :: Vector Int
ds'' = Vector Int -> Vector (Int, Int) -> Vector Int
forall a. Unbox a => Vector a -> Vector (Int, a) -> Vector a
V.update Vector Int
ds'
               (Vector (Int, Int) -> Vector Int)
-> (Vector (Int, Int, Bool) -> Vector (Int, Int))
-> Vector (Int, Int, Bool)
-> Vector Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int, Bool) -> (Int, Int))
-> Vector (Int, Int, Bool) -> Vector (Int, Int)
forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
V.map (\(Int
di, Int
dj, Bool
st) -> (Int
di, Int
dj))
               (Vector (Int, Int, Bool) -> Vector (Int, Int))
-> (Vector (Int, Int, Bool) -> Vector (Int, Int, Bool))
-> Vector (Int, Int, Bool)
-> Vector (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Int, Int, Bool) -> Bool)
-> Vector (Int, Int, Bool) -> Vector (Int, Int, Bool)
forall a. Unbox a => (a -> Bool) -> Vector a -> Vector a
V.filter (\(Int
di, Int
dj, Bool
st) -> Bool
st Bool -> Bool -> Bool
&& Int
di Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
dj)
               (Vector (Int, Int, Bool) -> Vector Int)
-> Vector (Int, Int, Bool) -> Vector Int
forall a b. (a -> b) -> a -> b
$ Vector Int -> Vector Int -> Vector Bool -> Vector (Int, Int, Bool)
forall a b c.
(Unbox a, Unbox b, Unbox c) =>
Vector a -> Vector b -> Vector c -> Vector (a, b, c)
V.zip3 (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds' Vector Int
es1)
                        (Vector Int -> Vector Int -> Vector Int
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute Vector Int
ds' Vector Int
es2)
                        (Vector Bool -> Vector Int -> Vector Bool
forall a. Unbox a => Vector a -> Vector Int -> Vector a
V.backpermute (Vector Int -> Vector Bool
starCheck Vector Int
ds') Vector Int
es1)