Documentation
¶
Overview ¶
Package intcode implements programming in "Intcode" for Advent of Code 2019.
Index ¶
- Variables
- func InstallAdderMultiplier(ic *Intcode)
- func InstallJumpers(ic *Intcode)
- func IsHalt(err error) bool
- func NewHaltError(from string) error
- func NewInvalidOpcodeError(opcode, position int64) error
- func NewOutOfBoundsError(lookingFor, actualLength int64) error
- type HaltError
- type Intcode
- func (ic *Intcode) AdjustRelativeBase(amount int64)
- func (ic *Intcode) Current() (value int64)
- func (ic *Intcode) Details() string
- func (ic *Intcode) Format(mem []int64)
- func (ic *Intcode) GetInput() (input int64, err error)
- func (ic *Intcode) GetLocation(location int64) (value int64, err error)
- func (ic *Intcode) GetNext(count int64) (mem []int64, err error)
- func (ic *Intcode) GetOutput() (output int64, err error)
- func (ic *Intcode) Increment(value int64) (err error)
- func (ic *Intcode) Input() (input []int64)
- func (ic *Intcode) Install(module *Module)
- func (ic *Intcode) Jump(value int64) (err error)
- func (ic *Intcode) Len() (length int64)
- func (ic *Intcode) Operate() error
- func (ic *Intcode) Output() (output []int64)
- func (ic *Intcode) PC() (pc int64)
- func (ic *Intcode) PushToInput(input int64)
- func (ic *Intcode) PushToOutput(value int64)
- func (ic *Intcode) RelativeBase() (relativeBase int64)
- func (ic *Intcode) ResetOutput()
- func (ic *Intcode) Rewind()
- func (ic *Intcode) SetInput(inputs ...int64)
- func (ic *Intcode) SetLocation(location, value int64) (err error)
- func (ic *Intcode) SetRelativeBase(amount int64)
- func (ic *Intcode) Snapshot() (mem []int64)
- func (ic *Intcode) UninstallAll()
- type InvalidOpcodeError
- type Module
- type ModuleConfig
- type OperationError
- type OutOfBoundsError
Constants ¶
This section is empty.
Variables ¶
var Adder = NewModule(ModuleConfig{ Opcode: 1, Mnemonic: "ADD", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(3); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, true); err != nil { return } if err = ic.SetLocation(params[2], params[0]+params[1]); err != nil { return } return ic.Increment(4) }, })
Adder is a module that adds values with support for parameterized mode. Adapted from https://adventofcode.com/2019/day/5.
Memory:
1 ARG1 ARG2 ARG3
Procedure:
mem[ARG3] = mem[ARG1]+mem[ARG2] pc += 4
var ChangeRelativeBase = NewModule(ModuleConfig{ Opcode: 9, Mnemonic: "RELBASE", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(1); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, false); err != nil { return } ic.AdjustRelativeBase(params[0]) return ic.Increment(2) }, })
ChangeRelativeBase adjusts the relative base of the computer by its parameter.
Memory:
9 ARG1
Procedure:
relativeBase += mem[ARG1] pc += 2
var Equals = NewModule(ModuleConfig{ Opcode: 8, Mnemonic: "EQUALS", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(3); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, true); err != nil { return } if params[0] == params[1] { if err = ic.SetLocation(params[2], 1); err != nil { return } } else { if err = ic.SetLocation(params[2], 0); err != nil { return } } return ic.Increment(4) }, })
Equals is a module that stores 1 in the third parameter if the first equals the second; otherwise it will store 0
Memory:
8 ARG1 ARG2 ARG3
Procedure:
if mem[ARG1] == mem[ARG2] then mem[ARG3]=1 else mem[ARG3]=0 pc += 4
var Inputter = NewModule(ModuleConfig{ Opcode: 3, Mnemonic: "INPUT", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 var input int64 if params, err = ic.GetNext(1); err != nil { return } if input, err = ic.GetInput(); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, true); err != nil { return } if err = ic.SetLocation(params[0], input); err != nil { return } return ic.Increment(2) }, })
Inputter reads from the input and sets it to a specific address
Memory:
3 ARG1
Procedure:
mem[ARG1], err = ic.GetInput() pc += 2
var JumpIfFalse = NewModule(ModuleConfig{ Opcode: 6, Mnemonic: "JUMPIFTRUE", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(2); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, false); err != nil { return } if params[0] == 0 { return ic.Jump(params[1]) } return ic.Increment(3) }, })
JumpIfFalse is a module that sets the instruction pointer to the second parameter if the first parameter is zero
Memory:
5 ARG1 ARG2
Procedure:
if mem[ARG1] == 0 then jump(mem[ARG2]) pc += 3
var JumpIfTrue = NewModule(ModuleConfig{ Opcode: 5, Mnemonic: "JUMPIFTRUE", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(2); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, false); err != nil { return } if params[0] != 0 { return ic.Jump(params[1]) } return ic.Increment(3) }, })
JumpIfTrue is a module that sets the instruction pointer to the second parameter if the first parameter is non-zero
Memory:
5 ARG1 ARG2
Procedure:
if mem[ARG1] != 0 then jump(mem[ARG2]) pc += 3
var LessThan = NewModule(ModuleConfig{ Opcode: 7, Mnemonic: "LESSTHAN", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(3); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, true); err != nil { return } if params[0] < params[1] { if err = ic.SetLocation(params[2], 1); err != nil { return } } else { if err = ic.SetLocation(params[2], 0); err != nil { return } } return ic.Increment(4) }, })
LessThan is a module that stores 1 in the third parameter if the first is less than the second; otherwise it will store 0
Memory:
7 ARG1 ARG2 ARG3
Procedure:
if mem[ARG1] < mem[ARG2] then mem[ARG3]=1 else mem[ARG3]=0 pc += 4
var Multiplier = NewModule(ModuleConfig{ Opcode: 2, Mnemonic: "MUL", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(3); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, true); err != nil { return } if err = ic.SetLocation(params[2], params[0]*params[1]); err != nil { return } return ic.Increment(4) }, })
Multiplier is a module that adds values with support for parameterized mode. Adapted from https://adventofcode.com/2019/day/5.
Memory:
2 ARG1 ARG2 ARG3
Procedure:
mem[ARG3] = mem[ARG1]*mem[ARG2] pc += 4
var OutputAndHalt = NewModule(ModuleConfig{ Opcode: 4, Mnemonic: "OUTPUT", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(1); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, false); err != nil { return } ic.PushToOutput(params[0]) if params[0] != 0 { return NewHaltError("OUTPUT (4)") } return ic.Increment(2) }, })
OutputAndHalt is a module that outputs the value at its only parameter and, if non-zero, will halt immediately. Used for aoc2019.Day05.
Memory:
4 ARG1
Procedure:
output = append(output, mem[ARG1]) if mem[ARG1] != 0 then halt pc += 2
var OutputToInput = NewModule(ModuleConfig{ Opcode: 4, Mnemonic: "OUTPUT", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(1); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, false); err != nil { return } ic.PushToInput(params[0]) return ic.Increment(2) }, })
OutputToInput is a moule that, instead of pushing its parameter to Output, it pushes the value to Input
var Outputter = NewModule(ModuleConfig{ Opcode: 4, Mnemonic: "OUTPUT", Parameterized: true, Function: func(ic *Intcode) (err error) { var params []int64 if params, err = ic.GetNext(1); err != nil { return } if err = getFromMemory(ic.Current()/100, params, ic, false); err != nil { return } ic.PushToOutput(params[0]) return ic.Increment(2) }, })
Outputter is a module that outputs the value at its only parameter.
Memory:
4 ARG1
Procedure:
output = append(output, mem[ARG1]) pc += 2
var SimpleAdder = NewModule(ModuleConfig{ Opcode: 1, Mnemonic: "ADD", Function: func(ic *Intcode) (err error) { // assume that Current() is 1 // Now check if the next ones are in memory var params []int64 if params, err = ic.GetNext(3); err != nil { return } if params[0], err = ic.GetLocation(params[0]); err != nil { return } if params[1], err = ic.GetLocation(params[1]); err != nil { return } if err = ic.SetLocation(params[2], params[0]+params[1]); err != nil { return } return ic.Increment(4) }, })
SimpleAdder is a simple program that adds values. Adapted from https://adventofcode.com/2019/day/2.
Memory:
1 ARG1 ARG2 ARG3
Procedure:
mem[ARG3] = mem[ARG1]+mem[ARG2] pc += 4
var SimpleMultiplier = NewModule(ModuleConfig{ Opcode: 2, Mnemonic: "MUL", Function: func(ic *Intcode) (err error) { // assume that Current() is 2 // Now check if the next ones are in memory var params []int64 if params, err = ic.GetNext(3); err != nil { return } if params[0], err = ic.GetLocation(params[0]); err != nil { return } if params[1], err = ic.GetLocation(params[1]); err != nil { return } if err = ic.SetLocation(params[2], params[0]*params[1]); err != nil { return } return ic.Increment(4) }, })
SimpleMultiplier is a simple program that adds values. Adapted from https://adventofcode.com/2019/day/2.
Memory:
2 ARG1 ARG2 ARG3
Procedure:
mem[ARG3] = mem[ARG1]*mem[ARG2] pc += 4
Functions ¶
func InstallAdderMultiplier ¶
func InstallAdderMultiplier(ic *Intcode)
InstallAdderMultiplier installs the Adder and Multiplier modules to the Intcode computer
func InstallJumpers ¶
func InstallJumpers(ic *Intcode)
InstallJumpers installs the JumpIfFalse, JumpIfTrue, LessThan, and Equals modules
func NewHaltError ¶
NewHaltError returns a halt error where "from" could be any reason e.g., "program halted from HALT (99)"
func NewInvalidOpcodeError ¶
NewInvalidOpcodeError returns an InvalidOpcodeError with message "invalid opcode OPCODE at position POSITION"
func NewOutOfBoundsError ¶
NewOutOfBoundsError generates an OutOfBoundsError
Types ¶
type HaltError ¶
type HaltError struct {
From string
}
HaltError is an error that essentially stops the Intcode from running
type Intcode ¶
type Intcode struct {
// contains filtered or unexported fields
}
Intcode implements an "Intcode" computer consisting of a program counter and a tape of memory as well as a list of "modules" which are functions that take in an Intcode and may return an error.
func NewFromString ¶
NewFromString generates using a memory reel represented by a string
func (*Intcode) AdjustRelativeBase ¶
AdjustRelativeBase adjusts the relative base by some amount, increasing or decreasing it.
func (*Intcode) Format ¶
Format formats the memory, input, and outputs and sets PC and relative base to zero but does not remove installed modules
func (*Intcode) GetLocation ¶
GetLocation returns the value of the memory at a particular location. If location is more than the memory length, ic.mem is reallocated. If location is negative it will simply return an error.
func (*Intcode) GetNext ¶
GetNext returns a fragment of memory after Current() containing the next count locations
func (*Intcode) Operate ¶
Operate performs instructions on the Intcode computer depending on the modules it has
func (*Intcode) PushToInput ¶
PushToInput pushes a value to the input queue
func (*Intcode) PushToOutput ¶
PushToOutput pushes a value to its outputs
func (*Intcode) RelativeBase ¶
RelativeBase returns the relative base of the ic computer
func (*Intcode) SetLocation ¶
SetLocation sets the value of the memory at some location. If location is more than the memory length, ic.mem is reallocated. If location is negative it will simply return an error.
func (*Intcode) SetRelativeBase ¶
SetRelativeBase sets the relative base by some amount.
type InvalidOpcodeError ¶
type InvalidOpcodeError struct {
Opcode int64 // what opcode did it see?
At int64 // program counter?
// contains filtered or unexported fields
}
InvalidOpcodeError returns when the opcode being read is not valid.
func (*InvalidOpcodeError) Error ¶
func (e *InvalidOpcodeError) Error() string
type Module ¶
type Module struct {
// contains filtered or unexported fields
}
Module is a module with an opcode and a ParamCount which does something to an ic computer *Intcode using the next ParamCount memory locations. Calling function can return an error if its params turns out to be invalid e.g., accessing an invalid memory address.
It is assumed that calling function only happens if ic.Current() equals the opcode, unless if the Module supports "parameter modes", where in that case ic.Current()%100 is checked instead. Note that function will affect the Intcode computer e.g., changing its memory, inputs and outputs.
var Halt *Module = NewModule(ModuleConfig{ Opcode: 99, Mnemonic: "HALT", Parameterized: false, Function: func(ic *Intcode) error { return NewHaltError("HALT (99)") }, })
Halt is a module that is built in to the Intcode
func NewModule ¶
func NewModule(config ModuleConfig) *Module
NewModule generates a module object with several attributes using a config struct
type ModuleConfig ¶
type ModuleConfig struct {
Opcode int64 // opcode (if 0 then check will occur in function)
Mnemonic string // "name" of the opcode
Parameterized bool // should module support parameter modes?
Function func(ic *Intcode) error // what does it do to the computer?
}
ModuleConfig is a structure representing the configuration of a module
type OperationError ¶
type OperationError struct {
Child error // a "deeper" error
PC int64 // program counter
Opcode int64 // the current opcode
Memory []int64 // memory snapshot
Input []int64
Output []int64
// contains filtered or unexported fields
}
OperationError is an error that occurs during the operation of the Intcode computer
func NewOperationError ¶
func NewOperationError(err error, ic *Intcode) *OperationError
NewOperationError creates an Error object that occurred due to some other error
func (*OperationError) Error ¶
func (e *OperationError) Error() string
type OutOfBoundsError ¶
type OutOfBoundsError struct {
LookingFor int64 // what memory location is out of bounds?
ActualLength int64 // how long is memory?
// contains filtered or unexported fields
}
OutOfBoundsError returns when accessing a memory location that is outside Intcode.mem
func (*OutOfBoundsError) Error ¶
func (e *OutOfBoundsError) Error() string