Skip to content

Commit

Permalink
generalize
Browse files Browse the repository at this point in the history
  • Loading branch information
glguy committed Dec 17, 2024
1 parent b1f17a1 commit 50040e9
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions solutions/src/2024/17.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Data.List (intercalate)
import Data.SBV
(Word64, SWord64, SBool,
(.==), (./=), (.&.), (.&&), sShiftRight, shiftR, xor,
optLexicographic, free, minimize, constrain, getModelValue)
optLexicographic, free, minimize, constrain, getModelValue, sFalse, sTrue, (.||))

-- | >>> :main
-- 2,7,4,7,2,1,7,5,1
Expand All @@ -31,11 +31,11 @@ main =
Program: %u&,%n|]

putStrLn (intercalate "," (map show (run (Machine a b c) program)))

res <- optLexicographic
do a2 <- free "a"
minimize "smallest" a2
constrain (part2 a2 program)
constrain (run2 (SMachine program a2 0 0) program)
case getModelValue "a" res of
Just x -> print (x :: Word64)
Nothing -> fail "no solution"
Expand All @@ -48,22 +48,40 @@ run m0 pgm = go m0 pgm
go m = \case
0 : x : ip' -> go m{ rA = rA m `shiftR` combo x } ip'
1 : x : ip' -> go m{ rB = rB m `xor` x } ip'
2 : x : ip' -> go m{ rB = combo x .&. 7 } ip'
3 : x : ip' -> go m (if rA m == 0 then ip' else drop x pgm)
2 : x : ip' -> go m{ rB = 7 .&. combo x } ip'
4 : _ : ip' -> go m{ rB = rB m `xor` rC m } ip'
5 : x : ip' -> combo x .&. 7 : go m ip'
6 : x : ip' -> go m{ rB = rA m `shiftR` combo x } ip'
7 : x : ip' -> go m{ rC = rA m `shiftR` combo x } ip'
3 : x : ip' -> go m (if rA m == 0 then ip' else drop x pgm)
5 : x : ip' -> combo x .&. 7 : go m ip'
_ -> []
where
combo = \case
0 -> 0; 1 -> 1; 2 -> 2; 3 -> 3
4 -> rA m; 5 -> rB m; 6 -> rC m
_ -> error "invalid combo operand"

part2 :: SWord64 -> [Int] -> SBool
part2 a [] = a .== 0
part2 a (o:os) = a ./= 0 .&& b2 .== fromIntegral o .&& part2 (a `shiftR` 3) os
data SMachine = SMachine { outs :: [Int], sA, sB, sC :: SWord64 }

run2 :: SMachine -> [Int] -> SBool
run2 m0 pgm = go m0 pgm
where
b1 = a .&. 7 `xor` 2
b2 = (a `sShiftRight` b1 `xor` b1 `xor` 3) .&. 7
go m = \case
0 : x : ip' -> go m{ sA = sA m `sShiftRight` combo x } ip'
1 : x : ip' -> go m{ sB = sB m `xor` fromIntegral x } ip'
2 : x : ip' -> go m{ sB = 7 .&. combo x } ip'
4 : _ : ip' -> go m{ sB = sB m `xor` sC m } ip'
6 : x : ip' -> go m{ sB = sA m `sShiftRight` combo x } ip'
7 : x : ip' -> go m{ sC = sA m `sShiftRight` combo x } ip'
3 : x : ip' -> (sA m .== 0) .&& go m ip' .||
(sA m ./= 0) .&& go m (drop x pgm)
5 : x : ip' ->
case outs m of
[] -> sFalse
o:os -> combo x .&. 7 .== fromIntegral o .&& go m{ outs = os} ip'
_ -> if null (outs m) then sTrue else sFalse
where
combo = \case
0 -> 0; 1 -> 1; 2 -> 2; 3 -> 3
4 -> sA m; 5 -> sB m; 6 -> sC m
_ -> error "invalid combo operand"

0 comments on commit 50040e9

Please sign in to comment.