2018 Day 19 part 1 complete
This commit is contained in:
197
2018/day19/day19.go
Normal file
197
2018/day19/day19.go
Normal file
@@ -0,0 +1,197 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
input := stdinToStringSlice()
|
||||
part1(input)
|
||||
}
|
||||
|
||||
func part1(input []string) {
|
||||
vpc := NewState()
|
||||
vpc.reg[0] = 1
|
||||
if strings.HasPrefix(input[0], "#ip") {
|
||||
// Binding the ip to a register...
|
||||
pts := strings.Split(input[0], " ")
|
||||
vpc.ipReg = Atoi(pts[1])
|
||||
input = input[1:]
|
||||
}
|
||||
for i := 0; i < 1000000; i++ {
|
||||
if vpc.ip >= len(input) {
|
||||
break
|
||||
}
|
||||
inp := input[vpc.ip]
|
||||
if op, cmd, err := vpc.parseCommand(inp); err == nil {
|
||||
if vpc.ipReg > -1 {
|
||||
vpc.reg[vpc.ipReg] = vpc.ip
|
||||
}
|
||||
vpc.run(op, cmd)
|
||||
vpc.ip = vpc.reg[vpc.ipReg]
|
||||
}
|
||||
vpc.ip++
|
||||
}
|
||||
fmt.Println(vpc.string())
|
||||
}
|
||||
|
||||
type State struct {
|
||||
ip, ipReg int
|
||||
reg [6]int
|
||||
OpCodes map[string]func(a, b, c int)
|
||||
}
|
||||
|
||||
func NewState() *State {
|
||||
s := &State{
|
||||
ip: 0,
|
||||
ipReg: -1,
|
||||
}
|
||||
s.OpCodes = make(map[string]func(a, b, c int))
|
||||
s.OpCodes["addr"] = s.addr
|
||||
s.OpCodes["addi"] = s.addi
|
||||
s.OpCodes["mulr"] = s.mulr
|
||||
s.OpCodes["muli"] = s.muli
|
||||
s.OpCodes["banr"] = s.banr
|
||||
s.OpCodes["bani"] = s.bani
|
||||
s.OpCodes["borr"] = s.borr
|
||||
s.OpCodes["bori"] = s.bori
|
||||
s.OpCodes["setr"] = s.setr
|
||||
s.OpCodes["seti"] = s.seti
|
||||
s.OpCodes["gtir"] = s.gtir
|
||||
s.OpCodes["gtri"] = s.gtri
|
||||
s.OpCodes["gtrr"] = s.gtrr
|
||||
s.OpCodes["eqir"] = s.eqir
|
||||
s.OpCodes["eqri"] = s.eqri
|
||||
s.OpCodes["eqrr"] = s.eqrr
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *State) parseCommand(inp string) (string, []int, error) {
|
||||
var retOp string
|
||||
var retCmd []int
|
||||
pts := strings.Split(inp, " ")
|
||||
if len(pts) != 4 {
|
||||
return retOp, retCmd, errors.New("Invalid Command")
|
||||
}
|
||||
retOp = pts[0]
|
||||
for _, v := range pts[1:] {
|
||||
retCmd = append(retCmd, Atoi(v))
|
||||
}
|
||||
return retOp, retCmd, nil
|
||||
}
|
||||
|
||||
func (s *State) string() string {
|
||||
ret := fmt.Sprintf("ip=%d ", s.ip)
|
||||
for i := 0; i < len(s.reg); i++ {
|
||||
if i == s.ipReg {
|
||||
ret = fmt.Sprintf("%s <%d> ", ret, s.reg[i])
|
||||
} else {
|
||||
ret = fmt.Sprintf("%s %d ", ret, s.reg[i])
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (s *State) run(op string, cmd []int) error {
|
||||
if fn, ok := s.OpCodes[op]; !ok {
|
||||
return errors.New(fmt.Sprintf("Invalid OpCode: %d", cmd[0]))
|
||||
} else {
|
||||
fn(cmd[0], cmd[1], cmd[2])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *State) addr(r1, r2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] + s.reg[r2]
|
||||
}
|
||||
|
||||
func (s *State) addi(r1, v2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] + v2
|
||||
}
|
||||
|
||||
func (s *State) mulr(r1, r2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] * s.reg[r2]
|
||||
}
|
||||
|
||||
func (s *State) muli(r1, v2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] * v2
|
||||
}
|
||||
|
||||
func (s *State) banr(r1, r2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] & s.reg[r2]
|
||||
}
|
||||
|
||||
func (s *State) bani(r1, v2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] & v2
|
||||
}
|
||||
|
||||
func (s *State) borr(r1, r2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] | s.reg[r2]
|
||||
}
|
||||
|
||||
func (s *State) bori(r1, v2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1] | v2
|
||||
}
|
||||
|
||||
func (s *State) setr(r1, r2, r3 int) {
|
||||
s.reg[r3] = s.reg[r1]
|
||||
}
|
||||
|
||||
func (s *State) seti(v1, v2, r3 int) {
|
||||
s.reg[r3] = v1
|
||||
}
|
||||
|
||||
func (s *State) gtir(v1, r2, r3 int) {
|
||||
s.reg[r3] = boolToInt(v1 > s.reg[r2])
|
||||
}
|
||||
|
||||
func (s *State) gtri(r1, v2, r3 int) {
|
||||
s.reg[r3] = boolToInt(s.reg[r1] > v2)
|
||||
}
|
||||
|
||||
func (s *State) gtrr(r1, r2, r3 int) {
|
||||
s.reg[r3] = boolToInt(s.reg[r1] > s.reg[r2])
|
||||
}
|
||||
|
||||
func (s *State) eqir(v1, r2, r3 int) {
|
||||
s.reg[r3] = boolToInt(v1 == s.reg[r2])
|
||||
}
|
||||
|
||||
func (s *State) eqri(r1, v2, r3 int) {
|
||||
s.reg[r3] = boolToInt(s.reg[r1] == v2)
|
||||
}
|
||||
|
||||
func (s *State) eqrr(r1, r2, r3 int) {
|
||||
s.reg[r3] = boolToInt(s.reg[r1] == s.reg[r2])
|
||||
}
|
||||
|
||||
func boolToInt(v bool) int {
|
||||
if v {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func stdinToStringSlice() []string {
|
||||
var input []string
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for scanner.Scan() {
|
||||
input = append(input, scanner.Text())
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
func Atoi(i string) int {
|
||||
var ret int
|
||||
var err error
|
||||
if ret, err = strconv.Atoi(i); err != nil {
|
||||
log.Fatal("Invalid Atoi: " + i)
|
||||
}
|
||||
return ret
|
||||
}
|
37
2018/day19/input
Normal file
37
2018/day19/input
Normal file
@@ -0,0 +1,37 @@
|
||||
#ip 4
|
||||
addi 4 16 4
|
||||
seti 1 4 3
|
||||
seti 1 3 5
|
||||
mulr 3 5 1
|
||||
eqrr 1 2 1
|
||||
addr 1 4 4
|
||||
addi 4 1 4
|
||||
addr 3 0 0
|
||||
addi 5 1 5
|
||||
gtrr 5 2 1
|
||||
addr 4 1 4
|
||||
seti 2 9 4
|
||||
addi 3 1 3
|
||||
gtrr 3 2 1
|
||||
addr 1 4 4
|
||||
seti 1 6 4
|
||||
mulr 4 4 4
|
||||
addi 2 2 2
|
||||
mulr 2 2 2
|
||||
mulr 4 2 2
|
||||
muli 2 11 2
|
||||
addi 1 2 1
|
||||
mulr 1 4 1
|
||||
addi 1 7 1
|
||||
addr 2 1 2
|
||||
addr 4 0 4
|
||||
seti 0 8 4
|
||||
setr 4 3 1
|
||||
mulr 1 4 1
|
||||
addr 4 1 1
|
||||
mulr 4 1 1
|
||||
muli 1 14 1
|
||||
mulr 1 4 1
|
||||
addr 2 1 2
|
||||
seti 0 3 0
|
||||
seti 0 6 4
|
8
2018/day19/testinput
Normal file
8
2018/day19/testinput
Normal file
@@ -0,0 +1,8 @@
|
||||
#ip 0
|
||||
seti 5 0 1
|
||||
seti 6 0 2
|
||||
addi 0 1 0
|
||||
addr 1 2 3
|
||||
setr 1 0 0
|
||||
seti 8 0 4
|
||||
seti 9 0 5
|
Reference in New Issue
Block a user