Skip to main content
added 54 characters in body
Source Link
Gurkenglas
  • 3.8k
  • 13
  • 17

Use Control.Lens for code this stateful. (Control.Lens.TH must be used to define Machine.) May as well leave out type signatures this homogenous. Control.Monad.Loops often helps against explicit monadic recursion.

opReadAt target = uses mState $ (`index` target)
opReadNext = mPos <<+= 1 >>= opReadAt
opWrite target what = mState %= update target what

opBin op = do
    a <- opReadNext >>= opReadAt
    b <- opReadNext >>= opReadAt
    target <- opReadNext
    opWrite target $ op a b 

opcode 1 = opBin (+)
opcode 2 = opBin (*)
opcode 99 = isDone .= True

runCode = (opReadNext >>= opCode) `untilM_` getsuse isDone

evalWith :: Int -> Int -> Machine -> Int
evalWith noun verb = evalState $ do
    opWrite 1 noun
    opWrite 2 verb
    runCode
    opReadAt 0

Use Control.Lens for code this stateful. May as well leave out type signatures this homogenous. Control.Monad.Loops often helps against explicit monadic recursion.

opReadAt target = uses mState $ (`index` target)
opReadNext = mPos <<+= 1 >>= opReadAt
opWrite target what = mState %= update target what

opBin op = do
    a <- opReadNext >>= opReadAt
    b <- opReadNext >>= opReadAt
    target <- opReadNext
    opWrite target $ op a b 

opcode 1 = opBin (+)
opcode 2 = opBin (*)
opcode 99 = isDone .= True

runCode = (opReadNext >>= opCode) `untilM_` gets isDone

evalWith :: Int -> Int -> Machine -> Int
evalWith noun verb = evalState $ do
    opWrite 1 noun
    opWrite 2 verb
    runCode
    opReadAt 0

Use Control.Lens for code this stateful. (Control.Lens.TH must be used to define Machine.) May as well leave out type signatures this homogenous. Control.Monad.Loops often helps against explicit monadic recursion.

opReadAt target = uses mState $ (`index` target)
opReadNext = mPos <<+= 1 >>= opReadAt
opWrite target what = mState %= update target what

opBin op = do
    a <- opReadNext >>= opReadAt
    b <- opReadNext >>= opReadAt
    target <- opReadNext
    opWrite target $ op a b 

opcode 1 = opBin (+)
opcode 2 = opBin (*)
opcode 99 = isDone .= True

runCode = (opReadNext >>= opCode) `untilM_` use isDone

evalWith :: Int -> Int -> Machine -> Int
evalWith noun verb = evalState $ do
    opWrite 1 noun
    opWrite 2 verb
    runCode
    opReadAt 0
Source Link
Gurkenglas
  • 3.8k
  • 13
  • 17

Use Control.Lens for code this stateful. May as well leave out type signatures this homogenous. Control.Monad.Loops often helps against explicit monadic recursion.

opReadAt target = uses mState $ (`index` target)
opReadNext = mPos <<+= 1 >>= opReadAt
opWrite target what = mState %= update target what

opBin op = do
    a <- opReadNext >>= opReadAt
    b <- opReadNext >>= opReadAt
    target <- opReadNext
    opWrite target $ op a b 

opcode 1 = opBin (+)
opcode 2 = opBin (*)
opcode 99 = isDone .= True

runCode = (opReadNext >>= opCode) `untilM_` gets isDone

evalWith :: Int -> Int -> Machine -> Int
evalWith noun verb = evalState $ do
    opWrite 1 noun
    opWrite 2 verb
    runCode
    opReadAt 0