|
1 | 1 | {-# LANGUAGE OverloadedStrings #-}
|
| 2 | +{-# LANGUAGE ViewPatterns #-} |
2 | 3 |
|
3 | 4 | -- |
|
4 | 5 | -- Module: Day19
|
5 | 6 | -- Description: <https://adventofcode.com/2024/day/19 Day 19: Linen Layout>
|
6 | 7 | module Day19 (solve) where
|
7 | 8 |
|
8 |
| -import Data.Bifunctor (bimap) |
| 9 | +import Control.Parallel.Strategies |
9 | 10 | import Data.Foldable (foldMap')
|
10 |
| -import Data.Monoid (Sum (Sum, getSum)) |
| 11 | +import Data.Monoid (Sum (Sum)) |
11 | 12 | import Data.Text (Text)
|
12 |
| -import Data.Text qualified as T (isSuffixOf, length, lines, null, splitOn, take) |
| 13 | +import Data.Text qualified as T (lines, null, splitOn) |
| 14 | +import Data.Text.Array qualified as A (equal) |
| 15 | +import Data.Text.Internal (Text (Text)) |
| 16 | +import Data.Text.Unsafe qualified as T (lengthWord8) |
13 | 17 | import Data.Vector qualified as V (generate, (!))
|
14 | 18 |
|
15 | 19 | count :: [Text] -> Text -> Int
|
16 |
| -count keys target = getCount $ T.length target |
| 20 | +count keys target = getCount $ T.lengthWord8 target |
17 | 21 | where
|
18 |
| - counts = V.generate (T.length target) getCount |
| 22 | + counts = V.generate (T.lengthWord8 target) getCount |
19 | 23 | getCount 0 = 1
|
20 |
| - getCount i = sum [counts V.! (i - T.length key) | key <- keys, key `T.isSuffixOf` T.take i target] |
| 24 | + getCount i = sum [counts V.! (i - T.lengthWord8 key) | key <- keys, key `isSuffixOfAt` i $ target] |
21 | 25 |
|
22 |
| -solve :: Text -> (Int, Int) |
23 |
| -solve input |
24 |
| - | keys : rest <- T.lines input = |
25 |
| - bimap getSum getSum . foldMap' ((Sum 1,) . Sum) . filter (> 0) $ count (T.splitOn ", " keys) <$> filter (not . T.null) rest |
26 |
| - | otherwise = (0, 0) |
| 26 | +isSuffixOfAt :: Text -> Int -> Text -> Bool |
| 27 | +isSuffixOfAt (Text a aoff alen) n (Text b boff blen) = |
| 28 | + alen <= n && n <= blen && A.equal a aoff b (boff + n - alen) alen |
| 29 | + |
| 30 | +solve :: Text -> Maybe (Int, Int) |
| 31 | +solve (T.lines -> (T.splitOn ", " -> keys) : rest) | not $ any T.null keys = Just (part1, part2) |
| 32 | + where |
| 33 | + (Sum part1, Sum part2) = foldMap' ((Sum 1,) . Sum) . filter (> 0) . parMap rseq (count keys) $ filter (not . T.null) rest |
| 34 | +solve _ = Nothing |
0 commit comments