áŁááá áá¨ááľ á°áłáľá áá áá˘
á Google Summer of Code 2019 á°áłáłá áĽáá°áááᣠá á¤á°-áá˝áááľ ááľáĽ ááŽáááľ á°ááťáá
á áá ááĄá á˝áá á ááľáŹá ááľáĽ ááááľáŽá˝ááľ ááŤá áááá°á˝ áľá á áááŞáá á á°ááŁá á á ááŤááᢠááá áĽááłá á áááŞáá á áŁá áá á¨áłá á¨áááľ ááľáĽ á ááą á˘áááᣠá ááŤáá áááł á á°ááŁáŤá ááᤠáá°áá አáĽá áľáááážá˝á ááľáśáĽáá áĽá áĽá áľáŤ á áľáááááᢠá áá ááááŤáľ á¨áááľ áľáŤááľááááŽá˝ áá áá° áľáá ፠ááŁáá˘
áľá áĽá
áľá áŤá˛á á áááŽá áĽáŁáááᣠá á´ááľ áá°ááľá áá á¤á˝á¤áľá˘ á¨á áŤá°á áááľ á°á᪠ááᢠáá°á áĽáŹ á áťááŠáľ áĽáá ááľáĽ
áľá á áááŞáá á á°ááŁá á
áá áľá
á ááŽááŤá ááľáĽ á¨ááłá°á á°ááŞáá˝ á áĽáá áĽáá˛áŤá°áá á áĽáĽá
áá á¨áłáłáᢠááĽáá ááľá¨á á ááá
á°ááááá˘
á¨ááá°áľ áĽáŤá á áĽáŤá ááľáĽ áŤáá áŽáľ áá ááá áá˝ááá˘
áľá áĽáŤáŹ áá¤áľ (á áĽááááá) ááá ἠáľá˝ááá˝á
áá á˝áá á ááŁá˘áá á á°ááŁáŤá ááŽááŤááá ááľáĽ á¨áá á¨áłá á áá°-ááłáŚá˝ áá ááá°ááá á¨áłá°á áá ᣠááá áĽááłá ááá á˛á°ááľ áĽá á áá á¨áááľá áááá áááľ áááľáłááľ áĽáááŤáá á˘
ááááľ ááá˛ááľ ááŤáá˝á ááá°á˝
ááááľáŽá˝ááľ ááŤá áááá°á˝ áľáá° ááá áĽááá áá á á áááŞáá áá á áá°áĽ áŽááľ ááľáĽ á áŁá ááá á¨ááŤá áľáá° áááŽá˝ á ááą ááᢠááłáĄ ááĽá°á ááᥠááááŞáŤ áĽáá°ááá áá° á፠ááá áá áľááť áá áŤáá˝á áĽááľáááŁáá áĽá á¨ááá á áá á˛áá ááŤá á¨áááľáŽá˝ áĽááłááá áĽáá¨áááŁááá˘
áľáá˝ á°á¨á᪠ááááᥠá ááááŞáŤ á á፠áľááťá áá á¨á°áá°á áááľ áĽááľáááŁááᢠá ááá˝ ááá¨áľ áĽáá°ááťáá, ááá á¨áá áŤá áá¨á¤áśá˝ á áľááááá áἠááľáĽ ááá¸áľ á ááŁá¸á. á á°á¨ááŞá, ááá á¨áá áŤá áá¨á¤áśá˝ áá¨á¤áśá˝ á á፠áἠááľáĽ áá°ááľ á ááŁá¸á, ááá°. áĽá áá¨á¤áśá˝ áŤááá°áĽáá áľ á¨ááááá ᾠᨠvertex ááá á¨á°ááá á áŤá áá á ááá áŤáá˝ áĽáľáŤá áľá¨áľ á áá˛áŽáá˝á áá° áŤáá˝ ááá°áĽá áĽáááĽáááᢠá¨á፠áá á áĽááá áááá á¨á°ááá á áŤááľ áĽáá°ááááá.
á á°ááłáłáŠ ááááá ááľáĽ á áááľá áŤáá˝ ááŤá¨á á áá áŤá á ááŤá ááľáĽ áŤáá°ááá° áá°áľ ááááľ á áľá¸á᪠á áá°áá ᣠáá á á á°áá á¨ááłáá (áĽá á ááá ) á áááľáŽá˝ ááŤá ááľáĽ á¨áááťá ááᢠá áá áááŤ, áĽá áľáááá ááááá á áá, áá á áááľ ááŤá á¨áááľáŽá˝ áá.
á á°áááś áá
áľáá° ááá á áá áá áá°áá áŤá
áľááá , áá°áá¨á°áá áĽá áľ á°áá°áá. áĽáááľ-á¨ááááŞáŤ áááá á áá áá á¨ááŤáá áŤáá˝ áĽááááŁáá áĽá á áá˛áŽáá˝á áĽáááľáŁá¸ááá, á á áá áá áľááááłááľ á¨ááĽáŠá ááĽá áĽááááŁáá. ááľáááá áľááť áŤáá áľááť ááá áááľ áááá°áĽ á¨áá¨áá ááŤá á¨áááľáŽá˝ á áá°áá áááľ áĽáá˝áááᢠááá áŤáá˝ á ááľ áľááť á á°áá°áĄá áľ áá áĽá áááá áŤáá˝ á á°ááá¨áľáá áľ áá áĽáŠ áááá á ááá˘
á¨áľááśá˝ áá á á
á Haskell ááľáĽ ááá áľááśá˝ áĽáá°áá áĽááááłááᢠááá ᢠááá ááᣠáá áĽáááľ á¨ááᣠááá ááá á áľááŞá áá ááá°á ááá á áááľ ááááľ á ááá¨áá áá áᢠáá˝á, ááá áľááśá˝ á áŁá á°áá áľááá á ááľá á¨ááᢠááá á ááľ ááá áááľááľ ááááŤáśá˝. á ááŽááŤá ááľáĽ á¨áá¨á°áą ááá áľááśá˝ á áá ááááľ áĽáá˛áᥠááá°áłá "ááŠáľ" áááľ á á.áŚ.
áááśá˝ áľááśá˝á á¨ááááá áľ ááááľ áá¸áᢠá°á
áááá˝ á Haskell ááľáĽ. áĽáá´áľ áĽáá°áá አááĽáŤáŤáľ á¨áá
á˝áá áá°á á áá ááᢠáĽáŠ áĽá ááá˝ ááá፠á áĽááááá ááá ἠáá˝áá
áĽáá áá áĽáá° á áጠáŤá á ááłááľ áááśá˝ á á áááŁáŁáŞ á áľááľ á˛á°áá አááá˝ ááá áááľ ááťáá á áśááľáá ááľáĽ áĽáá°áá°áá አáĽá á ááľáŁá¸á áŤááľ ááá áľááśá˝ áášá áááá¸áá áááá áĽáááááá˘
áĽá á°á áááá˝ á á áĽá áĽáŤááłááą á¨áŤáą áááł á áá. áá á áŁá á ááŤáŤ áĽá á¨ááŤáá á áá°-ááłáĽ áá-ááá áááśá˝ á ááľ á áááľ á áááá˝ áá°ááĽáŤáᢠáľááá¨á°ááľ áśáľáľ áááśá˝ áĽáááááŤáá-
- áá ᢠá¨á áááľ áĽá´áľá á¨ááááľ ááá á¨á ááᾠᢠá áľá°áá á¨ááĽá áľááľ ááᢠá¨áá áááľ áŁá ᪠á á áľááłá ááááá˝ áአá áŤáŤá áá á áŁá á°ááłáłá ááᥠáľá á°áśá˝ ááŤá ááá áá°ááá áá˝ááᢠááá ááŠááą áááłá áá á áá á áááá ááľáĽ áŁáá áá°á á á¤á°-áá˝áááľ ááľáĽ áá á áá ááááŤáłá á áá ááááľ áá°áá አáá ᣠá áľááá ááááá˝ áá áĽááá áá á¨áľááá° ááá áá´áá˝á áá áááá˘
- State sa á¨á áááľ á áĽá´áľá á¨ááááľ áĽá á¨ááááá áá á áááľ s á¨ááá áľááľ ááá˘
- ááááŁáľ á. The Maybe monad ááá ááá á ááááľ á ááááá áá ááá¨áĽ á¨áá˝á áľááľ ááááťáᢠááá áá, áľá MonadPlus ááá áááᤠááááľ á á°ááŁá á áĽáááááŤáá, áĽáąá á°ááŤááá áá¤áľ á¨áááá˝ áá: á ááľ á¨á°áá°á áĽá´áľ á ááááľ á ááááá áá ááá¨áĽ á¨áá˝á áľááľ áá.
á¨á áááŞáá á á°ááŁá á
áááľ á¨áłáł ááááśá˝ á áá áŁááŤá á áĽá á˘ááŤá ab áŁá¨ááááŞáŤá á á áááľ á áá á¨á°áá á áŤáá˝ áŤáá¸á ááŤáá˝á ááááá áŁááá°áá á°áá á¨áááľáŽá˝ ááŤáá˝á á¨ááááá á¨á፠áá áááśá˝ á áááľ á áĽá áá áá¸áᢠ- á¨áá áŤáá˝ á ááááľ áĽá´áśá˝ ááááľ á¨á°á°á¨ááŁá¸á á.
áĽááá á¨á áá á¤á°-áá˝áááľ á¨áᥠááááśá˝ á áá°áá. á áá ááá°áአá¨áááľáŽá˝ ááŤáá˝ áááá á¨áááᢠááá˝ áááľá¨á áĽáá°áá á áááľ ááááśá˝á á ááá áťáá.
áĽáá˛áá á¨áá¨á°ááľ ááááá˝ áá á¨á¨áłáľ á°ááŁáŤáľá áĽááááááá˘
-- ХпиŃОк ŃĐžŃодоК даннОК воŃŃинŃ.
neighbours :: Ord a => a -> Graph a -> [a]
-- ĐĐžŃŃŃОиŃŃ Đ´Đ˛ŃдОНŃĐ˝ŃĐš ĐłŃĐ°Ń ĐżĐž ĐłŃĐ°ŃŃ Đ¸ ŃŃнкŃии, Đ´ĐťŃ ĐşĐ°ĐśĐ´ĐžĐš воŃŃинŃ
-- вŃĐ´Đ°ŃŃоК ĐľŃ Đ´ĐžĐťŃ Đ¸ пОПоŃĐşŃ Đ˛ нОвОК дОНо, игнОŃиŃŃŃ ĐşĐžĐ˝ŃНикŃĐ˝ŃĐľ ŃŃĐąŃĐ°.
toBipartiteWith :: (Ord a, Ord b, Ord c) => (a -> Either b c)
-> Graph a
-> Bigraph b c
-- ХпиŃОк воŃŃин в ĐłŃĐ°ŃĐľ
vertexList :: Ord a => Graph a -> [a]
ХигнаŃŃŃĐ° ŃŃнкŃии, кОŃĐžŃŃŃ ĐźŃ ĐąŃдоП пиŃĐ°ŃŃ, вŃгНŃĐ´Đ¸Ń ŃĐ°Đş:
type OddCycle a = [a]
detectParts :: Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
á áĽáá -á¨ááááŞáŤ ááá áá áľ áĽááľ á ááą á¨ááá á áá áŤááá ᣠáŤáá°ááá°á áá°áľ á áľáááá˝ ááá á ááľ áá áĽáá°ááá ááá¨áľ ááá ááᢠáľááá , áá°áá á¨á áľ áááááľ, á¨á°á°ááá ááá ááᎠáĽáľá¨ á¨áá¨á¨áťá áŤá á¨ááááŞáŤ ááľá°áľ áľá¨áľ áááá ááá ááá¨áĽ á ááĽá.
á¨áĽáááľ-á¨ááááŞáŤ áááá áĽáá°ááĽáŤáá ááĽáŤááłááą áŹá´ááľ á áśáşáŹá˛á á¨á áá˛áŽá ááĽáŽá˝á á áá á á ᢠá¨áľáá ááá á áá¨áĽáá á¨ááá á፠ááá áľáá ፠á ááŤáááľ á áŤáľ-á°á áá á ááᥠá¨ááááą áá° á°á°ááá á°ááŁá áá° á°ááá°á áá¤áľ áááá áŤáá˝ áĽáť ááľááἠá ááĽáá˘
á¨áĽá á¨ááááŞáŤ ááłáĽ áĽá á¨ááááááá á°á áĽá á áľááá á¨áá°áá á á¨áááľááá áá áááľá áá áá áá áᢠá¨áťááŠáľ á¨ááááŞáŤ á á°ááŁá á ááá á ááŤá á áŁá á áἠáá áᢠáĽáá°áá á á ááľ áá áľ á ááľáľ á¨á°ááŤáŠ á á°ááŁá ááá˝ áá áŠá áĽá á áá¨á¨áť á áááá áá á°áááĽáŠá˘
á ááááŞáŤáŁ á¨á ááááľ áááŤáá˝á áľááľá ááá¨áľ á ááĽá - áá
áľá áááľ á¨áá ááá ááᢠá ááá°á á°á¨á, áááľ á˛áłáá
ááá ááťá á ááĽá. áá
Monad á áá ááá MonadPlus á ááááŁáľ ááá áá˝ááᢠááá ááŠááľ áľááą áŤáá°áá¨á áááá ááááľ áá˝áá, áĽá ááááŁáľ á áá
ááłá áá áľááá
ááłá áá¨áá áĽáť ááááłá. ááľáŹáľ á¨á°áᨠáá áľáááááá (ááľááá á áááľ ááľáĽ á°á¨áá˝áˇá)ᣠááááŁáľ áĽááááŁááᢠáĽá á¨áááľ áááśá˝á á°á
áĽááá˝ ááááľ á ááŤáľáááá áá, áĽááą áááŁá
ááá áĽáá°áá á áááľ ááľáĽáľáĽ á áááľ áá¨áĽáŠ? áááľ ááááŤáśá˝. á ááááŞáŤ á°á¨á, á á°ááŁá አá¨á áľáááá áá á áŁá á°ááłáłá áá. ááá°áᣠá¨áľáááá˝ áá° áá áľááááľ áááľ á ááá áá áľ áá á¨ááááť áĽá´áąá ááľá°áŤá¨á á ááĽáᣠáá á áŤáá°ááá°áá áá°áľ áá°áá á¨á áľ áááááľ á Maybe monad ááľáĽ á áŁá ááá ááá˘
áľááá áá áá áľáá ፠áĽááááá.
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE ScopedTypeVariables #-}
data Part = LeftPart | RightPart
otherPart :: Part -> Part
otherPart LeftPart = RightPart
otherPart RightPart = LeftPart
type PartMap a = Map.Map a Part
type OddCycle a = [a]
toEither :: Ord a => PartMap a -> a -> Either a a
toEither m v = case fromJust (v `Map.lookup` m) of
LeftPart -> Left v
RightPart -> Right v
type PartMonad a = MaybeT (State (PartMap a)) [a]
detectParts :: forall a. Ord a => Graph a -> Either (OddCycle a) (Bigraph a a)
detectParts g = case runState (runMaybeT dfs) Map.empty of
(Just c, _) -> Left $ oddCycle c
(Nothing, m) -> Right $ toBipartiteWith (toEither m) g
where
inVertex :: Part -> a -> PartMonad a
inVertex p v = ((:) v) <$> do modify $ Map.insert v p
let q = otherPart p
msum [ onEdge q u | u <- neigbours v g ]
{-# INLINE onEdge #-}
onEdge :: Part -> a -> PartMonad a
onEdge p v = do m <- get
case v `Map.lookup` m of
Nothing -> inVertex p v
Just q -> do guard (q /= p)
return [v]
processVertex :: a -> PartMonad a
processVertex v = do m <- get
guard (v `Map.notMember` m)
inVertex LeftPart v
dfs :: PartMonad a
dfs = msum [ processVertex v | v <- vertexList g ]
oddCycle :: [a] -> [a]
oddCycle c = tail (dropWhile ((/=) last c) c)
á¨áľ áĽááłá á¨á áááŞáá áá á áŤá ááᢠá ááľáĄ áŤááá ááá áááľá¨áłáľ áĽáááŤááá˘
- inVertex á¨áĽáááľ-á¨ááááŞáŤá ááá á áŤá áá áááááŞáŤ áá á á¨ááŤáŞáá á¨áááá áá áľá˘ áĽáá á¨áááŤáľ ááĽáá áá° áŹáá´ááľ áĽáááľáŁáá áĽá onEdge á ááá áá¨á¤áśá˝ áá áĽááľáŹáłááᢠáá á°áá á¨áĽáŞ ááá áá°áá á¨á áľ á¨áááááľá áľ ááᥠmsum áĽá´áľ á¨ááá°áŁ áĽá áĽá፠ááá áĽáááááá˘
- onEdge á ááá á¨áááá áá áľ ááá ááᢠááĽáŤááłááą á áá áááľ áá ááŁáá. áĽáá á áááá á áŠá áŤáá áŤá á¨á°áá á áááá áĽáá¨áááŁáá, áĽá áŤááá áááĽááľ. á¨á°áá á, á áá áĽááľ á ááľ á¨ááá áááá áĽáá¨áááŁáá. á¨áá ᣠáĽá´áąá áĽááááłáá - á¨ááľáá፠ááá á¨áááá ááá ᣠá¨á፠ááá ááá˝ áŤáá˝ á˛áááą ááááŁáá˘
- ááŽá°áľ áŹáá´ááľ áĽáŤááłááąá ááĽá á¨á°áá á áááá áŤá¨áááŁá áĽá áŤááá á áአáá á áŹáá´ááľ áá°áŤáá˘
- dfs á ááá áŤáá˝ áá á¨áá´ááľá áŤáŤááłáá˘
ááźá áá.
INLINE á¨ááá áá áłáŞá
INLINE á¨ááá áá á á áááŞáá á¨ááááŞáŤ á á°ááŁá á ááľáĽ á ááá á¨áᤠá áá áá áłá¨á˘ á¨á°áťá á á°ááŁá á áááááľ áľááá INLINE áŤáááá áĽáľá á á ááłááľ ááŤáá˝ áá á ááŤáľá°áá áááł áááá áá á áááźáááᢠá áľááá á°á¨á á°ááŁáŤáśáš á ááľ á áááľ ááľáŤáľ áĽááłááŁá¸á áááľ ááľáĽ á ááľááŁáľ áá á áŁá á áľáá¨ááᢠáĽáááł áĽááłáᣠáá á¨áá¤á˝á˛ áľáŞáľ áŁáá áá áá˝á áá ááá á¨ááłá ááŠááľ á ááá á¨áá˘
á¨GHC Core áá ááľá á ááľ áłáááľ áŤáá áĽáŠ á ááᣠá˝ááŠá á á ááľ ááľáá ááá˝ á áá INLINE ááľá°áŤá¨á á˝áŤááᢠá á°áá°á áá á GHC 8.4.4 áĽá GHC 8.6.5 ááŤá¨á á ááťá˝ á áŤáą áá á ááľá¨á á ááá˘
á Haskell ááŽááŤááá áá áĽáá°áá áŤá ááťáť áŤááĽááá áĽáŹ á áá á áŠá áá áᢠááá áĽáá ááŹá á˘áá á ááťážá˝ á ááłááľ áá áľá á°áľ áá áŤá, áĽá ááĽááą ááá ááľá áľ á¨áĽá áľáŤ áá. áááłá, áĽáá ááľáĽ á°ááŁáŠ á¨ááľ ááá áĽááłáá áľ áĽááááá, ááááŤáąá á á áľáááá áľáŞáľ ááľáĽ áá, áĽá áá áá áááŁáŁáŞá ááá áááľá áľ ááááŤáľ áá.
á¨ááŤáľ áá áá?
á¨ááŤá ááááŽááľ-áŤáá á áááŞááá á¨ááá˝ áááśá˝ áá á°ááŁáŤá á áľáááŤááᣠáĽá ፠á¨ááŽááŤá áá¨á¨áť áá áá˘
áááá á¨á á áŽáľ ááľáá áááŁáá á á°ááŁáŤá ááŽááŤááá áá á°ááŁáŤá áááľ á áááťááᣠáá
á á áááĽáá á¨á á áá
áľ á áá ááłá áá ááááľ áĽááłáá á¨áľáśáá (áá
áŚáł áá áŤá
á á ááĽá áĽáááľ áŁáá¸á áłáłááá˝ ááŤá¨á áĽááłá áĽáá°ááłáá
áĽááá á á áá°ááá ᣠáá á ááą áá) á á°ááŁáŤá ááŽááŤááá áá áááłá°á á á á á¨ááľá˝ááľ áĽááśá˝) ááá áá á áŁá
áá ááááá˝ áŤáá áááľ á á°áᨠááአáá
áá ááłá á á°ááŁá á¨áááá á áľá°áááá ááá á áľá°ááááá˘
ááá: hab.com