From de7df62e28cba20d0b03983a4bc0a1ae0a210316 Mon Sep 17 00:00:00 2001 From: Nihilazo Date: Mon, 14 Dec 2020 19:33:34 +0000 Subject: [PATCH] added day 14 part 2 --- day14/input.example2 | 4 ++ day14/main.go | 152 ++++++++++++++++++++++++++++++------------- 2 files changed, 112 insertions(+), 44 deletions(-) create mode 100644 day14/input.example2 diff --git a/day14/input.example2 b/day14/input.example2 new file mode 100644 index 0000000..b4b4e06 --- /dev/null +++ b/day14/input.example2 @@ -0,0 +1,4 @@ +mask = 000000000000000000000000000000X1001X +mem[42] = 100 +mask = 00000000000000000000000000000000X0XX +mem[26] = 1 \ No newline at end of file diff --git a/day14/main.go b/day14/main.go index 8684bd4..8cd8ac2 100644 --- a/day14/main.go +++ b/day14/main.go @@ -1,52 +1,116 @@ package main import ( - "strings" - "strconv" - "io/ioutil" - "fmt" - "regexp" + "fmt" + "io/ioutil" + "regexp" + "strconv" + "strings" ) func main() { - mem := make(map[int64]int64) // The values are 36-bit - using int64s - memre, _ := regexp.Compile(`mem\[(\d+)\] = (\d+)`) // isn't matching all memory lines? - maskre, _ := regexp.Compile(`mask = ([01X]+)`) - d, _ := ioutil.ReadFile("input") - lines := strings.Split(string(d),"\n") - var mask string - for _, l := range lines { - memMatch := memre.FindStringSubmatch(l) - maskMatch := maskre.FindStringSubmatch(l) - if len(memMatch) != 0 { - addr, _ := strconv.ParseInt(memMatch[1], 10, 64) - value, _ := strconv.ParseInt(memMatch[2], 10, 64) + mem := make(map[int64]int64) // The values are 36-bit - using int64s + memre, _ := regexp.Compile(`mem\[(\d+)\] = (\d+)`) // isn't matching all memory lines? + maskre, _ := regexp.Compile(`mask = ([01X]+)`) + d, _ := ioutil.ReadFile("input") + lines := strings.Split(string(d), "\n") + var mask string + for _, l := range lines { + memMatch := memre.FindStringSubmatch(l) + maskMatch := maskre.FindStringSubmatch(l) + if len(memMatch) != 0 { + addr, _ := strconv.ParseInt(memMatch[1], 10, 64) + value, _ := strconv.ParseInt(memMatch[2], 10, 64) + + // Applying the bitmask using strings because I'm doing this the stupid way + valueString := strconv.FormatInt(value, 2) // value as a binary string + v := "" + // Pad out to 36 bits + for i := 36 - len(valueString); i > 0; i-- { + v = "0" + v + } + v = v + valueString + applied := "" + for i, _ := range v { + if mask[i] != byte('X') { + applied += string(mask[i]) + } else { + applied += string(v[i]) + } + } + av, _ := strconv.ParseInt(applied, 2, 64) // applied + mem[addr] = av + } else if len(maskMatch) != 0 { + mask = maskMatch[1] + } else { + } + } + var sum int64 = 0 + for _, v := range mem { + sum += v + } + fmt.Println("Part 1:", sum) + // Part 2 + mem = make(map[int64]int64) // reset memory + mask = "" + for _, l := range lines { + memMatch := memre.FindStringSubmatch(l) + maskMatch := maskre.FindStringSubmatch(l) + if len(memMatch) != 0 { + addr, _ := strconv.ParseInt(memMatch[1], 10, 64) + value, _ := strconv.ParseInt(memMatch[2], 10, 64) + addrString := strconv.FormatInt(addr, 2) // addr as a binary string + v := "" + // Pad out to 36 bits + for i := 36 - len(addrString); i > 0; i-- { + v = "0" + v + } + v = v + addrString + applied := "" + var addresses []string + for i, _ := range v { + if mask[i] != byte('0') { + applied += string(mask[i]) + } else { + applied += string(v[i]) + } + } + addresses = constructAddresses(applied) + for _, a := range addresses { + d, _ := strconv.ParseInt(a, 2, 64) + mem[d] = value + } + } else if len(maskMatch) != 0 { + mask = maskMatch[1] + } else { + } + } + sum = 0 + for _, v := range mem { + sum += v + } + fmt.Println("Part 2:", sum) - // Applying the bitmask using strings because I'm doing this the stupid way - valueString := strconv.FormatInt(value, 2) // value as a binary string - v := "" - // Pad out to 36 bits - for i := 36-len(valueString); i > 0; i-- { - v = "0" + v - } - v = v + valueString - applied := "" - for i, _ := range v { - if mask[i] != byte('X') { - applied += string(mask[i]) - } else { - applied += string(v[i]) - } - } - av, _:= strconv.ParseInt(applied, 2, 64) // applied - mem[addr] = av - } else if len(maskMatch) != 0 { - mask = maskMatch[1] - } else {} - } - var sum int64 = 0 - for _, v := range mem { - sum += v - } - fmt.Println("Part 1:", sum) } + +func constructAddresses(addr string) []string { + var out []string + x := false + for _, c := range addr { + if c == 'X' { + x = true + } + } + if x == true { + ones := constructAddresses(strings.Replace(addr, "X", "1", 1)) + zeroes := constructAddresses(strings.Replace(addr, "X", "0", 1)) + for _, i := range ones { + out = append(out, i) + } + for _, i := range zeroes { + out = append(out, i) + } + return out + } + return []string{addr} +} \ No newline at end of file