From 740bf24df692cbb26b4fb7006d509c5c4a969933 Mon Sep 17 00:00:00 2001 From: James Griffin Date: Mon, 14 Dec 2020 21:21:39 -0400 Subject: [PATCH] Day 14: Part 1 and 2 Signed-off-by: James Griffin --- fourteen/day_fourteen.go | 199 ++++++++++++ fourteen/day_fourteen_test.go | 46 +++ fourteen/input.txt | 585 ++++++++++++++++++++++++++++++++++ fourteen/sample.txt | 4 + fourteen/sample2.txt | 5 + fourteen/sample3.txt | 4 + main.go | 10 +- 7 files changed, 850 insertions(+), 3 deletions(-) create mode 100644 fourteen/day_fourteen.go create mode 100644 fourteen/day_fourteen_test.go create mode 100644 fourteen/input.txt create mode 100644 fourteen/sample.txt create mode 100644 fourteen/sample2.txt create mode 100644 fourteen/sample3.txt diff --git a/fourteen/day_fourteen.go b/fourteen/day_fourteen.go new file mode 100644 index 0000000..e3760c8 --- /dev/null +++ b/fourteen/day_fourteen.go @@ -0,0 +1,199 @@ +package fourteen + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +type command struct { + mem int + pointer int + + mask string + isMask bool +} + +type computer struct { + memory map[int]uint64 + m map[int]bool + + mask string + ones uint64 + zeros uint64 + + input []command + executed bool +} + +func (c *computer) load(filename string) error { + file, err := os.Open(filename) + if err != nil { + return err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + inputs := strings.Split(scanner.Text(), " = ") + if len(inputs) != 2 { + return fmt.Errorf("Unable to parse input %q", scanner.Text()) + } + + if inputs[0] == "mask" { + c.input = append(c.input, command{ + isMask: true, + mask: inputs[1], + }) + } else { + var pointer, mem int + count, err := fmt.Sscanf(inputs[0], "mem[%d]", &pointer) + if count != 1 || err != nil { + return fmt.Errorf("Unable to parse memory location from %s", inputs[0]) + } + mem, err = strconv.Atoi(inputs[1]) + + c.input = append(c.input, command{ + isMask: false, + mem: mem, + pointer: pointer, + }) + } + } + + c.memory = make(map[int]uint64, len(c.input)) + return nil +} + +func newComputer(filename string) *computer { + c := &computer{} + c.mask = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + c.executed = false + if err := c.load(filename); err != nil { + fmt.Println(err.Error()) + return nil + } + + return c +} + +func (c *computer) execute() { + c.executed = true + + for _, input := range c.input { + if input.isMask { + c.mask = input.mask + c.ones = 0 + c.zeros = 0 + + for i := 0; i < len(input.mask); i++ { + switch string(input.mask[len(input.mask)-1-i]) { + case "0": + c.zeros += 1 << i + case "1": + c.ones += 1 << i + } + } + + continue + } + + value := uint64(input.mem) + value |= c.ones + value &^= c.zeros + c.memory[input.pointer] = value + } +} + +func (c *computer) executeV2() { + c.executed = true + + for _, input := range c.input { + if input.isMask { + c.mask = input.mask + c.ones = 0 + c.zeros = 0 + for i := 0; i < len(input.mask); i++ { + switch string(input.mask[len(input.mask)-1-i]) { + case "0": + c.zeros += 1 << i + case "1": + c.ones += 1 << i + } + } + + continue + } + + value := uint64(input.mem) + location := uint64(input.pointer) | c.ones + + for _, p := range c.memMask(location) { + c.memory[p] = value + } + } +} + +func (c *computer) memMask(p uint64) []int { + locations := []int{0} + + for i := 0; i < len(c.mask); i++ { + switch string(c.mask[len(c.mask)-1-i]) { + case "X": + for j, l := range locations { + locations = append(locations, int(l|(1<