์ง๋ ์ฌ๋ฆ์ ์ ๊ฐ ์ฐธ์ฌํ๋
Google Summer of Code 2019์ ์ฐธ์ฌํ์ฌ ๋์๊ด ๋ด์์ ํ๋ก์ ํธ๋ฅผ ์งํํ์ต๋๋ค.
์ด๋ฒ ํฌ์คํ ์์๋ Haskell์์ ๊ทธ๋ํ์ ์ด๋ถ์ฑ์ ํ์ธํ๋ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค. ์๊ณ ๋ฆฌ์ฆ์ด ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ฒ ์ค ํ๋์์๋ ๋ถ๊ตฌํ๊ณ ์ด๋ฅผ ๊ธฐ๋ฅ์ ์คํ์ผ๋ก ์๋ฆ๋ต๊ฒ ๊ตฌํํ๋ ค๋ฉด ์ฌ๋ฌ ๋ฒ์ ๋ฐ๋ณต์ด ํ์ํ๊ณ ๊ฝค ๋ง์ ์์ ์ด ํ์ํ์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์ ๋ ๋ชจ๋๋ ๋ณํ๊ธฐ๋ฅผ ์ฌ์ฉํ ๊ตฌํ์ ๊ฒฐ์ ํ์ต๋๋ค.
์ฑ๋ช ์
์ ์ด๋ฆ์ Vasily Alferov์ด๊ณ ์ํธํํ
๋ฅด๋ถ๋ฅดํฌ HSE์ XNUMXํ๋
ํ์์
๋๋ค. ์ ๊ฐ ์์ ์ ๋ธ๋ก๊ทธ์ ์ผ๋
์๊ณ ๋ฆฌ์ฆ ๊ตฌํ์ ๋ํด
๋จธ๋ฆฌ๋ง
ํ๋ก๊ทธ๋จ์ ์ฐธ์ฌํ๋ ํ์๋ค์ ๋ธ๋ก๊ทธ ํ๋์ ์ ๊ทน ๊ถ์ฅํฉ๋๋ค. ๊ทธ๋ค์ ๋์๊ฒ ๋ธ๋ก๊ทธ ํ๋ซํผ์ ์ ๊ณตํ์ต๋๋ค
๋ฌธ์ ์ ์ฝ๋๊ฐ ํฌํจ๋ Pull Request๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
๋ด ์์
๊ฒฐ๊ณผ๋ฅผ ์ฝ์ ์ ์์ต๋๋ค(์์ด).
์ด ๊ฒ์๋ฌผ์ ๋ ์๊ฐ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ ์ต์ํด์ง๋๋ก ์๋๋์์ง๋ง, ๋๊ฐ ๋๋ฉด ์ฌ์ฉ๋ ๋ชจ๋ ์ฉ์ด๋ฅผ ๊ธฐ์ตํด๋ด๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค.
๊ทธ๋ํ์ ์ด๋ถ์ฑ ํ์ธ
๊ทธ๋ํ์ ์ด๋ถ์ฑ์ ํ์ธํ๋ ์๊ณ ๋ฆฌ์ฆ์ ์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฅ ๊ฐ๋จํ ๊ทธ๋ํ ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋๋ก ์๊ณ ๋ฆฌ์ฆ ๊ฐ์ข์์ ์ ๊ณต๋ฉ๋๋ค. ๊ทธ์ ์์ด๋์ด๋ ๊ฐ๋จํฉ๋๋ค. ๋จผ์ ์ด๋ป๊ฒ๋ ์ผ์ชฝ์ด๋ ์ค๋ฅธ์ชฝ ๊ณต์ ์ ์ ์ ์ ๋ฐฐ์นํ๊ณ ์ถฉ๋ํ๋ ๊ฐ์ฅ์๋ฆฌ๊ฐ ๋ฐ๊ฒฌ๋๋ฉด ๊ทธ๋ํ๊ฐ ์ด๋ถํ์ด ์๋๋ผ๊ณ ์ฃผ์ฅํฉ๋๋ค.
์กฐ๊ธ ๋ ์์ธํ ์ค๋ช ํ์๋ฉด ๋จผ์ ์ผ์ชฝ ๊ณต์ ์ ์ ์ ์ ๋ฐฐ์นํฉ๋๋ค. ๋ถ๋ช ํ ์ด ๊ผญ์ง์ ์ ๋ชจ๋ ์ด์์ ์ค๋ฅธ์ชฝ ์ฝ์ ์์ด์ผ ํฉ๋๋ค. ๋ํ, ์ด ์ ์ ์ ์ด์์ ๋ชจ๋ ์ด์์ ์ผ์ชฝ ์ฝ์ ์์ด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ ์์ํ ์ ์ ์ ์ฐ๊ฒฐ๋ ๊ตฌ์ฑ ์์์ ์ด์์ ํ ๋นํ์ง ์์ ์ ์ ์ด ์ฌ์ ํ ์๋ ํ ์ ์ ์ ๊ณต์ ๋ฅผ ๊ณ์ ํ ๋นํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ฐ๊ฒฐ๋ ๋ชจ๋ ๊ตฌ์ฑ ์์์ ๋ํด ์ด ์์ ์ ๋ฐ๋ณตํฉ๋๋ค.
๋์ผํ ๋ถํ ์ ์ํ๋ ์ ์ ์ฌ์ด์ ๊ฐ์ ์ด ์๋ ๊ฒฝ์ฐ ๊ทธ๋ํ์์ ํ์ ์ฌ์ดํด์ ์ฐพ๋ ๊ฒ์ด ์ด๋ ต์ง ์์ต๋๋ค. ์ด๋ ์ด๋ถ ๊ทธ๋ํ์์๋ ๋ถ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด ๋๋ฆฌ ์๋ ค์ ธ ์์ต๋๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฌ๋ฐ๋ฅธ ๋ถํ ์ด ์์ผ๋ฉฐ ์ด๋ ๊ทธ๋ํ๊ฐ ์ด๋ถํ์์ ์๋ฏธํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ด ์๊ณ ๋ฆฌ์ฆ์ ๋ค์์ ์ฌ์ฉํ์ฌ ๊ตฌํ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ ๊ณํ์ ์ธ์ ์ต๋๋ค. ๊น์ด ์ฐ์ ๊ฒ์์ ์ฌ์ฉํ์ฌ ๊ทธ๋ํ์ ๊ผญ์ง์ ์ ํ์ํ๊ณ ๊ณต์ ๋ฅผ ํ ๋นํ์ฌ ๊ฐ์ฅ์๋ฆฌ๋ฅผ ๋ฐ๋ผ ์ด๋ํ ๋ ๊ณต์ ์ ์๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค. ์ด๋ฏธ ๊ณต์ ๊ฐ ํ ๋น๋ ์ ์ ์ ๊ณต์ ๋ฅผ ํ ๋นํ๋ ค๊ณ ํ๋ฉด ๊ทธ๋ํ๊ฐ ์ด๋ถํ์ด ์๋๋ผ๊ณ ์์ ํ๊ฒ ๋งํ ์ ์์ต๋๋ค. ๋ชจ๋ ๊ผญ์ง์ ์ ๊ณต์ ๊ฐ ํ ๋น๋๊ณ ๋ชจ๋ ๊ฐ์ฅ์๋ฆฌ๋ฅผ ์ดํด๋ณธ ์๊ฐ ์ข์ ํํฐ์ ์ ๊ฐ๊ฒ ๋ฉ๋๋ค.
๊ณ์ฐ์ ์์์ฑ
Haskell์์๋ ๋ชจ๋ ๊ณ์ฐ์ด ๋ค์๊ณผ ๊ฐ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ๊นจ๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ฌ์ค์ด๋ผ๋ฉด ํ๋ฉด์ ์๋ฌด๊ฒ๋ ์ธ์ํ ๋ฐฉ๋ฒ์ด ์์ ๊ฒ์ ๋๋ค. ์กฐ๊ธ๋, ๊นจ๋ํ ๊ณ์ฐ์ด ๋๋ฌด ๊ฒ์ผ๋ฅธ๋ฐ ํ๋๋ ์๋ค ๊นจ๋ํ ๋ฌด์ธ๊ฐ๋ฅผ ๊ณ์ฐํ๋ ์ด์ . ํ๋ก๊ทธ๋จ์์ ๋ฐ์ํ๋ ๋ชจ๋ ๊ณ์ฐ์ ์ด๋ป๊ฒ๋ ๊ฐ์ ๋ก ์ํ๋ฉ๋๋ค. "๋๋ฌ์ด" ๋ชจ๋๋ IO.
๋ชจ๋๋๋ ๊ณ์ฐ์ ํํํ๋ ๋ฐฉ๋ฒ์
๋๋ค. ํจ๊ณผ ํ์ค์ผ์์. ์๋ ๋ฐฉ์์ ์ค๋ช
ํ๋ ๊ฒ์ ์ด ๊ฒ์๋ฌผ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋ฉ๋๋ค. ํ๋ฅญํ๊ณ ๋ช
ํํ ์ค๋ช
์ ์์ด๋ก ์ฝ์ ์ ์์ต๋๋ค.
์ฌ๊ธฐ์๋ IO์ ๊ฐ์ ์ผ๋ถ ๋ชจ๋๋๊ฐ ์ปดํ์ผ๋ฌ ๋ง๋ฒ์ ํตํด ๊ตฌํ๋๋ ๋ฐ๋ฉด, ๊ฑฐ์ ๋ชจ๋ ๋ชจ๋๋๋ ์ํํธ์จ์ด๋ก ๊ตฌํ๋๋ฉฐ ๊ทธ ์์ ๋ชจ๋ ๊ณ์ฐ์ ์์ํ๋ค๋ ์ ์ ์ง์ ํ๊ณ ์ถ์ต๋๋ค.
๋ง์ ํจ๊ณผ๊ฐ ์์ผ๋ฉฐ ๊ฐ๊ฐ ๊ณ ์ ํ ๋ชจ๋๋๊ฐ ์์ต๋๋ค. ์ด๊ฒ์ ๋งค์ฐ ๊ฐ๋ ฅํ๊ณ ์๋ฆ๋ค์ด ์ด๋ก ์ ๋๋ค. ๋ชจ๋ ๋ชจ๋๋๋ ๋์ผํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ค์ ์ธ ๊ฐ์ง ๋ชจ๋๋์ ๋ํด ์ด์ผ๊ธฐํ ๊ฒ์ ๋๋ค:
- ea๋ a ์ ํ์ ๊ฐ์ ๋ฐํํ๊ฑฐ๋ e ์ ํ์ ์์ธ๋ฅผ ๋ฐ์์ํค๋ ๊ณ์ฐ์ ๋๋ค. ์ด ๋ชจ๋๋์ ๋์์ ๋ช ๋ นํ ์ธ์ด์ ์์ธ ์ฒ๋ฆฌ์ ๋งค์ฐ ์ ์ฌํฉ๋๋ค. ์ฆ, ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๊ฑฐ๋ ์ ๋ฌํ ์ ์์ต๋๋ค. ์ฃผ์ ์ฐจ์ด์ ์ ๋ชจ๋๋๋ Haskell์ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์์ ํ ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ตฌํ๋๋ ๋ฐ๋ฉด ๋ช ๋ นํ ์ธ์ด๋ ์ผ๋ฐ์ ์ผ๋ก ์ด์ ์ฒด์ ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ๋ค๋ ๊ฒ์ ๋๋ค.
- ์ํ sa๋ a ์ ํ์ ๊ฐ์ ๋ฐํํ๊ณ s ์ ํ์ ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํ์ ์ก์ธ์คํ ์ ์๋ ๊ณ์ฐ์ ๋๋ค.
- ์๋ง. Maybe ๋ชจ๋๋๋ Nothing์ ๋ฐํํจ์ผ๋ก์จ ์ธ์ ๋ ์ง ์ค๋จ๋ ์ ์๋ ๊ณ์ฐ์ ํํํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ Maybe ์ ํ์ ๋ํ MonadPlus ํด๋์ค์ ๊ตฌํ์ ๋ํด ์ด์ผ๊ธฐํ ๊ฒ์ ๋๋ค. ์ด๋ ๋ฐ๋ ํจ๊ณผ๋ฅผ ํํํฉ๋๋ค. ์ด๋ ํน์ ๊ฐ์ ๋ฐํํจ์ผ๋ก์จ ์ธ์ ๋ ์ง ์ค๋จ๋ ์ ์๋ ๊ณ์ฐ์ ๋๋ค.
์๊ณ ๋ฆฌ์ฆ ๊ตฌํ
Graph a์ Bigraph ab๋ผ๋ ๋ ๊ฐ์ง ๋ฐ์ดํฐ ์ ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ๋ a ์ ํ์ ๊ฐ์ผ๋ก ๋ ์ด๋ธ์ด ์ง์ ๋ ์ ์ ์ด ์๋ ๊ทธ๋ํ๋ฅผ ๋ํ๋ด๊ณ , ๋ ๋ฒ์งธ๋ a ์ ํ๊ณผ ์ค๋ฅธ์ชฝ์ ๊ฐ์ผ๋ก ๋ ์ด๋ธ์ด ์ง์ ๋ ์ผ์ชฝ ์ ์ ์ด ์๋ ์ด๋ถ ๊ทธ๋ํ๋ฅผ ๋ํ๋ ๋๋ค. - b ์ ํ์ ๊ฐ์ผ๋ก ๋ ์ด๋ธ์ด ์ง์ ๋ ์ธก๋ฉด ์ ์ .
์ด๋ Alga ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ํ์ด ์๋๋๋ค. Alga์๋ ๋ฐฉํฅ์ด ์๋ ์ด๋ถ ๊ทธ๋ํ์ ๋ํ ํํ์ด ์์ต๋๋ค. ๋ช ํ์ฑ์ ์ํด ์ด์ ๊ฐ์ ์ ํ์ ๋ง๋ค์์ต๋๋ค.
๋ํ ๋ค์ ์๋ช ์ด ์๋ ๋์ฐ๋ฏธ ํจ์๊ฐ ํ์ํฉ๋๋ค.
-- ะกะฟะธัะพะบ ัะพัะตะดะตะน ะดะฐะฝะฝะพะน ะฒะตััะธะฝั.
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)
๊น์ด ์ฐ์ ๊ฒ์ ์ค์ ์ถฉ๋ํ๋ ์์ง๋ฅผ ๋ฐ๊ฒฌํ๋ฉด ํ์ ์ฌ์ดํด์ด ์ฌ๊ท ์คํ ์๋จ์ ์๋ค๋ ๊ฒ์ ์ฝ๊ฒ ์ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ด๋ฅผ ๋ณต์ํ๋ ค๋ฉด ์ฌ๊ท ์คํ๋ถํฐ ๋ง์ง๋ง โโ์ ์ ์ ์ฒซ ๋ฒ์งธ ๋ฐ์๊น์ง ๋ชจ๋ ๊ฒ์ ์๋ผ์ผ ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ๊ฐ ์ ์ ์ ๋ํ ๊ณต์ ๋ฒํธ์ ์ฐ๊ด ๋ฐฐ์ด์ ์ ์งํจ์ผ๋ก์จ ๊น์ด ์ฐ์ ๊ฒ์์ ๊ตฌํํฉ๋๋ค. ์ฌ๊ท ์คํ์ ์ฐ๋ฆฌ๊ฐ ์ ํํ ๋ชจ๋๋์ Functor ํด๋์ค ๊ตฌํ์ ํตํด ์๋์ผ๋ก ์ ์ง ๊ด๋ฆฌ๋ฉ๋๋ค. ๊ฒฝ๋ก์ ๋ชจ๋ ์ ์ ์ ์ฌ๊ท ํจ์์์ ๋ฐํ๋ ๊ฒฐ๊ณผ์ ๋ฃ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
๋์ ์ฒซ ๋ฒ์งธ ์์ด๋์ด๋ ์ฐ๋ฆฌ์๊ฒ ํ์ํ ํจ๊ณผ๋ฅผ ์ ํํ๊ฒ ๊ตฌํํ๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ ์์ชฝ ๋ชจ๋๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด์์ต๋๋ค. ์ ๊ฐ ์์ฑํ ์ฒซ ๋ฒ์งธ ๊ตฌํ์ ์ด ์ต์ ์ ๋งค์ฐ ๊ฐ๊น์ต๋๋ค. ์ฌ์ค, ์ ๋ ํ ์ง์ ์์ ๋ค์ฏ ๊ฐ์ง ๋ค๋ฅธ ๊ตฌํ์ ์ํํ๊ณ ๊ฒฐ๊ตญ ๋ค๋ฅธ ๊ตฌํ์ผ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
์ฒซ์งธ, ๊ณต์ ์๋ณ์์ ์ฐ๊ด ๋ฐฐ์ด์ ์ ์งํด์ผ ํฉ๋๋ค. ์ด๋ State์ ๊ดํ ๊ฒ์
๋๋ค. ๋์งธ, ์ถฉ๋์ด ๊ฐ์ง๋๋ฉด ์ค์งํ ์ ์์ด์ผ ํฉ๋๋ค. ์ด๋ ๋ ์ค ํ๋๋ฅผ ์ํ Monad์ผ ์๋ ์๊ณ Maybe๋ฅผ ์ํ MonadPlus์ผ ์๋ ์์ต๋๋ค. ์ฃผ์ ์ฐจ์ด์ ์ ๊ณ์ฐ์ด ์ค์ง๋์ง ์์ ๊ฒฝ์ฐ ๋ ์ค ํ๋๊ฐ ๊ฐ์ ๋ฐํํ ์ ์๊ณ Maybe๋ ์ด ๊ฒฝ์ฐ ์ด์ ๋ํ ์ ๋ณด๋ง ๋ฐํํ๋ค๋ ๊ฒ์
๋๋ค. ์ฑ๊ณต์ ์ํด ๋ณ๋์ ๊ฐ์ด ํ์ํ์ง ์์ผ๋ฏ๋ก(์ด๋ฏธ State์ ์ ์ฅ๋์ด ์์) Maybe๋ฅผ ์ ํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ ๋ชจ๋๋์ ํจ๊ณผ๋ฅผ ๊ฒฐํฉํด์ผ ํ๋ ์๊ฐ, ๊ทธ๋ค์ ๋์ต๋๋ค.
์ ์ด๋ ๊ฒ ๋ณต์กํ ์ ํ์ ์ ํํ์ต๋๊น? ๋ ๊ฐ์ง ์ด์ . ์ฒซ์งธ, ๊ตฌํ์ ๋ช ๋ นํ๊ณผ ๋งค์ฐ ์ ์ฌํฉ๋๋ค. ๋์งธ, ํ์ ๋ฃจํ๋ฅผ ๋ณต์ํ๊ธฐ ์ํด ์ฌ๊ท์์ ๋์์ฌ ๋ ์ถฉ๋์ด ๋ฐ์ํ ๊ฒฝ์ฐ ๋ฐํ ๊ฐ์ ์กฐ์ํด์ผ ํ๋๋ฐ, ์ด๋ Maybe ๋ชจ๋๋์์ ํจ์ฌ ์ฝ์ต๋๋ค.
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์ด๋ฌํ ๊ตฌํ์ ์ป์ต๋๋ค.
{-# 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)
where ๋ธ๋ก์ ์๊ณ ๋ฆฌ์ฆ์ ํต์ฌ์ ๋๋ค. ๋๋ ๊ทธ ์์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ์ค๋ช ํ๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค.
- inVertex๋ ์ฒ์์ผ๋ก ์ ์ ์ ๋ฐฉ๋ฌธํ๋ ๊น์ด ์ฐ์ ํ์์ ์ผ๋ถ์ ๋๋ค. ์ฌ๊ธฐ์๋ ์ ์ ์ ๊ณต์ ๋ฒํธ๋ฅผ ํ ๋นํ๊ณ ๋ชจ๋ ์ด์์์ onEdge๋ฅผ ์คํํฉ๋๋ค. ์ด๊ฒ์ ๋ํ ํธ์ถ ์คํ์ ๋ณต์ํ๋ ๊ณณ์ด๊ธฐ๋ ํฉ๋๋ค. msum์ด ๊ฐ์ ๋ฐํํ๋ฉด ์ ์ v๋ฅผ ๊ฑฐ๊ธฐ์ ํธ์ํฉ๋๋ค.
- onEdge๋ ์ฐ๋ฆฌ๊ฐ ์ฃ์ง๋ฅผ ๋ฐฉ๋ฌธํ๋ ๋ถ๋ถ์ ๋๋ค. ๊ฐ ๊ฐ์ฅ์๋ฆฌ์ ๋ํด ๋ ๋ฒ ํธ์ถ๋ฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ฐ๋ํธ ์ ์ ์ ๋ฐฉ๋ฌธํ๋์ง ํ์ธํ๊ณ ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ๋ฐฉ๋ฌธํฉ๋๋ค. ๋ฐฉ๋ฌธํ๋ฉด ๊ฐ์ฅ์๋ฆฌ๊ฐ ์ถฉ๋ํ๋์ง ํ์ธํฉ๋๋ค. ๋ง์ฝ ๊ทธ๋ ๋ค๋ฉด, ์ฐ๋ฆฌ๋ ์ฌ๊ท ์คํ์ ๋งจ ์ ๊ฐ์ ๋ฐํํ๋ฉฐ, ๋ฐํ ์ ๋ค๋ฅธ ๋ชจ๋ ์ ์ ์ด ๋ฐฐ์น๋ฉ๋๋ค.
- processVertex๋ ๊ฐ ๊ผญ์ง์ ์ ๋ฐฉ๋ฌธํ๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๊ณ ๋ฐฉ๋ฌธํ์ง ์์ ๊ฒฝ์ฐ inVertex๋ฅผ ์คํํฉ๋๋ค.
- dfs๋ ๋ชจ๋ ์ ์ ์์ processVertex๋ฅผ ์คํํฉ๋๋ค.
๊ทธ๊ฒ ๋ค์ผ.
INLINE์ด๋ผ๋ ๋จ์ด์ ์ญ์ฌ
INLINE์ด๋ผ๋ ๋จ์ด๋ ์๊ณ ๋ฆฌ์ฆ์ ์ฒซ ๋ฒ์งธ ๊ตฌํ์๋ ์์์ง๋ง ๋์ค์ ๋ํ๋ฌ์ต๋๋ค. ๋ ๋์ ๊ตฌํ์ ์ฐพ์ผ๋ ค๊ณ ๋ ธ๋ ฅํ์ ๋ INLINE์ด ์๋ ๋ฒ์ ์ด ์ผ๋ถ ๊ทธ๋ํ์์ ๋์ ๋๊ฒ ๋๋ ค์ง๋ ๊ฒ์ ๋ฐ๊ฒฌํ์ต๋๋ค. ๊ธฐ๋ฅ์ด ์๋ฏธ์ ๋์ผํ๊ฒ ์๋ํด์ผ ํ๋ค๋ ์ ์ ๊ณ ๋ คํ๋ฉด ์ด๋ ๋งค์ฐ ๋๋์ต๋๋ค. ๋ ์ด์ํ๊ฒ๋, ๋ค๋ฅธ ๋ฒ์ ์ GHC๋ฅผ ์ฌ์ฉํ๋ ๋ค๋ฅธ ์ปดํจํฐ์์๋ ๋์ ๋๋ ์ฐจ์ด๊ฐ ์์์ต๋๋ค.
์ผ์ฃผ์ผ ๋์ GHC Core ์ถ๋ ฅ์ ์ฝ์ ํ ๋ช ์์ ์ธ INLINE ํ ์ค๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์์ต๋๋ค. GHC 8.4.4์ GHC 8.6.5 ์ฌ์ด์ ์ด๋ ์์ ์์ ์ต์ ํ ํ๋ก๊ทธ๋จ์ ์ด ์์ ์ ์์ฒด์ ์ผ๋ก ์ค๋จํ์ต๋๋ค.
๋๋ Haskell ํ๋ก๊ทธ๋๋ฐ์์ ๊ทธ๋ฐ ๋จผ์ง๋ฅผ ๋ง๋ ๊ฒ์ด๋ผ๊ณ ๋ ์์ํ์ง ๋ชปํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ค๋๋ ์๋ ์ตํฐ๋ง์ด์ ๋ ๋๋๋ก ์ค์๋ฅผ ํ๋ฉฐ, ๊ทธ๋ค์๊ฒ ํํธ๋ฅผ ์ฃผ๋ ๊ฒ์ด ์ฐ๋ฆฌ์ ์๋ฌด์ ๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ํจ์๊ฐ ๋ช ๋ นํ ๋ฒ์ ์์ ์ธ๋ผ์ธ๋๊ธฐ ๋๋ฌธ์ ์ธ๋ผ์ธ๋์ด์ผ ํ๋ค๋ ๊ฒ์ ์๊ณ ์์ผ๋ฉฐ ์ด๊ฒ์ด ์ปดํ์ผ๋ฌ์ ํํธ๋ฅผ ์ ๊ณตํ๋ ์ด์ ์ ๋๋ค.
๋ค์์ ๋ฌด์จ ์ผ์ด ์์๋๊ฑฐ์ผ?
๊ทธ๋ฐ ๋ค์ ๋ค๋ฅธ ๋ชจ๋๋์ ํจ๊ป Hopcroft-Karp ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๊ณ , ๊ทธ๊ฒ์ด ํ๋ก๊ทธ๋จ์ ๋์ด์์ต๋๋ค.
Google Summer of Code ๋๋ถ์ ์ ๋ ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ๋ํ ์ค๋ฌด ๊ฒฝํ์ ์ป์๊ณ , ์ด๋ ๋ค์ ์ฌ๋ฆ์ Jane Street์์ ์ธํด์ญ์ ํ๋ ๋ฐ ๋์์ด ๋์์ ๋ฟ๋ง ์๋๋ผ(Habr์ ์ง์์ด ํ๋ถํ ์ฒญ์ค๋ค ์ฌ์ด์์๋ ์ด ๊ณณ์ด ์ผ๋ง๋ ์ ์๋ ค์ ธ ์๋์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง, ํจ์ํ ํ๋ก๊ทธ๋๋ฐ์ ์ฐธ์ฌํ๊ธฐ ์ํด ์ฌ๋ฆ์ ๋ณด๋ผ ์ ์๋ ์์์ ๊ณณ ์ค) ๋ฟ๋ง ์๋๋ผ ์ ํต์ ์ธ ์ธ์ด์์์ ๊ฒฝํ๊ณผ๋ ์๋นํ ๋ค๋ฅธ ์ด ํจ๋ฌ๋ค์์ ์ค์ ๋ก ์ ์ฉํ๋ ๋ฉ์ง ์ธ๊ณ๋ฅผ ์๊ฐํ์ต๋๋ค.
์ถ์ฒ : habr.com