day 18
This commit is contained in:
parent
9d341d6542
commit
82760c7f64
2 changed files with 345 additions and 0 deletions
191
18/18.2.go
Normal file
191
18/18.2.go
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cat input | go run 18.2.go
|
||||||
|
|
||||||
|
type instruction struct {
|
||||||
|
instr string
|
||||||
|
register string
|
||||||
|
argIsInt bool
|
||||||
|
argInt int
|
||||||
|
argReg string
|
||||||
|
}
|
||||||
|
|
||||||
|
var sends int
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
registers0 := make(map[string]int)
|
||||||
|
registers1 := make(map[string]int)
|
||||||
|
var instructions = []instruction{}
|
||||||
|
var q0 = []int{}
|
||||||
|
var q1 = []int{}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
s := strings.Split(scanner.Text(), " ")
|
||||||
|
i := instruction{s[0], s[1], false, -1, ""}
|
||||||
|
|
||||||
|
if len(s) == 3 {
|
||||||
|
int, err := strconv.Atoi(s[2])
|
||||||
|
if err != nil {
|
||||||
|
i.argIsInt = false
|
||||||
|
i.argReg = s[2]
|
||||||
|
} else {
|
||||||
|
i.argIsInt = true
|
||||||
|
i.argInt = int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instructions = append(instructions, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pc0 := 0
|
||||||
|
pc1 := 0
|
||||||
|
registers0["p"] = 0
|
||||||
|
registers1["p"] = 1
|
||||||
|
|
||||||
|
for pc0 < len(instructions) && pc0 >= 0 && pc1 < len(instructions) && pc1 >= 0 {
|
||||||
|
pcpre0, pcpre1 := pc0, pc1
|
||||||
|
pc0 = runInstr(0, ®isters0, instructions[pc0], pc0, &q0, &q1)
|
||||||
|
pc1 = runInstr(1, ®isters1, instructions[pc1], pc1, &q1, &q0)
|
||||||
|
if pc0 == pcpre0 && pc1 == pcpre1 {
|
||||||
|
fmt.Println("deadlock!", sends)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(sends)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInstr(p int, registers *map[string]int, i instruction, pc int, qin *[]int, qout *[]int) int {
|
||||||
|
//fmt.Println(p, "PC:", pc, i, *registers, qin, qout)
|
||||||
|
register := i.register
|
||||||
|
|
||||||
|
// Skip register if this is an int, because 'jgz 1 3'
|
||||||
|
_, err := strconv.Atoi(register)
|
||||||
|
if err != nil {
|
||||||
|
r := *registers
|
||||||
|
_, present := r[register]
|
||||||
|
if !present {
|
||||||
|
r[register] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch i.instr {
|
||||||
|
case "set":
|
||||||
|
pc = instrSet(registers, i, pc)
|
||||||
|
case "add":
|
||||||
|
pc = instrAdd(registers, i, pc)
|
||||||
|
case "mul":
|
||||||
|
pc = instrMul(registers, i, pc)
|
||||||
|
case "mod":
|
||||||
|
pc = instrMod(registers, i, pc)
|
||||||
|
case "snd":
|
||||||
|
pc = instrSnd(registers, i, pc, qout)
|
||||||
|
if p == 1 {
|
||||||
|
sends++
|
||||||
|
}
|
||||||
|
case "rcv":
|
||||||
|
pc = instrRcv(registers, i, pc, qin)
|
||||||
|
case "jgz":
|
||||||
|
pc = instrJgz(registers, i, pc)
|
||||||
|
default:
|
||||||
|
fmt.Println("Instruction invalid!")
|
||||||
|
}
|
||||||
|
pc++
|
||||||
|
//fmt.Println(p, "PC:", pc, i, *registers, qin, qout)
|
||||||
|
//fmt.Println()
|
||||||
|
return pc
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrSet(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] = i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] = r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrAdd(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] += i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] += r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrMul(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] *= i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] *= r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrMod(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] %= i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] %= r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrSnd(registers *map[string]int, i instruction, pc int, snd *[]int) int {
|
||||||
|
r := *registers
|
||||||
|
n, err := strconv.Atoi(i.register)
|
||||||
|
if err == nil {
|
||||||
|
*snd = append(*snd, n)
|
||||||
|
} else {
|
||||||
|
*snd = append(*snd, r[i.register])
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrRcv(registers *map[string]int, i instruction, pc int, snd *[]int) int {
|
||||||
|
r := *registers
|
||||||
|
s := *snd
|
||||||
|
if len(s) == 0 {
|
||||||
|
pc--
|
||||||
|
} else {
|
||||||
|
x, t := s[0], s[1:]
|
||||||
|
r[i.register] = x
|
||||||
|
*snd = t
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrJgz(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
|
||||||
|
cmp := r[i.register]
|
||||||
|
n, err := strconv.Atoi(i.register)
|
||||||
|
if err == nil {
|
||||||
|
cmp = n
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmp > 0 {
|
||||||
|
if i.argIsInt {
|
||||||
|
pc = (pc + i.argInt) - 1
|
||||||
|
} else {
|
||||||
|
pc = (pc + r[i.argReg]) - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pc
|
||||||
|
}
|
154
18/18.go
Normal file
154
18/18.go
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// cat input | go run 18.go
|
||||||
|
|
||||||
|
type instruction struct {
|
||||||
|
instr string
|
||||||
|
register string
|
||||||
|
argIsInt bool
|
||||||
|
argInt int
|
||||||
|
argReg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
registers := make(map[string]int)
|
||||||
|
var instructions = []instruction{}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
s := strings.Split(scanner.Text(), " ")
|
||||||
|
i := instruction{s[0], s[1], false, 0, ""}
|
||||||
|
|
||||||
|
if len(s) == 3 {
|
||||||
|
int, err := strconv.Atoi(s[2])
|
||||||
|
if err != nil {
|
||||||
|
i.argIsInt = false
|
||||||
|
i.argReg = s[2]
|
||||||
|
} else {
|
||||||
|
i.argIsInt = true
|
||||||
|
i.argInt = int
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instructions = append(instructions, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
pc := 0
|
||||||
|
lastsnd := -1
|
||||||
|
|
||||||
|
loop:
|
||||||
|
for pc < len(instructions) && pc >= 0 {
|
||||||
|
fmt.Println("PC: ", pc, instructions[pc])
|
||||||
|
fmt.Println(registers, lastsnd)
|
||||||
|
|
||||||
|
instruction := instructions[pc].instr
|
||||||
|
register := instructions[pc].register
|
||||||
|
|
||||||
|
_, present := registers[register]
|
||||||
|
if !present {
|
||||||
|
registers[register] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
switch instruction {
|
||||||
|
case "set":
|
||||||
|
pc = instrSet(®isters, instructions[pc], pc)
|
||||||
|
case "add":
|
||||||
|
pc = instrAdd(®isters, instructions[pc], pc)
|
||||||
|
case "mul":
|
||||||
|
pc = instrMul(®isters, instructions[pc], pc)
|
||||||
|
case "mod":
|
||||||
|
pc = instrMod(®isters, instructions[pc], pc)
|
||||||
|
case "snd":
|
||||||
|
pc = instrSnd(®isters, instructions[pc], pc, &lastsnd)
|
||||||
|
case "rcv":
|
||||||
|
pc = instrRcv(®isters, instructions[pc], pc, &lastsnd)
|
||||||
|
break loop
|
||||||
|
case "jgz":
|
||||||
|
pc = instrJgz(®isters, instructions[pc], pc)
|
||||||
|
default:
|
||||||
|
fmt.Println("Instruction invalid!")
|
||||||
|
}
|
||||||
|
fmt.Println(registers, lastsnd)
|
||||||
|
pc++
|
||||||
|
|
||||||
|
}
|
||||||
|
fmt.Println(registers, lastsnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrSet(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] = i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] = r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrAdd(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] += i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] += r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrMul(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] *= i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] *= r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrMod(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
r[i.register] %= i.argInt
|
||||||
|
} else {
|
||||||
|
r[i.register] %= r[i.argReg]
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrSnd(registers *map[string]int, i instruction, pc int, snd *int) int {
|
||||||
|
r := *registers
|
||||||
|
*snd = r[i.register]
|
||||||
|
fmt.Println("*snd:", *snd)
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrRcv(registers *map[string]int, i instruction, pc int, snd *int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt && i.argInt != 0 {
|
||||||
|
r[i.register] = *snd
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
||||||
|
|
||||||
|
func instrJgz(registers *map[string]int, i instruction, pc int) int {
|
||||||
|
r := *registers
|
||||||
|
if i.argIsInt {
|
||||||
|
if r[i.register] > 0 {
|
||||||
|
pc = (pc + i.argInt) - 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if r[i.register] > 0 {
|
||||||
|
pc = (pc + r[i.argReg]) - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pc
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue