package main import ( "fmt" "sort" "strconv" "strings" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { inp := h.StdinToStringSlice() part1(inp) fmt.Println() part2(inp) } func part1(inp []string) { fmt.Println("# Part 1") dev, gates := parseInput1(inp) // Perform all logic gateDone := make(map[int]bool) for len(gateDone) != len(gates)-1 { for i := range gates { if _, ok := gateDone[i]; !ok { pts := strings.Split(gates[i], " ") var w1, w2, ok bool if w1, ok = dev[pts[0]]; ok { if w2, ok = dev[pts[2]]; ok { switch pts[1] { case "AND": dev[pts[4]] = w1 && w2 case "OR": dev[pts[4]] = w1 || w2 case "XOR": dev[pts[4]] = w1 != w2 } gateDone[i] = true } } } } } fmt.Println(findValueOf(dev, "z")) } // Not fully working yet... I solved this part manually. func part2(inp []string) { fmt.Println("# Part 2") gates := parseInput2(inp)[1] var swapped []string var c0 string for i := 0; i < 45; i++ { n := fmt.Sprintf("%02d", i) var m1, n1, r1, z1, c1 string m1 = find("x"+n, "y"+n, "XOR", gates) n1 = find("x"+n, "y"+n, "AND", gates) if c0 != "" { r1 = find(c0, m1, "AND", gates) if r1 == "" { m1, n1 = n1, m1 swapped = append(swapped, m1, n1) r1 = find(c0, m1, "AND", gates) } z1 = find(c0, m1, "XOR", gates) if strings.HasPrefix(m1, "z") { m1, z1 = z1, m1 swapped = append(swapped, m1, z1) } if strings.HasPrefix(n1, "z") { n1, z1 = z1, n1 swapped = append(swapped, n1, z1) } if strings.HasPrefix(r1, "z") { r1, z1 = z1, r1 swapped = append(swapped, r1, z1) } c1 = find(r1, n1, "OR", gates) } if strings.HasPrefix(c1, "z") && c1 != "z45" { c1, z1 = z1, c1 swapped = append(swapped, c1, z1) } if c0 == "" { c0 = n1 } else { c0 = c1 } } // Sort and join swapped wires sort.Strings(swapped) fmt.Println(strings.Join(swapped, ",")) } func parseInput1(inp []string) (map[string]bool, []string) { dev := make(map[string]bool) var gates []string var inGates bool for i := range inp { if len(inp[i]) == 0 { inGates = true } if !inGates { if inp[i][3] == ':' { wire := inp[i][:3] v := inp[i][5] == '1' dev[wire] = v } } else { gates = append(gates, inp[i]) } } return dev, gates } func parseInput2(inp []string) [][]string { var parts [][]string var currPt []string for _, line := range inp { if line == "" { if len(currPt) > 0 { parts = append(parts, currPt) currPt = []string{} } } else { currPt = append(currPt, line) } } if len(currPt) > 0 { parts = append(parts, currPt) } return parts } func findHighestReg(dev map[string]bool) int { var highest string for i := range dev { if i > highest { highest = i } } ret, _ := strconv.Atoi(highest[1:]) return ret } func findValueOf(dev map[string]bool, register string) int64 { var highest string for i := range dev { if i > highest { highest = i } } get, _ := strconv.Atoi(highest[1:]) var val int64 for i := get; ; i-- { key := fmt.Sprintf("%s%02d", register, i) v, ok := dev[key] if !ok { break } else { val = val << 1 if v { val += 1 } } } return val } func find(w1, w2, op string, gates []string) string { for _, gate := range gates { if strings.HasPrefix(gate, fmt.Sprintf("%s %s %s", w1, op, w2)) || strings.HasPrefix(gate, fmt.Sprintf("%s %s %s", w2, op, w2)) { parts := strings.Split(gate, " -> ") return parts[len(parts)-1] } } return "" }