Skip to content

Commit 1cebf10

Browse files
day 17
1 parent 78d540a commit 1cebf10

File tree

4 files changed

+78
-1
lines changed

4 files changed

+78
-1
lines changed

Diff for: BUILD.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ haskell_binary(
3838
ghcopts = EXTENSIONS,
3939
)
4040

41-
DAYS = 16
41+
DAYS = 17
4242

4343
[haskell_binary(
4444
name = "d{}".format(day + 1),

Diff for: Day17.hs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import qualified Data.Attoparsec.Text as At
2+
import qualified Data.Map.Strict as M
3+
import qualified Data.Set as S
4+
import qualified Data.Array.Unboxed as A
5+
import Control.Monad
6+
import Control.Applicative
7+
import Control.Monad.Writer.Strict
8+
import Control.Monad.State.Strict
9+
import Data.Bits
10+
import Data.List (tails)
11+
12+
import Commons
13+
14+
parser :: At.Parser ((Integer,Integer,Integer),[Int])
15+
parser = do
16+
let reg = (At.string "Register " >> At.anyChar >> At.string ": ") *> At.decimal <* At.endOfLine
17+
prog = At.string "Program: " >> At.sepBy1 At.decimal (At.char ',')
18+
regs <- (,,) <$> reg <*> reg <*> reg
19+
(regs,) <$> (At.endOfLine *> prog)
20+
21+
data Inst = Adv | Bxl | Bst | Jnz | Bxc | Out | Bdv | Cdv deriving (Eq, Ord, Enum, Show)
22+
23+
newtype Prog = Prog (A.UArray Int Int) deriving Show
24+
25+
data Store = Store { regA :: Integer, regB :: Integer, regC :: Integer, pc :: Int } deriving (Show)
26+
27+
eval :: Prog -> WriterT [Int] (State Store) ()
28+
eval (Prog p) = do
29+
st <- get
30+
31+
when (pc st <= snd (A.bounds p)) $ do
32+
let inst = toEnum $ p A.! pc st
33+
opnd = fromIntegral $ p A.! (1 + pc st)
34+
combo = if | 0 <= opnd && opnd <= 3 -> fromIntegral opnd
35+
| opnd == 4 -> regA st
36+
| opnd == 5 -> regB st
37+
| opnd == 6 -> regC st
38+
| opnd == 7 -> error "invalid combo"
39+
40+
modify (\s -> s{pc = pc st + 2})
41+
42+
case inst of
43+
Adv -> modify (\s -> s{regA = div (regA st) (2 ^ combo)})
44+
Bdv -> modify (\s -> s{regB = div (regA st) (2 ^ combo)})
45+
Cdv -> modify (\s -> s{regC = div (regA st) (2 ^ combo)})
46+
Bxl -> modify (\s -> s{regB = regB st .^. opnd})
47+
Bst -> modify (\s -> s{regB = mod combo 8})
48+
Bxc -> modify (\s -> s{regB = regB st .^. regC st})
49+
Out -> tell [fromInteger $ mod combo 8]
50+
Jnz -> unless (regA st == 0) $ modify (\s -> s{pc = fromInteger opnd})
51+
52+
eval (Prog p)
53+
54+
-- https://old.reddit.com/r/haskell/comments/1hg39hy/advent_of_code_2024_day_17/m2hyhxk/
55+
solve2 :: (Integer -> [Int]) -> [[Int]] -> Integer -> [Integer]
56+
solve2 f [] n = [n]
57+
solve2 f (x:xs) n = [nx | i <- [0..7], f (n * 8 + i) == x, nx <- solve2 f xs (n * 8 + i)]
58+
59+
main :: IO ()
60+
main = do
61+
((ra, rb, rc), prog) <- inp parser
62+
let startStore = Store ra rb rc 0
63+
simulate = snd . evalState (runWriterT $ eval $ Prog (A.listArray (0, length prog - 1) prog))
64+
s1 = simulate startStore
65+
print s1
66+
let bbFn i = simulate startStore{regA = i}
67+
print $ minimum $ solve2 bbFn (tail $ reverse $ tails prog) 0

Diff for: inputs/17/input.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Register A: 51064159
2+
Register B: 0
3+
Register C: 0
4+
5+
Program: 2,4,1,5,7,5,1,6,0,3,4,6,5,5,3,0

Diff for: inputs/17/test.txt

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Register A: 2024
2+
Register B: 0
3+
Register C: 0
4+
5+
Program: 0,3,5,4,3,0

0 commit comments

Comments
 (0)