Day 23, part 1
This commit is contained in:
parent
b7e9013d09
commit
746da09956
|
@ -0,0 +1,67 @@
|
||||||
|
{-# LANGUAGE BangPatterns #-}
|
||||||
|
import Text.Read (readMaybe)
|
||||||
|
import Data.Char (ord)
|
||||||
|
import Data.Sequence (Seq, fromList, index)
|
||||||
|
import Data.Vector.Unboxed (Vector, (!), (//))
|
||||||
|
import qualified Data.Vector.Unboxed as V (replicate)
|
||||||
|
import Debug.Trace
|
||||||
|
|
||||||
|
type Registers = Vector Int
|
||||||
|
type Instruction = State -> State
|
||||||
|
data Value = Register Char | Number Int
|
||||||
|
data Operation = Set | Sub | Mul deriving Eq
|
||||||
|
data Function = Function {
|
||||||
|
operation :: Operation,
|
||||||
|
function :: Int -> Int -> Int
|
||||||
|
}
|
||||||
|
data State = State {
|
||||||
|
registers :: Registers,
|
||||||
|
position :: Int,
|
||||||
|
countMul :: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
getIndex :: Value -> Int
|
||||||
|
getIndex (Register c) = ord c - ord 'a'
|
||||||
|
|
||||||
|
getValue :: Registers -> Value -> Int
|
||||||
|
getValue r v = case v of
|
||||||
|
Number i -> i
|
||||||
|
c -> r ! (getIndex c)
|
||||||
|
|
||||||
|
app :: Function -> Value -> Value -> Instruction
|
||||||
|
app (Function op fn) index value state@(State reg pos cnt) =
|
||||||
|
let i = getIndex index
|
||||||
|
in State {
|
||||||
|
registers = reg // [(i, reg ! i `fn` getValue reg value)],
|
||||||
|
position = pos + 1,
|
||||||
|
countMul = cnt + fromEnum (op == Mul)
|
||||||
|
}
|
||||||
|
|
||||||
|
jnz :: Value -> Value -> Instruction
|
||||||
|
jnz x y state@(State reg pos _) =
|
||||||
|
state {
|
||||||
|
position = pos + if getValue reg x /= 0 then getValue reg y else 1
|
||||||
|
}
|
||||||
|
|
||||||
|
parseLine :: String -> Instruction
|
||||||
|
parseLine str =
|
||||||
|
let op : vs = words str
|
||||||
|
in case op of
|
||||||
|
"set" -> app (Function Set (flip const)) (parseValue $ head vs) (parseValue $ last vs)
|
||||||
|
"sub" -> app (Function Sub (-)) (parseValue $ head vs) (parseValue $ last vs)
|
||||||
|
"mul" -> app (Function Mul (*)) (parseValue $ head vs) (parseValue $ last vs)
|
||||||
|
"jnz" -> jnz (parseValue $ head vs) (parseValue $ last vs)
|
||||||
|
where parseValue s = case readMaybe s of
|
||||||
|
Just i -> Number i
|
||||||
|
Nothing -> Register $ head s
|
||||||
|
|
||||||
|
runInstructions :: Seq Instruction -> State -> Int
|
||||||
|
runInstructions instructions state@(State reg pos cnt) =
|
||||||
|
if pos >= length instructions then cnt else
|
||||||
|
let !nextState = instructions `index` pos $ state in runInstructions instructions nextState
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
instructions <- fromList . map parseLine . lines <$> readFile "23.txt"
|
||||||
|
print $ runInstructions instructions (State (V.replicate 8 0) 0 0)
|
||||||
|
print $ runInstructions instructions (State (V.replicate 8 0 // [(0, 1)]) 0 0)
|
|
@ -0,0 +1,32 @@
|
||||||
|
set b 81
|
||||||
|
set c b
|
||||||
|
jnz a 2
|
||||||
|
jnz 1 5
|
||||||
|
mul b 100
|
||||||
|
sub b -100000
|
||||||
|
set c b
|
||||||
|
sub c -17000
|
||||||
|
set f 1
|
||||||
|
set d 2
|
||||||
|
set e 2
|
||||||
|
set g d
|
||||||
|
mul g e
|
||||||
|
sub g b
|
||||||
|
jnz g 2
|
||||||
|
set f 0
|
||||||
|
sub e -1
|
||||||
|
set g e
|
||||||
|
sub g b
|
||||||
|
jnz g -8
|
||||||
|
sub d -1
|
||||||
|
set g d
|
||||||
|
sub g b
|
||||||
|
jnz g -13
|
||||||
|
jnz f 2
|
||||||
|
sub h -1
|
||||||
|
set g b
|
||||||
|
sub g c
|
||||||
|
jnz g 2
|
||||||
|
jnz 1 3
|
||||||
|
sub b -17
|
||||||
|
jnz 1 -23
|
Loading…
Reference in New Issue