package main import ( "fmt" "io" "log" "strconv" "strings" ) var wires map[string]uint16 func main() { var input []string var bldInput string var readInp string for { _, err := fmt.Scan(&readInp) if err != nil { if err != io.EOF { log.Fatal(err) } break } if strings.HasSuffix(bldInput, "->") { bldInput = bldInput + " " + readInp input = append(input, bldInput) bldInput = "" continue } if len(bldInput) > 0 { bldInput += " " } bldInput = bldInput + readInp } wires = make(map[string]uint16) var done bool for !done { for i := range input { parsePts := strings.Split(input[i], " -> ") inputs := parsePts[0] output := parsePts[1] if _, ok := getValue(output); ok { // We've already done this one continue } // What's up with these inputs? inpParts := strings.Split(inputs, " ") if len(inpParts) == 1 { if val, ok := getValue(inpParts[0]); ok { setValue(output, val) } else { continue } } else if len(inpParts) == 2 { if val, ok := getValue(inpParts[1]); ok { setValue(output, ^val) } else { continue } } else { // All other gates var inp1, inp2 uint16 if val, ok := getValue(inpParts[0]); ok { inp1 = val } else { continue } if val, ok := getValue(inpParts[2]); ok { inp2 = val } else { continue } if inpParts[1] == "RSHIFT" { setValue(output, (inp1 >> inp2)) } else if inpParts[1] == "LSHIFT" { setValue(output, (inp1 << inp2)) } else if inpParts[1] == "OR" { setValue(output, (inp1 | inp2)) } else if inpParts[1] == "AND" { setValue(output, (inp1 & inp2)) } } if len(wires) == len(input) { done = true } } if aWire, ok := wires["a"]; ok { fmt.Printf("\"a\" value: %d\n", aWire) done = true } } } func setValue(key string, val uint16) { wires[key] = val } func getValue(input string) (uint16, bool) { var ret uint16 var i int var err error if i, err = strconv.Atoi(input); err != nil { if w, ok := wires[input]; ok { return w, true } return wires[input], false } ret = uint16(i) return ret, true }