|
|
|
@ -1,38 +1,19 @@
|
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
module Bag where
|
|
|
|
|
|
|
|
|
|
import Data.Bifunctor
|
|
|
|
|
import qualified Data.Text as T
|
|
|
|
|
import Data.Tuple
|
|
|
|
|
|
|
|
|
|
type Bag = (String, [(String, Int)])
|
|
|
|
|
|
|
|
|
|
findWithContent :: [Bag] -> String -> [String]
|
|
|
|
|
findWithContent bags target = map first . filter (elem target . second) . map (mapSecond $ map first) $ bags
|
|
|
|
|
|
|
|
|
|
bagSpec :: String -> Bag
|
|
|
|
|
bagSpec = mapFirst T.unpack . mapSecond contents . breakNoPrefix (T.pack " bags contain ") . T.pack
|
|
|
|
|
bagSpec = bimap T.unpack contents . breakNoPrefix " bags contain " . T.pack
|
|
|
|
|
|
|
|
|
|
contents :: T.Text -> [(String, Int)]
|
|
|
|
|
contents c
|
|
|
|
|
| c == (T.pack "no other bags.") = []
|
|
|
|
|
| otherwise = map (mapSecond read . both T.unpack . swap . breakNoPrefix spc . T.strip . first . T.breakOnEnd spc) . T.splitOn (T.pack ",") $ T.init c
|
|
|
|
|
where spc = T.pack " "
|
|
|
|
|
| c == "no other bags." = []
|
|
|
|
|
| otherwise = map (bimap T.unpack (read . T.unpack) . swap . breakNoPrefix " " . T.strip . fst . T.breakOnEnd " ") . T.splitOn "," $ T.init c
|
|
|
|
|
|
|
|
|
|
breakNoPrefix :: T.Text -> T.Text -> (T.Text, T.Text)
|
|
|
|
|
breakNoPrefix prefix text = (a, T.drop (T.length prefix) b) where (a, b) = T.breakOn prefix text
|
|
|
|
|
|
|
|
|
|
first :: (a, b) -> a
|
|
|
|
|
first (a, b) = a
|
|
|
|
|
|
|
|
|
|
second :: (a, b) -> b
|
|
|
|
|
second (a, b) = b
|
|
|
|
|
|
|
|
|
|
mapFirst :: (a -> c) -> (a, b) -> (c, b)
|
|
|
|
|
mapFirst f (a, b) = (f a, b)
|
|
|
|
|
|
|
|
|
|
mapSecond :: (b -> c) -> (a, b) -> (a, c)
|
|
|
|
|
mapSecond f (a, b) = (a, f b)
|
|
|
|
|
|
|
|
|
|
both :: (a -> b) -> (a, a) -> (b, b)
|
|
|
|
|
both f (a, b) = (f a, f b)
|
|
|
|
|
|
|
|
|
|
swap :: (a, b) -> (b, a)
|
|
|
|
|
swap (a,b) = (b,a)
|
|
|
|
|