day22, part1, struggle

This commit is contained in:
efim 2023-12-22 12:19:12 +00:00
parent 2b3c7f4ca6
commit 45d03e5ab3
7 changed files with 192 additions and 15 deletions

View File

@ -26,8 +26,26 @@ store z, and have 'settledZ', maybe with default -1?
** DONE now i guess what? do i want a sorted map? or just map from height to blocks on that hight? ** DONE now i guess what? do i want a sorted map? or just map from height to blocks on that hight?
let's read file, and calc max height present? let's read file, and calc max height present?
i suppose funciton to read file could also be initially entered via test, right? i suppose funciton to read file could also be initially entered via test, right?
** TODO now go through the z levels, block by block, doing setting. ** DONE now go through the z levels, block by block, doing setting.
i suppose i could organize setting methods around Space? i suppose i could organize setting methods around Space?
it will store (settledOnZ) and (maxSettledOnXY) it will store (settledOnZ) and (maxSettledOnXY)
** TODO [#A] when i settle single block. the maxSettledOnXY - should use (z + height) ** DONE [#A] when i settle single block. the maxSettledOnXY - should use (z + height)
** i can already imagine secon part? what is the most volume that can be disintegrated? or what? most volume is just all ** i can already imagine secon part? what is the most volume that can be disintegrated? or what? most volume is just all
* part 1, wrong answer.
i guess try to go, setting the input? block after block and try to check the calculations?
what i want to check:
how maxSettledOnXY works, how linking works. maybe i'll find a problem in few steps =C
** can't see anything just glancing around.
maybe then trying to pick a block and track what's under it?
* ok. let's try to brute force?
for each block, remove it?
create new space and try to settle it
** this is shit. why blocks move up?
2023/12/22 12:12:24 >>> starting for block [Block 1 - x:0-2, y:0-0, z:1, h:0, isSettled true] (supports [[Block 3 - x:0-0, y:0-2, z:3, h:0, isSettled true] [Block 4 - x:2-2, y:0-2, z:3, h:0, isSettled true] [Block 3 - x:0-0, y:0-2, z:2, h:0, isSettled true] [Block 4 - x:2-2, y:0-2, z:2, h:0, isSettled true]])
2023/12/22 12:12:24 block [Block 2 - x:0-2, y:2-2, z:2, h:0, isSettled true] moved from 1 to 2
2023/12/22 12:12:24 block [Block 3 - x:0-0, y:0-2, z:3, h:0, isSettled true] moved from 2 to 3
2023/12/22 12:12:24 block [Block 4 - x:2-2, y:0-2, z:3, h:0, isSettled true] moved from 2 to 3
2023/12/22 12:12:24 block [Block 5 - x:0-2, y:1-1, z:4, h:0, isSettled true] moved from 3 to 4
2023/12/22 12:12:24 block [Block 6 - x:1-1, y:1-1, z:5, h:1, isSettled true] moved from 4 to 5
2023/12/22 12:12:24 for block [Block 1 - x:0-2, y:0-0, z:1, h:0, isSettled true] new space has 5 moved

38
day22/printingSpace.go Normal file
View File

@ -0,0 +1,38 @@
package day22
import (
"math"
"github.com/tidwall/pinhole"
)
func TestPinhole() {
p := pinhole.New()
p.DrawCube(-0.3, -0.3, -0.3, 0.3, 0.3, 0.3)
p.Rotate(math.Pi/3, math.Pi/2, 0)
p.SavePNG("cube.png", 500, 500, nil)
}
func PrintSpace(s Space, filename string) {
// pinhole is from -1 to 1. let's use from 0 to 1.
// so coord should be divided by max height, and let's hope that they are not too wide
rotation := []float64{math.Pi/3, math.Pi/6, 0}
p := pinhole.New()
p.DrawRect(-1, -1, 1, 1, 0)
for _, zLevel := range s.SettledOnZ {
for _, block := range zLevel {
p.DrawCube(float64(block.XMin) / float64(s.MaxZ),
float64(block.YMin) / float64(s.MaxZ),
float64(block.Z) / float64(s.MaxZ),
float64(block.XMax + 1) / float64(s.MaxZ),
float64(block.YMax + 1) / float64(s.MaxZ),
float64(block.Z + block.ZHeight + 1) / float64(s.MaxZ))
}
}
p.Rotate(rotation[0], rotation[1], rotation[2])
p.SavePNG(filename, 1920, 1080, nil)
}

View File

@ -6,13 +6,13 @@ import (
func Run() int { func Run() int {
fmt.Print("oi, hello day 22") fmt.Print("oi, hello day 22")
filename := "day22/example" filename := "day22/input"
blocks := ReadBlockFile(filename) blocks := ReadBlockFile(filename)
byZ := BlocksByZ(blocks) byZ := BlocksByZ(blocks)
space := NewSpace(byZ) space := NewSpace(byZ)
space.SettleAll() space.SettleAll()
result := space.CountFreeBlocks() result := space.ThirdTimeCountFreeBlocks()
return result return result
} }

View File

@ -1,6 +1,11 @@
package day22 package day22
import "log" import (
// "fmt"
"log"
"slices"
// "time"
)
type Space struct { type Space struct {
MaxZ uint MaxZ uint
@ -18,6 +23,26 @@ func NewSpace(blocksByZ [][]*Block) Space {
} }
} }
func (s *Space) AgainCountFreeBlocks() (result int) {
for _, row := range s.SettledOnZ {
for _, block := range row {
thisSupports := block.Supports
canDisintegrate := true
for _, blockThisSupports := range thisSupports {
if len(blockThisSupports.SupportedBy) == 1 {
// we cannot disintigrate this block
canDisintegrate = false
}
}
if canDisintegrate {
result += 1
}
}
}
return
}
func (s *Space) CountFreeBlocks() (result int) { func (s *Space) CountFreeBlocks() (result int) {
allBlocks := make(map[*Block]any) allBlocks := make(map[*Block]any)
@ -25,9 +50,10 @@ func (s *Space)CountFreeBlocks() (result int) {
for _, block := range row { for _, block := range row {
allBlocks[block] = struct{}{} allBlocks[block] = struct{}{}
if len(block.SupportedBy) == 1 { if len(block.SupportedBy) == 1 {
log.Printf("in block %+v. only support is %+v", block, block.SupportedBy) onlySupport := block.SupportedBy[0]
log.Printf("should be NOT OK to remove %+v", block.SupportedBy) log.Printf("in block %+v. only support is %+v", block, onlySupport)
delete(allBlocks, block.SupportedBy[0]) log.Printf("should be NOT OK to remove %+v", onlySupport)
delete(allBlocks, onlySupport)
} }
} }
} }
@ -35,21 +61,61 @@ func (s *Space)CountFreeBlocks() (result int) {
return return
} }
func (s *Space)SettleAll() { func (s *Space) ThirdTimeCountFreeBlocks() (result int) {
for i := uint(1); i <= s.MaxZ; i++ { // for each block create a new space without it. try to settle and check if 0 moved
s.SettleZ(i) log.Println(">>>>> starting hardcode count <<<<<")
for rowNum, row := range s.SettledOnZ {
for blockNum, block := range row {
log.Printf(">>> starting for block %+v (supports %+v)\n", block, block.Supports)
newUnsettled := slices.Clone(s.SettledOnZ)
for rowNum, row := range newUnsettled {
newUnsettled[rowNum] = slices.Clone(row)
} }
newUnsettled[rowNum] = slices.Delete(newUnsettled[rowNum], blockNum, blockNum+1)
// and now copy the blocks
for rowNum, row := range newUnsettled {
for blockNum, block := range row {
newBlock := *block
newUnsettled[rowNum][blockNum] = &newBlock
}
}
newSpace := NewSpace(newUnsettled)
moved := newSpace.SettleAll()
if moved > 0 {
log.Printf("for block %+v new space has %d moved\n\n", block, moved)
} else {
log.Printf("for block %+v new space has %d moved\n\n", block, moved)
result += 1
}
}
}
return
}
func (s *Space) SettleAll() (totalMoved int) {
for i := uint(1); i <= s.MaxZ; i++ {
movedAfterLayer := s.SettleZ(i)
totalMoved += movedAfterLayer
}
return
} }
// settle all blocks in Z, remove Z from UnsettledByZ // settle all blocks in Z, remove Z from UnsettledByZ
func (s *Space)SettleZ(z uint) { func (s *Space) SettleZ(z uint) (totalMoved int) {
blocksToSettle := s.UnsettledByZ[int(z)] blocksToSettle := s.UnsettledByZ[int(z)]
for _, block := range blocksToSettle { for _, block := range blocksToSettle {
s.SettleBlock(block) hasMoved := s.SettleBlock(block)
if hasMoved {
totalMoved += 1
}
} }
s.UnsettledByZ[int(z)] = nil s.UnsettledByZ[int(z)] = nil
return
} }
// for the block: // for the block:
@ -59,20 +125,29 @@ func (s *Space)SettleZ(z uint) {
// set Z for block to Z+1, settled to true // set Z for block to Z+1, settled to true
// add block as highest settled for all the XY // add block as highest settled for all the XY
// add block to MaxSettledOnXY // add block to MaxSettledOnXY
func (s *Space)SettleBlock(block *Block) { func (s *Space) SettleBlock(block *Block) (hasMoved bool) {
initialZ := block.Z
underZMax := uint(0) underZMax := uint(0)
underZBlocks := make([]*Block, 0) underZBlocks := make([]*Block, 0)
// fmt.Printf("\n>> for block %s\n", block)
for _, xy := range block.getXY() { for _, xy := range block.getXY() {
underBlock, found := s.MaxSettledOnXY[xy] underBlock, found := s.MaxSettledOnXY[xy]
// if block.NameNum // if block.NameNum
if found { if found {
underBlockMaxZ := underBlock.Z + underBlock.ZHeight underBlockMaxZ := underBlock.Z + underBlock.ZHeight
// action := " 'skipping' "
if underBlockMaxZ > underZMax { if underBlockMaxZ > underZMax {
underZBlocks = []*Block{underBlock} underZBlocks = []*Block{underBlock}
underZMax = underBlockMaxZ underZMax = underBlockMaxZ
// action = " 'overriding' "
} else if underBlockMaxZ == underZMax { } else if underBlockMaxZ == underZMax {
underZBlocks = append(underZBlocks, underBlock) underZBlocks = append(underZBlocks, underBlock)
// action = " 'adding' "
} }
// fmt.Printf("checking under coord %+v. found under %+v. (%s) with %d ; maxZ %d\n directly supporting blocks are %+v\n",
// xy, underBlock, action, underBlockMaxZ, underZMax, underZBlocks)
} else {
// fmt.Printf("checking under coord %+v. nothing under\n", xy)
} }
s.MaxSettledOnXY[xy] = block s.MaxSettledOnXY[xy] = block
} }
@ -86,4 +161,12 @@ func (s *Space)SettleBlock(block *Block) {
block.IsSettled = true block.IsSettled = true
s.SettledOnZ[block.Z] = append(s.SettledOnZ[block.Z], block) s.SettledOnZ[block.Z] = append(s.SettledOnZ[block.Z], block)
// fmt.Printf(">> after settring block %s. supported by %+v\n\n", block, block.SupportedBy)
// time.Sleep(500 * time.Millisecond)
hasMoved = initialZ != block.Z
if hasMoved {
log.Printf("block %+v moved from %d to %d", block, initialZ, block.Z)
}
return
} }

View File

@ -85,3 +85,22 @@ func TestSpaceExampleSettleAll(t *testing.T) {
// i guess we can start with set of all blocks, then? // i guess we can start with set of all blocks, then?
// run over all, if some block is only supported by some underBlock - remove that underblock // run over all, if some block is only supported by some underBlock - remove that underblock
} }
func TestPinholeStart(t *testing.T) {
TestPinhole()
}
func TestExampleSpacePrint(t *testing.T) {
filename := "example"
blocks := ReadBlockFile(filename)
byZ := BlocksByZ(blocks)
space := NewSpace(byZ)
// PrintSpace(space, "before-settping.png")
space.SettleAll()
PrintSpace(space, "after-settping.png")
}

9
go.mod
View File

@ -1,3 +1,12 @@
module sunshine.industries/aoc2023 module sunshine.industries/aoc2023
go 1.21.4 go 1.21.4
require github.com/tidwall/pinhole v0.0.0-20210130162507-d8644a7c3d19
require (
github.com/fogleman/gg v1.3.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/google/btree v1.1.2 // indirect
golang.org/x/image v0.14.0 // indirect
)

10
go.sum Normal file
View File

@ -0,0 +1,10 @@
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/tidwall/pinhole v0.0.0-20210130162507-d8644a7c3d19 h1:PH18rfaiwA/34DAtuREBTrrByvZeLHqhfYh4SG7jYg4=
github.com/tidwall/pinhole v0.0.0-20210130162507-d8644a7c3d19/go.mod h1:5VfbOBfzaI6Y0XiGSkz7hiXgKtwYaDBI3plwKGsLonM=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=