module AOC.Challenge.Day06 (
day06a
, day06b
) where
import AOC.Solver ((:~>)(..))
import Data.Bits (setBit, popCount, (.&.), (.|.))
import Data.Char (ord)
import Data.List (foldl')
import Data.List.NonEmpty (NonEmpty)
import Data.List.Split (splitOn)
import Data.Maybe (mapMaybe)
import qualified Data.List.NonEmpty as NE
type CharSet = Word
toCharSet :: [Char] -> CharSet
toCharSet :: [Char] -> CharSet
toCharSet = (CharSet -> Char -> CharSet) -> CharSet -> [Char] -> CharSet
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' CharSet -> Char -> CharSet
forall {a}. Bits a => a -> Char -> a
insertCharSet CharSet
0
where
insertCharSet :: a -> Char -> a
insertCharSet a
cs Char
c = a
cs a -> Int -> a
forall a. Bits a => a -> Int -> a
`setBit` Int
i
where
i :: Int
i = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Char -> Int
ord Char
'a'
answers :: [String] -> Maybe (NonEmpty CharSet)
answers :: [[Char]] -> Maybe (NonEmpty CharSet)
answers = ((NonEmpty [Char] -> NonEmpty CharSet)
-> Maybe (NonEmpty [Char]) -> Maybe (NonEmpty CharSet)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((NonEmpty [Char] -> NonEmpty CharSet)
-> Maybe (NonEmpty [Char]) -> Maybe (NonEmpty CharSet))
-> (([Char] -> CharSet) -> NonEmpty [Char] -> NonEmpty CharSet)
-> ([Char] -> CharSet)
-> Maybe (NonEmpty [Char])
-> Maybe (NonEmpty CharSet)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> CharSet) -> NonEmpty [Char] -> NonEmpty CharSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) [Char] -> CharSet
toCharSet (Maybe (NonEmpty [Char]) -> Maybe (NonEmpty CharSet))
-> ([[Char]] -> Maybe (NonEmpty [Char]))
-> [[Char]]
-> Maybe (NonEmpty CharSet)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> Maybe (NonEmpty [Char])
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty
day06With
:: (CharSet -> CharSet -> CharSet)
-> [[String]] :~> Int
day06With :: (CharSet -> CharSet -> CharSet) -> [[[Char]]] :~> Int
day06With CharSet -> CharSet -> CharSet
f = MkSol :: forall a b.
([Char] -> Maybe a)
-> ((?dyno::DynoMap) => a -> Maybe b) -> (b -> [Char]) -> a :~> b
MkSol
{ sParse :: [Char] -> Maybe [[[Char]]]
sParse = [[[Char]]] -> Maybe [[[Char]]]
forall a. a -> Maybe a
Just ([[[Char]]] -> Maybe [[[Char]]])
-> ([Char] -> [[[Char]]]) -> [Char] -> Maybe [[[Char]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> [[Char]]) -> [[Char]] -> [[[Char]]]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> [[Char]]
lines ([[Char]] -> [[[Char]]])
-> ([Char] -> [[Char]]) -> [Char] -> [[[Char]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Char] -> [[Char]]
forall a. Eq a => [a] -> [a] -> [[a]]
splitOn [Char]
"\n\n"
, sShow :: Int -> [Char]
sShow = Int -> [Char]
forall a. Show a => a -> [Char]
show
, sSolve :: (?dyno::DynoMap) => [[[Char]]] -> Maybe Int
sSolve = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int)
-> ([[[Char]]] -> Int) -> [[[Char]]] -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> ([[[Char]]] -> [Int]) -> [[[Char]]] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([[Char]] -> Maybe Int) -> [[[Char]]] -> [Int]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((NonEmpty CharSet -> Int) -> Maybe (NonEmpty CharSet) -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (CharSet -> Int
forall a. Bits a => a -> Int
popCount (CharSet -> Int)
-> (NonEmpty CharSet -> CharSet) -> NonEmpty CharSet -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CharSet -> CharSet -> CharSet) -> NonEmpty CharSet -> CharSet
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 CharSet -> CharSet -> CharSet
f) (Maybe (NonEmpty CharSet) -> Maybe Int)
-> ([[Char]] -> Maybe (NonEmpty CharSet)) -> [[Char]] -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Char]] -> Maybe (NonEmpty CharSet)
answers)
}
day06a :: [[String]] :~> Int
day06a :: [[[Char]]] :~> Int
day06a = (CharSet -> CharSet -> CharSet) -> [[[Char]]] :~> Int
day06With CharSet -> CharSet -> CharSet
forall a. Bits a => a -> a -> a
(.|.)
day06b :: [[String]] :~> Int
day06b :: [[[Char]]] :~> Int
day06b = (CharSet -> CharSet -> CharSet) -> [[[Char]]] :~> Int
day06With CharSet -> CharSet -> CharSet
forall a. Bits a => a -> a -> a
(.&.)