|
1 |
| -{-# OPTIONS_GHC -Wno-unused-imports #-} |
2 |
| -{-# OPTIONS_GHC -Wno-unused-top-binds #-} |
3 |
| - |
4 | 1 | -- |
|
5 | 2 | -- Module : AOC2024.Day22
|
6 | 3 | -- License : BSD3
|
|
9 | 6 | -- Portability : non-portable
|
10 | 7 | --
|
11 | 8 | -- Day 22. See "AOC.Solver" for the types used in this module!
|
12 |
| --- |
13 |
| --- After completing the challenge, it is recommended to: |
14 |
| --- |
15 |
| --- * Replace "AOC.Prelude" imports to specific modules (with explicit |
16 |
| --- imports) for readability. |
17 |
| --- * Remove the @-Wno-unused-imports@ and @-Wno-unused-top-binds@ |
18 |
| --- pragmas. |
19 |
| --- * Replace the partial type signatures underscores in the solution |
20 |
| --- types @_ :~> _@ with the actual types of inputs and outputs of the |
21 |
| --- solution. You can delete the type signatures completely and GHC |
22 |
| --- will recommend what should go in place of the underscores. |
23 | 9 | module AOC2024.Day22 (
|
24 | 10 | day22a,
|
25 | 11 | day22b,
|
26 | 12 | )
|
27 | 13 | where
|
28 | 14 |
|
29 |
| -import AOC.Prelude |
30 |
| -import Data.Bits |
31 |
| -import qualified Data.Graph.Inductive as G |
| 15 | +import AOC.Common (strictIterate, (!!!)) |
| 16 | +import AOC.Common.Parser (pDecimal, parseMaybe', sepByLines) |
| 17 | +import AOC.Solver (noFail, type (:~>) (..)) |
| 18 | +import Data.Bits (Bits (shift, xor, (.&.))) |
| 19 | +import Data.Foldable (Foldable (toList)) |
32 | 20 | import qualified Data.IntMap as IM
|
33 |
| -import qualified Data.IntMap.NonEmpty as NEIM |
34 |
| -import qualified Data.IntSet as IS |
35 |
| -import qualified Data.IntSet.NonEmpty as NEIS |
36 |
| -import qualified Data.List.NonEmpty as NE |
37 |
| -import qualified Data.List.PointedList as PL |
38 |
| -import qualified Data.List.PointedList.Circular as PLC |
39 |
| -import qualified Data.Map as M |
40 |
| -import qualified Data.Map.NonEmpty as NEM |
41 |
| -import qualified Data.OrdPSQ as PSQ |
42 |
| -import qualified Data.Sequence as Seq |
43 |
| -import qualified Data.Sequence.NonEmpty as NESeq |
44 |
| -import qualified Data.Set as S |
45 |
| -import qualified Data.Set.NonEmpty as NES |
46 |
| -import qualified Data.Text as T |
47 |
| -import qualified Data.Vector as V |
48 |
| -import qualified Linear as L |
49 |
| -import qualified Text.Megaparsec as P |
50 |
| -import qualified Text.Megaparsec.Char as P |
51 |
| -import qualified Text.Megaparsec.Char.Lexer as PP |
52 |
| - |
53 |
| -day22a :: _ :~> _ |
54 |
| -day22a = |
55 |
| - MkSol |
56 |
| - { sParse = |
57 |
| - parseMaybe' $ |
58 |
| - sepByLines pDecimal |
59 |
| - , -- noFail $ |
60 |
| - -- lines |
61 |
| - sShow = show |
62 |
| - , sSolve = |
63 |
| - noFail $ |
64 |
| - sum . map ((!! 2000) . iterate step) |
65 |
| - } |
| 21 | +import Safe.Foldable (maximumMay) |
66 | 22 |
|
67 | 23 | step :: Int -> Int
|
68 |
| -step n = n''' |
| 24 | +step = prune . phase3 . prune . phase2 . prune . phase1 |
69 | 25 | where
|
70 |
| - n' = prune $ (n `shift` 6) `xor` n |
71 |
| - n'' = prune $ (n' `shift` (-5)) `xor` n' |
72 |
| - n''' = prune $ (n'' `shift` 11) `xor` n'' |
| 26 | + phase1 n = (n `shift` 6) `xor` n |
| 27 | + phase2 n = (n `shift` (-5)) `xor` n |
| 28 | + phase3 n = (n `shift` 11) `xor` n |
73 | 29 | prune = (.&. 16777215)
|
74 | 30 |
|
75 |
| -day22b :: _ :~> _ |
| 31 | +day22a :: [Int] :~> Int |
| 32 | +day22a = |
| 33 | + MkSol |
| 34 | + { sParse = parseMaybe' $ sepByLines pDecimal |
| 35 | + , sShow = show |
| 36 | + , sSolve = noFail $ sum . map ((!!! 2000) . strictIterate step) |
| 37 | + } |
| 38 | + |
| 39 | +day22b :: [Int] :~> Int |
76 | 40 | day22b =
|
77 | 41 | MkSol
|
78 | 42 | { sParse = sParse day22a
|
79 | 43 | , sShow = show
|
80 |
| - , sSolve = |
81 |
| - noFail $ \xs -> |
82 |
| - let serieses = |
83 |
| - xs <&> \x -> |
84 |
| - let ps = take 2000 $ map (`mod` 10) $ iterate step x |
85 |
| - dPs = zipWith (\p0 p1 -> (p1, p1 - p0)) ps (drop 1 ps) |
86 |
| - windows = slidingWindows 4 dPs <&> \w -> (encodeSeq $ snd <$> w, fst $ last (toList w)) |
87 |
| - seqMap = IM.fromListWith (const id) windows |
88 |
| - in seqMap |
89 |
| - bests = toList $ IM.unionsWith (+) serieses |
90 |
| - in maximum bests |
91 |
| - -- bests = M.unionsWith (<>) $ map (fmap (:[])) serieses |
92 |
| - -- in maximumBy (comparing (sum . snd)) (M.toList bests) |
| 44 | + , sSolve = maximumMay . toList . IM.unionsWith (+) . map genSeries |
93 | 45 | }
|
94 | 46 | where
|
95 |
| - encodeSeq = sum . zipWith (\i x -> x * 19^(i :: Int)) [0..] . map (+ 9) . toList |
| 47 | + encodeSeq = sum . zipWith (\i x -> x * 19 ^ (i :: Int)) [0 ..] . map (+ 9) |
| 48 | + genSeries = IM.fromListWith (const id) . chompChomp . take 2000 . map (`mod` 10) . strictIterate step |
| 49 | + where |
| 50 | + chompChomp :: [Int] -> [(Int, Int)] |
| 51 | + chompChomp (a : b : c : d : e : fs) = |
| 52 | + (encodeSeq [da, db, dc, dd], e) : chompChomp (b : c : d : e : fs) |
| 53 | + where |
| 54 | + da = b - a |
| 55 | + db = c - b |
| 56 | + dc = d - c |
| 57 | + dd = e - d |
| 58 | + chompChomp _ = [] |
0 commit comments