@@ -73,9 +73,9 @@ day17a =
73
73
p <- case parseProgram d of
74
74
Nothing -> fail " Bad program"
75
75
Just p -> pure p
76
- pure (a, b, c, p)
76
+ pure (a, b, c, p, fromIntegral <$> d )
77
77
, sShow = intercalate " ," . map show
78
- , sSolve = \ (a, b, c, instrs) -> do
78
+ , sSolve = \ (a, b, c, instrs, _ ) -> do
79
79
pure . map fromIntegral $ stepProg instrs (V3 a b c)
80
80
}
81
81
@@ -161,6 +161,70 @@ stepWith tp out next i !a !b !c = case tp `SV.index` i of
161
161
| i == maxBound = \ _ _ _ -> mempty
162
162
| otherwise = p (i + 1 )
163
163
164
+ -- BST A --- b = a & 111
165
+ -- BXL 6 --- b ^= 110 (6)
166
+ -- CDV B --- c = a >> b
167
+ -- BXC --- b ^= c
168
+ -- BXL 4 --- b ^= 100 (4)
169
+ -- OUT B --- print b
170
+ -- ADV 3 --- a >> 3
171
+ -- JNZ 0
172
+ --
173
+ -- ok maybe we step from the back until the Out (to generate the options), and
174
+ -- then jump from the beginning to the out (to generate the constraints)
175
+ --
176
+ -- so "step backwards" from JNZ 2 to OUT B to generate all possible previous
177
+ -- values of a, then jump from BST A down to OUT B to limit which ones are
178
+ -- possible.
179
+
180
+ searchStep :: SV. Vector 8 Instr -> [Finite 8 ] -> [Word ]
181
+ searchStep tp outs = do
182
+ JNZ 0 <- pure $ tp `SV.index` maxBound
183
+ [CReg _] <- pure [r | OUT r <- toList tp]
184
+ let search a = \ case
185
+ o : os -> do
186
+ a' <- stepBack a
187
+ guard $ stepForward a' == Just o
188
+ search a' os
189
+ [] -> pure a
190
+ search 0 (reverse outs)
191
+ where
192
+ stepForward :: Word -> Maybe (Finite 8 )
193
+ stepForward a0 = getFirst <$> go' 0 a0 0 0
194
+ where
195
+ go' = stepWith tp (\ o _ _ _ _ -> Just (First o)) go'
196
+ stepBack :: Word -> [Word ]
197
+ stepBack = go' maxBound
198
+ where
199
+ go' i a = case tp `SV.index` i of
200
+ ADV r -> do
201
+ a' <- case r of
202
+ CLiteral l -> ((a `shift` fromIntegral l) + ) <$> [0 .. 2 ^ getFinite l - 1 ]
203
+ CReg _ -> []
204
+ go' (pred i) a'
205
+ OUT _ -> pure a
206
+ _ -> go' (pred i) a
207
+
208
+ -- stepProg tp (V3 a0 b0 c0) = stepAll 0 a0 b0 c0
209
+ -- where
210
+ -- stepAll = stepWith tp (\o i a b c -> o : stepAll i a b c) stepAll
211
+
212
+ -- 0 undefined undefined
213
+ -- go' (o : os) = stepWith tp (\r i a b c -> guard (o == r) >> go' os i a b c) \i a b c ->
214
+ -- if i == 0
215
+ -- then go' (o:os) i a undefined undefined
216
+ -- else go' (o:os) i a b c
217
+
218
+ -- where
219
+ -- search a = \case
220
+ -- [] -> pure a
221
+ -- o : os -> do
222
+ -- a' <- ((a `shift` 3) +) <$> [0 .. 7]
223
+ -- let b0 = (a' .&. 7) `xor` 6
224
+ -- let c = a' `shift` (-b0)
225
+ -- guard $ ((b0 `xor` c) `xor` 4) .&. 7 == o
226
+ -- search a' os
227
+
164
228
-- -- | Assumes that:
165
229
-- --
166
230
-- -- 1. Only A is persistent across each "loop"
@@ -237,6 +301,17 @@ stepWith tp out next i !a !b !c = case tp `SV.index` i of
237
301
-- ADV 3 --- a /= 8
238
302
-- JNZ 0
239
303
304
+ -- 2,4, 1,6, 7,5, 4,6, 1,4, 5,5, 0,3, 3,0
305
+ --
306
+ -- BST A --- b = a & 111
307
+ -- BXL 6 --- b ^= 110 (6)
308
+ -- CDV B --- c = a >> b
309
+ -- BXC --- b ^= c
310
+ -- BXL 4 --- b ^= 100 (4)
311
+ -- OUT B --- print b
312
+ -- ADV 3 --- a >> 3
313
+ -- JNZ 0
314
+
240
315
-- The *`adv`* instruction (opcode *`0`*) performs *division*. The
241
316
-- numerator is the value in the `A` register. The denominator is found by
242
317
-- raising 2 to the power of the instruction's *combo* operand. (So, an
@@ -287,22 +362,31 @@ stepWith tp out next i !a !b !c = case tp `SV.index` i of
287
362
288
363
day17b :: _ :~> _
289
364
day17b =
365
+ -- MkSol
366
+ -- { sParse = parseMaybe' do
367
+ -- _ <- "Register A: " *> pDecimal @Int
368
+ -- P.newline
369
+ -- _ <- "Register B: " *> pDecimal @Int
370
+ -- P.newline
371
+ -- _ <- "Register C: " *> pDecimal @Int
372
+ -- P.newline
373
+ -- P.newline
374
+ -- "Program: " *> (pDecimal `sepBy'` ",")
375
+ -- , sShow = show
376
+ -- , sSolve =
377
+ -- \p -> listToMaybe do
378
+ -- option <- stepBackwards (reverse p)
379
+ -- guard $ go 0 (V3 option 0 0) (Seq.fromList p) == p
380
+ -- pure option
290
381
MkSol
291
- { sParse = parseMaybe' do
292
- _ <- " Register A: " *> pDecimal @ Int
293
- P. newline
294
- _ <- " Register B: " *> pDecimal @ Int
295
- P. newline
296
- _ <- " Register C: " *> pDecimal @ Int
297
- P. newline
298
- P. newline
299
- " Program: " *> (pDecimal `sepBy'` " ," )
300
- , sShow = show
301
- , sSolve =
302
- \ p -> listToMaybe do
303
- option <- stepBackwards (reverse p)
304
- guard $ go 0 (V3 option 0 0 ) (Seq. fromList p) == p
305
- pure option
382
+ { sParse = sParse day17a
383
+ , sShow = show
384
+ , sSolve = \ (_, _, _, instrs, o) -> listToMaybe $
385
+ searchStep instrs o
386
+ -- searchStep :: SV.Vector 8 Instr -> [Finite 8] -> [Word]
387
+ -- searchStep tp outs = do
388
+
389
+ -- pure . map fromIntegral $ stepProg instrs (V3 a b c)
306
390
}
307
391
308
392
go :: Int -> V3 Int -> Seq Int -> [Int ]
0 commit comments