package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var registers map[string]int

func main() {
	registers = make(map[string]int)
	if len(os.Args) > 1 {
		if os.Args[1] == "-help" {
			fmt.Println("Usage: day23 [register presets]")
			fmt.Println("  Register presets are given in the form:")
			fmt.Println("    name=value")
			fmt.Println("  If more than one, separate with spaces.")
			fmt.Println("  If none are given, all registers start at 0")
			os.Exit(1)
		}
		for i := range os.Args {
			if strings.Contains(os.Args[i], "=") {
				presets := strings.Split(os.Args[i], "=")
				registers[presets[0]] = mustAtoi(presets[1])
			}
		}
	}
	var input []string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = append(input, strings.ToLower(scanner.Text()))
	}
	// We manually manage i
	var i, cnt int
	for i < len(input) {
		printRegisters()
		fmt.Print(" ")
		cnt++
		fmt.Print(input[i])
		parts := strings.Split(input[i], " ")
		switch parts[0] {
		case "hlf":
			registers[parts[1]] = registers[parts[1]] / 2
			i++
		case "tpl":
			registers[parts[1]] = registers[parts[1]] * 3
			i++
		case "inc":
			registers[parts[1]]++
			i++
		case "jmp":
			i += mustAtoi(parts[1])
		case "jie":
			parts[1] = string(parts[1][len(parts[1])-2])
			if registers[parts[1]]%2 == 0 {
				i += mustAtoi(parts[2])
			} else {
				i++
			}
		case "jio":
			parts[1] = string(parts[1][len(parts[1])-2])
			if registers[parts[1]] == 1 {
				i += mustAtoi(parts[2])
			} else {
				i++
			}
		}
		fmt.Print(" ")
		printRegistersLn()
	}
	printRegistersLn()
}

func printRegistersLn() {
	printRegisters()
	fmt.Println()
}

func printRegisters() {
	fmt.Print("[")
	for k := range registers {
		printRegister(k)
		fmt.Print(" ")
	}
	fmt.Print("]")
}

func printRegister(n string) {
	fmt.Print(n + ": " + strconv.Itoa(registers[n]))
}

func mustAtoi(s string) int {
	var i int
	var err error
	if i, err = strconv.Atoi(s); err != nil {
		fmt.Println("Tried to atoi " + s)
		os.Exit(1)
	}
	return i
}
