114 lines
2.1 KiB
Go
114 lines
2.1 KiB
Go
|
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
|
||
|
}
|