2020 Day 14 Complete
This commit is contained in:
119
2020/day14/main.go
Normal file
119
2020/day14/main.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("# Day 13")
|
||||
inp := h.StdinToStringSlice()
|
||||
vsn := h.Atoi(h.OptArgNumber(1, "1"))
|
||||
if vsn == 1 {
|
||||
part1(inp)
|
||||
} else {
|
||||
part2(inp)
|
||||
}
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
memory := make(map[int]uint)
|
||||
var mask map[int]uint
|
||||
for _, v := range inp {
|
||||
pts := strings.Split(v, " = ")
|
||||
if pts[0] == "mask" {
|
||||
mask = make(map[int]uint)
|
||||
parsemask := pts[1]
|
||||
for k := range parsemask {
|
||||
if parsemask[k] != 'X' {
|
||||
place := (len(parsemask) - k - 1)
|
||||
if parsemask[k] == '0' {
|
||||
mask[place] = 0
|
||||
} else {
|
||||
mask[place] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var reg int
|
||||
fmt.Sscanf(pts[0], "mem[%d]", ®)
|
||||
val := uint(h.Atoi(pts[1]))
|
||||
store := applyMask(val, mask)
|
||||
memory[reg] = store
|
||||
}
|
||||
}
|
||||
|
||||
var res uint
|
||||
for _, v := range memory {
|
||||
res = res + v
|
||||
}
|
||||
fmt.Println("## Part 1")
|
||||
fmt.Println("Sum:", res)
|
||||
}
|
||||
|
||||
func applyMask(val uint, mask map[int]uint) uint {
|
||||
for k, v := range mask {
|
||||
if v == 0 {
|
||||
val = val &^ (1 << k)
|
||||
} else if v == 1 {
|
||||
val = val | (1 << k)
|
||||
}
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
memory := make(map[uint]uint)
|
||||
var mask string
|
||||
for _, v := range inp {
|
||||
pts := strings.Split(v, " = ")
|
||||
if pts[0] == "mask" {
|
||||
mask = pts[1]
|
||||
} else {
|
||||
var reg int
|
||||
fmt.Sscanf(pts[0], "mem[%d]", ®)
|
||||
val := uint(h.Atoi(pts[1]))
|
||||
stores := []uint{uint(reg)}
|
||||
for k := range mask {
|
||||
bit := len(mask) - k - 1
|
||||
var wrk []uint
|
||||
for i := range stores {
|
||||
switch mask[k] {
|
||||
case '0':
|
||||
wrk = append(wrk, stores[i])
|
||||
case '1':
|
||||
wrk = append(wrk, setBitTo(stores[i], bit, true))
|
||||
case 'X':
|
||||
wrk = append(wrk, floatBit(stores[i], bit)...)
|
||||
}
|
||||
}
|
||||
stores = append([]uint{}, wrk...)
|
||||
}
|
||||
for k := range stores {
|
||||
memory[stores[k]] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
var sum uint
|
||||
for k := range memory {
|
||||
sum = sum + memory[k]
|
||||
}
|
||||
fmt.Println("## Part 2")
|
||||
fmt.Println("Sum:", sum)
|
||||
}
|
||||
|
||||
func setBitTo(addr uint, pos int, val bool) uint {
|
||||
if val {
|
||||
return addr | (1 << pos)
|
||||
} else {
|
||||
return addr &^ (1 << pos)
|
||||
}
|
||||
}
|
||||
func floatBit(addr uint, pos int) []uint {
|
||||
var ret []uint
|
||||
ret = append(ret, addr|(1<<pos))
|
||||
ret = append(ret, addr&^(1<<pos))
|
||||
return ret
|
||||
}
|
||||
Reference in New Issue
Block a user