Day 2, part 2: Optimized solution using HashSet.
This commit is contained in:
parent
a29ce36899
commit
c3276d620d
|
|
@ -2,22 +2,20 @@
|
||||||
-- stack --resolver lts-12.20 --install-ghc script
|
-- stack --resolver lts-12.20 --install-ghc script
|
||||||
module Main where
|
module Main where
|
||||||
|
|
||||||
loopRight :: b -> (b -> Either a b) -> a
|
import Control.Arrow ((***))
|
||||||
loopRight b f = case f b of
|
import qualified Data.List as L
|
||||||
Left a -> a
|
import qualified Data.HashSet as S
|
||||||
Right b' -> loopRight b' f
|
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = interact $ show . \input ->
|
main = interact $ (show .) $ (. lines) $ \codes ->
|
||||||
let codes = lines input :: [[Char]]
|
loopRight (S.empty, L.concatMap deletions codes) $ \(seen, d:ds) ->
|
||||||
in loopRight ([], codes) $ \(seen, c:cs) ->
|
if S.member d seen
|
||||||
case filter (`isSimilarTo` c) seen of
|
then Left (snd d)
|
||||||
[] -> Right (c:seen, cs)
|
else Right (S.insert d seen, ds)
|
||||||
(x:_) -> Left (c, x, foldMap (\(a,b) -> if a == b then [a] else [])
|
|
||||||
(zip c x))
|
|
||||||
|
|
||||||
isSimilarTo :: (Eq a) => [a] -> [a] -> Bool
|
loopRight :: b -> (b -> Either a b) -> a
|
||||||
(x:xs) `isSimilarTo` (y:ys)
|
loopRight b f = either id (`loopRight` f) (f b)
|
||||||
| x == y = xs `isSimilarTo` ys
|
|
||||||
| otherwise = xs == ys
|
deletions :: [a] -> [(Int, [a])]
|
||||||
_ `isSimilarTo` _ = False
|
deletions [] = []
|
||||||
|
deletions (x:xs) = (0, xs) : map ((+1) *** (x:)) (deletions xs)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue