Skip to content

Commit 1f487d3

Browse files
committed
clean up day 17
1 parent b95ad7e commit 1f487d3

File tree

1 file changed

+107
-18
lines changed

1 file changed

+107
-18
lines changed

2024/AOC2024/Day17.hs

Lines changed: 107 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# OPTIONS_GHC -Wno-orphans #-}
12
{-# OPTIONS_GHC -Wno-unused-imports #-}
23
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
34

@@ -20,14 +21,21 @@
2021
-- types @_ :~> _@ with the actual types of inputs and outputs of the
2122
-- solution. You can delete the type signatures completely and GHC
2223
-- will recommend what should go in place of the underscores.
23-
module AOC2024.Day17 (
24-
day17a,
25-
day17b,
26-
)
24+
module AOC2024.Day17
2725
where
2826

29-
import AOC.Prelude
27+
-- (
28+
-- day17a,
29+
-- day17b,
30+
-- )
31+
32+
import AOC.Prelude hiding (Finite, modulo, packFinite)
33+
import Control.Monad.Primitive
34+
import Control.Monad.ST
3035
import Data.Bits
36+
import qualified Data.Conduino as C
37+
import qualified Data.Conduino.Combinators as C
38+
import Data.Finite.Integral hiding (shift)
3139
import qualified Data.Graph.Inductive as G
3240
import qualified Data.IntMap as IM
3341
import qualified Data.IntMap.NonEmpty as IM
@@ -39,37 +47,110 @@ import qualified Data.List.PointedList.Circular as PLC
3947
import qualified Data.Map as M
4048
import qualified Data.Map.NonEmpty as NEM
4149
import qualified Data.OrdPSQ as PSQ
50+
import Data.Primitive.MutVar
51+
import Data.STRef
4252
import qualified Data.Sequence as Seq
4353
import qualified Data.Sequence.NonEmpty as NESeq
4454
import qualified Data.Set as S
4555
import qualified Data.Set.NonEmpty as NES
4656
import qualified Data.Text as T
4757
import qualified Data.Vector as V
58+
import qualified Data.Vector.Mutable.Sized as SMV
59+
import qualified Data.Vector.Sized as SV
60+
import qualified Data.Vector.Storable.Mutable.Sized as SMVS
61+
import qualified Data.Vector.Storable.Sized as SVS
4862
import qualified Linear as L
4963
import qualified Numeric.Lens as L
5064
import qualified Text.Megaparsec as P
5165
import qualified Text.Megaparsec.Char as P
5266
import qualified Text.Megaparsec.Char.Lexer as PP
5367

54-
day17a :: _ :~> _
68+
day17a :: _ :~> [Int]
5569
day17a =
5670
MkSol
5771
{ sParse = parseMaybe' do
58-
a <- "Register A: " *> pDecimal
59-
P.newline
60-
b <- "Register B: " *> pDecimal
61-
P.newline
62-
c <- "Register C: " *> pDecimal
63-
P.newline
72+
a <- "Register A: " *> pDecimal <* P.newline
73+
b <- "Register B: " *> pDecimal <* P.newline
74+
c <- "Register C: " *> pDecimal <* P.newline
6475
P.newline
6576
d <- "Program: " *> (pDecimal `sepBy'` ",")
66-
pure (a, b, c, d)
77+
p <- case parseProgram d of
78+
Nothing -> fail "Bad program"
79+
Just p -> pure p
80+
pure (a, b, c, p)
6781
, sShow = intercalate "," . map show
68-
, sSolve =
69-
noFail $ \(a, b, c, p :: [Int]) ->
70-
go 0 (V3 a b c) (Seq.fromList p)
82+
, sSolve = \(a, b, c, instrs) -> do
83+
pure . map fromIntegral $ stepProg instrs (V3 a b c)
7184
}
7285

86+
data Combo
87+
= CLiteral (Finite Word 4)
88+
| CReg (Finite Word 3)
89+
deriving stock (Show, Eq, Ord)
90+
91+
data Instr
92+
= ADV Combo
93+
| BXL (Finite Word 8)
94+
| BST Combo
95+
| JNZ (Finite Word 4)
96+
| BXC
97+
| OUT Combo
98+
| BDV Combo
99+
| CDV Combo
100+
deriving stock (Show, Eq, Ord)
101+
102+
comboParser :: Finite Word 7 -> Combo
103+
comboParser = either CLiteral CReg . separateSum
104+
105+
instrParser :: Finite Word 8 -> Finite Word 8 -> Maybe Instr
106+
instrParser i =
107+
SV.fromTuple @_ @8
108+
( fmap (ADV . comboParser) . strengthen
109+
, Just . BXL
110+
, fmap (BST . comboParser) . strengthen
111+
, Just . JNZ . snd . separateProduct @2 @4
112+
, const $ Just BXC
113+
, fmap (OUT . comboParser) . strengthen
114+
, fmap (BDV . comboParser) . strengthen
115+
, fmap (CDV . comboParser) . strengthen
116+
)
117+
`SV.index` fromIntegral i
118+
119+
parseProgram :: [Int] -> Maybe (SV.Vector 8 Instr)
120+
parseProgram xs = do
121+
xsVec <- SV.fromList @16 =<< traverse (packFinite . fromIntegral) xs
122+
SV.generateM \i ->
123+
instrParser (xsVec `SV.index` combineProduct (0, i)) (xsVec `SV.index` combineProduct (1, i))
124+
125+
readComboV3 :: Combo -> V3 Word -> Word
126+
readComboV3 = \case
127+
CLiteral l -> \_ -> fromIntegral l
128+
CReg 0 -> \(V3 a _ _) -> a
129+
CReg 1 -> \(V3 _ b _) -> b
130+
CReg 2 -> \(V3 _ _ c) -> c
131+
_ -> undefined
132+
133+
stepProg :: SV.Vector 8 Instr -> V3 Word -> [Finite Word 8]
134+
stepProg tp = go' 0
135+
where
136+
go' :: Finite Word 8 -> V3 Word -> [Finite Word 8]
137+
go' i v@(V3 a b c) = case tp `SV.index` fromIntegral i of
138+
ADV r -> withStep $ V3 (a `div` (2 ^ combo r)) b c
139+
BXL l -> withStep $ V3 a (b `xor` fromIntegral l) c
140+
BST r -> withStep $ V3 a (combo r `mod` 8) c
141+
JNZ l
142+
| a == 0 -> withStep v
143+
| otherwise -> go' (weakenN l) v
144+
BXC -> withStep $ V3 a (b `xor` c) c
145+
OUT r -> modulo (combo r) : withStep v
146+
BDV r -> withStep $ V3 a (a `div` (2 ^ combo r)) c
147+
CDV r -> withStep $ V3 a b (a `div` (2 ^ combo r))
148+
where
149+
combo = flip readComboV3 v
150+
withStep
151+
| i == maxBound = const []
152+
| otherwise = go' (succ i)
153+
73154
go :: Int -> V3 Int -> Seq Int -> [Int]
74155
-- go i (V3 a b c) tp = case (,) <$> Seq.lookup i tp <*> Seq.lookup (i + 1) tp of
75156
go i (V3 a b c) tp = case (,) <$> Seq.lookup i tp <*> Seq.lookup (i + 1) tp of
@@ -158,10 +239,18 @@ go i (V3 a b c) tp = case (,) <$> Seq.lookup i tp <*> Seq.lookup (i + 1) tp of
158239
day17b :: _ :~> _
159240
day17b =
160241
MkSol
161-
{ sParse = sParse day17a
242+
{ sParse = parseMaybe' do
243+
_ <- "Register A: " *> pDecimal @Int
244+
P.newline
245+
_ <- "Register B: " *> pDecimal @Int
246+
P.newline
247+
_ <- "Register C: " *> pDecimal @Int
248+
P.newline
249+
P.newline
250+
"Program: " *> (pDecimal `sepBy'` ",")
162251
, sShow = show
163252
, sSolve =
164-
\(_, _, _, p :: [Int]) -> listToMaybe do
253+
\p -> listToMaybe do
165254
option <- stepBackwards (reverse p)
166255
guard $ go 0 (V3 option 0 0) (Seq.fromList p) == p
167256
pure option

0 commit comments

Comments
 (0)