day4 part 2

This commit is contained in:
Donald Ball 2025-12-06 19:41:51 -05:00
parent 2fe4311e10
commit e26fc98af0

View file

@ -17,13 +17,15 @@ func readLines(filename string) []string {
} }
type warehouse struct { type warehouse struct {
boxes bitmap.Bitmap boxes *bitmap.Bitmap
width uint32 width uint32
height uint32 height uint32
} }
func buildWarehouse(lines []string) warehouse { func buildWarehouse(lines []string) warehouse {
wh := warehouse{} wh := warehouse{
boxes: &bitmap.Bitmap{},
}
wh.height = uint32(len(lines)) wh.height = uint32(len(lines))
if wh.height == 0 { if wh.height == 0 {
return wh return wh
@ -35,7 +37,7 @@ func buildWarehouse(lines []string) warehouse {
for y, line := range lines { for y, line := range lines {
for x, char := range line { for x, char := range line {
if char == '@' { if char == '@' {
set(&wh.boxes, wh.width, wh.height, uint32(x), uint32(y)) set(wh.boxes, wh.width, wh.height, uint32(x), uint32(y))
} }
} }
} }
@ -55,7 +57,9 @@ func debug(area *bitmap.Bitmap, width uint32) {
}) })
} }
func buildNeighbors(width uint32, height uint32, x uint32, y uint32) *bitmap.Bitmap { func buildNeighbors(width uint32, height uint32, offset uint32) *bitmap.Bitmap {
y := offset / width
x := offset % width
var neighbors bitmap.Bitmap var neighbors bitmap.Bitmap
set(&neighbors, width, height, x+1, y) set(&neighbors, width, height, x+1, y)
set(&neighbors, width, height, x-1, y) set(&neighbors, width, height, x-1, y)
@ -71,16 +75,30 @@ func buildNeighbors(width uint32, height uint32, x uint32, y uint32) *bitmap.Bit
func (wh warehouse) countAccessibleBoxes() uint32 { func (wh warehouse) countAccessibleBoxes() uint32 {
boxes := wh.boxes.Clone(nil) boxes := wh.boxes.Clone(nil)
boxes.Filter(func(offset uint32) bool { boxes.Filter(func(offset uint32) bool {
y := offset / wh.width neighbors := buildNeighbors(wh.width, wh.height, offset)
x := offset % wh.width neighbors.And(*wh.boxes)
neighbors := buildNeighbors(wh.width, wh.height, x, y)
neighbors.And(wh.boxes)
accessible := neighbors.Count() < 4 accessible := neighbors.Count() < 4
return accessible return accessible
}) })
return uint32(boxes.Count()) return uint32(boxes.Count())
} }
func (wh *warehouse) removeAccessibleBoxes() uint32 {
boxes := wh.boxes.Clone(nil)
removed := uint32(0)
boxes.Filter(func(offset uint32) bool {
neighbors := buildNeighbors(wh.width, wh.height, offset)
neighbors.And(*wh.boxes)
accessible := neighbors.Count() < 4
if accessible {
removed++
}
return !accessible
})
wh.boxes = &boxes
return removed
}
func main() { func main() {
filename := "input0.txt" filename := "input0.txt"
if len(os.Args) > 1 { if len(os.Args) > 1 {
@ -89,4 +107,13 @@ func main() {
lines := readLines(filename) lines := readLines(filename)
wh := buildWarehouse(lines) wh := buildWarehouse(lines)
fmt.Printf("%v\n", wh.countAccessibleBoxes()) fmt.Printf("%v\n", wh.countAccessibleBoxes())
total := uint32(0)
for {
count := wh.removeAccessibleBoxes()
if count == 0 {
break
}
total += count
}
fmt.Printf("%v\n", total)
} }