Completed part 2 of Day 22 puzzle (with a lot of help from Go code of rumkugel13 to correct my 2 bugs)

main
oabrivard 2 years ago
parent e30e6e8d0a
commit 94b71c93a1

@ -105,6 +105,13 @@ func (tower *Tower) layout(brick *Brick, currZ int) {
} }
} }
} }
brick.start.z = currZ
if brickHeight > 1 {
brick.end.z = currZ + brickHeight - 1
} else {
brick.end.z = currZ
}
} }
func (tower *Tower) addBrick(brick *Brick) { func (tower *Tower) addBrick(brick *Brick) {
@ -137,11 +144,11 @@ func (tower *Tower) addBrick(brick *Brick) {
func (tower *Tower) Print() { func (tower *Tower) Print() {
//for z := tower.maxHeight(); z >= 0; z-- { //for z := tower.maxHeight(); z >= 0; z-- {
for z := 8; z > 0; z-- { for z := 20; z > 0; z-- {
for x := 0; x < tower.floorWidth; x++ { for x := 0; x < tower.floorWidth; x++ {
for y := 0; y < tower.floorWidth; y++ { for y := 0; y < tower.floorWidth; y++ {
if tower.floors[z][x][y] != nil { if tower.floors[z][x][y] != nil {
fmt.Print(tower.floors[z][x][y].ID) fmt.Print(string(byte('A') - 1 + byte(tower.floors[z][x][y].ID)%26))
} else { } else {
fmt.Print(".") fmt.Print(".")
} }
@ -184,3 +191,141 @@ func Part1(lines []string) (int, []*Brick) {
tower.Print() tower.Print()
return count, bricks return count, bricks
} }
/*
func Part2(lines []string) {
// place bricks like Part1
// and change z coord of each brick once it is layed out
bricks := parseBricks(lines)
tower := NewTower(500, 10)
for _, brick := range bricks {
fmt.Printf("Placing brick %d (%v)~(%v)\n", brick.ID, brick.start, brick.end)
tower.addBrick(brick)
}
// sort brick by z coord desc (highest first)
slices.SortFunc(bricks, func(a, b *Brick) int {
return b.start.z - a.start.z
})
// for each brick
// if the brick above the current brick has just the current brick as support
// then add 1 + the total fall of the brick above (coming from the map "total fallen")
// Store the value in the map "total fallen" using the ID of the current brick
// end for
count := 0
for _, brick := range bricks {
for _, aboveBrick := range brick.supports {
if len(aboveBrick.supportedBy) == 0 {
log.Fatalln("Bug ", brick)
}
if len(aboveBrick.supportedBy) == 1 {
// will fall
}
}
}
}
*/
func buildDropList(brick *Brick, droppedList *map[int]bool) {
// Do not drop if the bricks below have not all been removed
for _, supportedBy := range brick.supportedBy {
if !(*droppedList)[supportedBy.ID] {
return
}
}
(*droppedList)[brick.ID] = true // the supported brick
for _, supportedBrick := range brick.supports {
dropAbove := true
for _, supportedBy := range supportedBrick.supportedBy {
if !(*droppedList)[supportedBy.ID] {
dropAbove = false
}
}
if dropAbove {
buildDropList(supportedBrick, droppedList) // the drops from the supported brick
}
}
}
func Part2(lines []string) int {
bricks := parseBricks(lines)
tower := NewTower(500, 10)
for _, brick := range bricks {
//fmt.Printf("Placing brick %d (%v)~(%v)\n", brick.ID, brick.start, brick.end)
tower.addBrick(brick)
}
// for debugging
slices.SortFunc(bricks, func(a, b *Brick) int {
return a.ID - b.ID
})
sum := 0
for _, brick := range bricks {
singleSupport := false
for _, supportedBrick := range brick.supports {
if len(supportedBrick.supportedBy) == 0 {
log.Fatalln("Bug ", brick)
}
if len(supportedBrick.supportedBy) == 1 {
singleSupport = true
}
}
/*
if singleSupport {
disintegrated := map[int]bool{brick.ID: true}
checkList := []*Brick{brick}
for len(checkList) > 0 {
// take first from checklist
check := checkList[0]
checkList = checkList[1:]
// for all bricks above, check ...
for _, above := range check.supports {
bricksRemoved := 0
// whether all bricks below it are disintegrated ...
for _, below := range above.supportedBy {
if disintegrated[below.ID] {
bricksRemoved++
}
}
if len(above.supportedBy) == bricksRemoved {
// then it would fall
checkList = append(checkList, above)
disintegrated[above.ID] = true
}
}
}
// do not include the brick we are currently checking
fmt.Printf("Brick %d would drop %d other bricks\n", brick.ID, len(disintegrated)-1)
sum += len(disintegrated) - 1
}
}
*/
if singleSupport {
dropList := map[int]bool{}
dropList[brick.ID] = true
if brick.ID == 14 {
fmt.Println("debug")
}
for _, supportedBrick := range brick.supports {
buildDropList(supportedBrick, &dropList)
}
fmt.Printf("Brick %d would drop %d other bricks\n", brick.ID, len(dropList)-1)
sum += len(dropList) - 1
}
}
tower.Print()
return sum
}

@ -35,3 +35,31 @@ func TestPart1WithInput(t *testing.T) {
t.Fatalf("expected 428, got %d", result) t.Fatalf("expected 428, got %d", result)
} }
} }
func TestPart2(t *testing.T) {
lines := []string{
"1,0,1~1,2,1", // 1
"0,0,2~2,0,2", // 2
"0,2,3~2,2,3", // 3
"0,0,4~0,2,4", // 4
"2,0,5~2,2,5", // 5
"0,1,6~2,1,6", // 6
"1,1,8~1,1,9", // 7
}
result := Part2(lines)
if result != 7 {
t.Fatalf("expected 7, got %d", result)
}
}
func TestPart2WithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := Part2(lines)
if result != 35654 {
t.Fatalf("expected 35654, got %d", result)
}
}

Loading…
Cancel
Save