From c994c0ea41ea9992ee20a1835cb4141f616fd32a Mon Sep 17 00:00:00 2001 From: Ben Charlton Date: Wed, 27 Dec 2017 22:08:03 +0000 Subject: [PATCH] last 3 days --- 23/23.2.go | 38 +++++++++++++++ 23/23.go | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ 24/24.go | 113 +++++++++++++++++++++++++++++++++++++++++++ 25/25.go | 62 ++++++++++++++++++++++++ 25/25_test.go | 22 +++++++++ 5 files changed, 365 insertions(+) create mode 100644 23/23.2.go create mode 100644 23/23.go create mode 100644 24/24.go create mode 100644 25/25.go create mode 100644 25/25_test.go diff --git a/23/23.2.go b/23/23.2.go new file mode 100644 index 0000000..1317ac0 --- /dev/null +++ b/23/23.2.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" +) + +/* + This was my third attempt at solving this - the first time trying to work out the + pattern of the registers from interpreting the 'assembly'. I gave up on that and + turned my input instructions into something closer to very messy go. That didn't + quite work either, I had to figure out the register values properly and restructure + the loops resulting in the final version below. I found this the most challenging of + the puzzles so far - not sure I'd have finished this without some of the hints from + the AoC subreddit. +*/ + +func main() { + f := 0 + h := 0 + + for b := 106500; b <= 123500; b += 17 { + f = 1 + for d := 2; d <= b; d++ { + for e := 2; e <= b; e++ { + if b%d != 0 { // thanks to AoC reddit for this hint + break + } + if d*e == b { + f = 0 + } + } + } + if f == 0 { + h += 1 + } + } + fmt.Println(h) +} diff --git a/23/23.go b/23/23.go new file mode 100644 index 0000000..cca8004 --- /dev/null +++ b/23/23.go @@ -0,0 +1,130 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// cat input | go run 23.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) + } + + reg := []string{"a", "b", "c", "d", "e", "f", "g", "h"} + for r := range reg { + registers[reg[r]] = 0 + } + + pc := 0 + mulcount := 0 + + for pc < len(instructions) && pc >= 0 { + + instruction := instructions[pc] + + /* + fmt.Printf("%v: %8v %8v %8v %8v %8v %8v %8v %8v\n",pc, registers["a"], + registers["b"],registers["c"], + registers["d"],registers["e"], + registers["f"],registers["g"],registers["h"]) + */ + + switch instruction.instr { + case "set": + pc = instrSet(®isters, instruction, pc) + case "sub": + pc = instrSub(®isters, instruction, pc) + case "mul": + pc = instrMul(®isters, instruction, pc) + mulcount++ + case "jnz": + pc = instrJnz(®isters, instruction, pc) + default: + fmt.Println("Instruction invalid!") + } + pc++ + } + fmt.Println(pc, registers, mulcount, registers["h"]) +} + +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 instrSub(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 instrJnz(registers *map[string]int, i instruction, pc int) int { + r := *registers + + cmp := r[i.register] + n, err := strconv.Atoi(i.register) + if err == nil { + cmp = n + } + + if cmp != 0 { + if i.argIsInt { + pc = (pc + i.argInt) - 1 + } else { + pc = (pc + r[i.argReg]) - 1 + } + } + + return pc +} diff --git a/24/24.go b/24/24.go new file mode 100644 index 0000000..69601d4 --- /dev/null +++ b/24/24.go @@ -0,0 +1,113 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// cat input | go run 24.go + +type comp struct { + a int + b int +} + +type bridge struct { + components []comp + last int +} + +func main() { + + scanner := bufio.NewScanner(os.Stdin) + var components = []comp{} + + for scanner.Scan() { + s := strings.Split(scanner.Text(), "/") + a, _ := strconv.Atoi(s[0]) + b, _ := strconv.Atoi(s[1]) + c := comp{a, b} + components = append(components, c) + } + + b := bridge{[]comp{}, 0} + bridges := []bridge{b} + oldcount := -1 + + for oldcount != 0 { + nb := []bridge{} + oldcount = 0 + for x := range bridges { + c, tb := BuildBridges(bridges[x], components) + oldcount += c + nb = append(nb, tb...) + } + bridges = nb + } + + maxlen := 0 + for p := range bridges { + if len(bridges[p].components) > maxlen { + maxlen = len(bridges[p].components) + } + } + + maxtot := 0 + maxlongest := 0 + for p := range bridges { + tot := 0 + for x := range bridges[p].components { + tot += bridges[p].components[x].a + tot += bridges[p].components[x].b + } + if len(bridges[p].components) == maxlen && tot > maxlongest { + maxlongest = tot + } + if tot > maxtot { + maxtot = tot + } + } + fmt.Println(maxtot, maxlongest) + +} + +func BuildBridges(b bridge, components []comp) (int, []bridge) { + var bridges = []bridge{} + + used := 0 + for c := range components { + + tc := components[c] + if isUsable(tc, b.components) && (tc.a == b.last || tc.b == b.last) { + used++ + nb := make([]comp, len(b.components)) + copy(nb, b.components) + nb = append(nb, tc) + nlast := -1 + if tc.a == b.last { + nlast = tc.b + } else { + nlast = tc.a + } + newbridge := bridge{nb, nlast} + bridges = append(bridges, newbridge) + } + } + if used == 0 { + bridges = append(bridges, b) + } + + return used, bridges +} + +func isUsable(n comp, h []comp) bool { + for c := range h { + if n.a == h[c].a && n.b == h[c].b { + return false + } + } + return true +} diff --git a/25/25.go b/25/25.go new file mode 100644 index 0000000..78bbf8a --- /dev/null +++ b/25/25.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" +) + +// go run 25.go + +type instruction struct { + state string + condition int + write int + move int + newState string +} + +var production = []instruction{ + {"a", 0, 1, 1, "b"}, + {"a", 1, 0, -1, "d"}, + {"b", 0, 1, 1, "c"}, + {"b", 1, 0, 1, "f"}, + {"c", 0, 1, -1, "c"}, + {"c", 1, 1, -1, "a"}, + {"d", 0, 0, -1, "e"}, + {"d", 1, 1, 1, "a"}, + {"e", 0, 1, -1, "a"}, + {"e", 1, 0, 1, "b"}, + {"f", 0, 0, 1, "c"}, + {"f", 1, 0, 1, "e"}, +} + +func main() { + fmt.Println(ProcessInstructions(production, 12317297)) +} + +func ProcessInstructions(instructions []instruction, count int) int { + pos := 0 + state := instructions[0].state + tape := make(map[int]int) + + for i := 0; i < count; i++ { + + for r := range instructions { + inst := instructions[r] + if inst.state == state && inst.condition == tape[pos] { + state = inst.newState + tape[pos] = inst.write + pos += inst.move + break + } + } + } + + cksum := 0 + for _, v := range tape { + if v == 1 { + cksum++ + } + } + + return cksum +} diff --git a/25/25_test.go b/25/25_test.go new file mode 100644 index 0000000..1cdad09 --- /dev/null +++ b/25/25_test.go @@ -0,0 +1,22 @@ +package main + +import ( + "testing" +) + +var test = []instruction{ + {"a", 0, 1, 1, "b"}, + {"a", 1, 0, -1, "b"}, + {"b", 0, 1, -1, "a"}, + {"b", 1, 1, 1, "a"}} + +func TestInstructions(t *testing.T) { + v := ProcessInstructions(test, 6) + if v != 3 { + t.Error( + "For", test, + "expected 3", + "got", v, + ) + } +}