module Solutions.P89 (bipartite) where
import Data.Set (Set)
import qualified Data.Set as Set
import Problems.Graphs
bipartite :: G -> Bool
bipartite :: G -> Bool
bipartite G
g = G -> (Set Vertex, Set Vertex, Set Vertex, Set Vertex) -> Bool
partition G
g (G -> Set Vertex
forall g. Graph g => g -> Set Vertex
vertexes G
g, Set Vertex
forall a. Set a
Set.empty, Set Vertex
forall a. Set a
Set.empty, Set Vertex
forall a. Set a
Set.empty)
partition :: G -> (Set Vertex, Set Vertex, Set Vertex, Set Vertex) -> Bool
partition :: G -> (Set Vertex, Set Vertex, Set Vertex, Set Vertex) -> Bool
partition G
g (Set Vertex
remaining, Set Vertex
boundary, Set Vertex
us, Set Vertex
vs)
| Set Vertex -> Bool
forall a. Set a -> Bool
Set.null Set Vertex
boundary Bool -> Bool -> Bool
&& Set Vertex -> Bool
forall a. Set a -> Bool
Set.null Set Vertex
remaining = Bool
True
| Set Vertex -> Bool
forall a. Set a -> Bool
Set.null Set Vertex
boundary = let (Vertex
v', Set Vertex
r') = Set Vertex -> (Vertex, Set Vertex)
forall a. Set a -> (a, Set a)
Set.deleteFindMin Set Vertex
remaining
in G -> (Set Vertex, Set Vertex, Set Vertex, Set Vertex) -> Bool
partition G
g (Set Vertex
r', Vertex -> Set Vertex
forall a. a -> Set a
Set.singleton Vertex
v', Set Vertex
us, Set Vertex
vs)
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Set Vertex -> Set Vertex -> Bool
forall a. Ord a => Set a -> Set a -> Bool
Set.disjoint Set Vertex
boundary' Set Vertex
us = Bool
False
| Bool
otherwise = G -> (Set Vertex, Set Vertex, Set Vertex, Set Vertex) -> Bool
partition G
g (Set Vertex
remaining', Set Vertex
boundary', Set Vertex
us', Set Vertex
vs')
where
boundary' :: Set Vertex
boundary' = Set Vertex -> Set Vertex -> Set Vertex
forall a. Ord a => Set a -> Set a -> Set a
Set.difference (Set (Set Vertex) -> Set Vertex
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions (Set (Set Vertex) -> Set Vertex) -> Set (Set Vertex) -> Set Vertex
forall a b. (a -> b) -> a -> b
$ (Vertex -> Set Vertex) -> Set Vertex -> Set (Set Vertex)
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map (Vertex -> G -> Set Vertex
forall g. Graph g => Vertex -> g -> Set Vertex
`neighbors` G
g) Set Vertex
boundary) Set Vertex
vs
remaining' :: Set Vertex
remaining' = Set Vertex -> Set Vertex -> Set Vertex
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set Vertex
remaining Set Vertex
boundary
us' :: Set Vertex
us' = Set Vertex
vs
vs' :: Set Vertex
vs' = Set Vertex -> Set Vertex -> Set Vertex
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set Vertex
us Set Vertex
boundary