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 }