day22, part1, struggle
This commit is contained in:
parent
2b3c7f4ca6
commit
45d03e5ab3
|
@ -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?
|
||||
let's read file, and calc max height present?
|
||||
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?
|
||||
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
|
||||
* 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
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -6,13 +6,13 @@ import (
|
|||
|
||||
func Run() int {
|
||||
fmt.Print("oi, hello day 22")
|
||||
filename := "day22/example"
|
||||
filename := "day22/input"
|
||||
blocks := ReadBlockFile(filename)
|
||||
byZ := BlocksByZ(blocks)
|
||||
|
||||
space := NewSpace(byZ)
|
||||
space.SettleAll()
|
||||
|
||||
result := space.CountFreeBlocks()
|
||||
result := space.ThirdTimeCountFreeBlocks()
|
||||
return result
|
||||
}
|
||||
|
|
105
day22/space.go
105
day22/space.go
|
@ -1,6 +1,11 @@
|
|||
package day22
|
||||
|
||||
import "log"
|
||||
import (
|
||||
// "fmt"
|
||||
"log"
|
||||
"slices"
|
||||
// "time"
|
||||
)
|
||||
|
||||
type Space struct {
|
||||
MaxZ uint
|
||||
|
@ -18,16 +23,37 @@ func NewSpace(blocksByZ [][]*Block) Space {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Space)CountFreeBlocks() (result int) {
|
||||
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) {
|
||||
allBlocks := make(map[*Block]any)
|
||||
|
||||
for _, row := range s.SettledOnZ {
|
||||
for _, block := range row {
|
||||
allBlocks[block] = struct{}{}
|
||||
if len(block.SupportedBy) == 1 {
|
||||
log.Printf("in block %+v. only support is %+v", block, block.SupportedBy)
|
||||
log.Printf("should be NOT OK to remove %+v", block.SupportedBy)
|
||||
delete(allBlocks, block.SupportedBy[0])
|
||||
onlySupport := block.SupportedBy[0]
|
||||
log.Printf("in block %+v. only support is %+v", block, onlySupport)
|
||||
log.Printf("should be NOT OK to remove %+v", onlySupport)
|
||||
delete(allBlocks, onlySupport)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,21 +61,61 @@ func (s *Space)CountFreeBlocks() (result int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *Space)SettleAll() {
|
||||
for i := uint(1); i <= s.MaxZ; i++ {
|
||||
s.SettleZ(i)
|
||||
func (s *Space) ThirdTimeCountFreeBlocks() (result int) {
|
||||
// for each block create a new space without it. try to settle and check if 0 moved
|
||||
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
|
||||
func (s *Space)SettleZ(z uint) {
|
||||
func (s *Space) SettleZ(z uint) (totalMoved int) {
|
||||
blocksToSettle := s.UnsettledByZ[int(z)]
|
||||
|
||||
for _, block := range blocksToSettle {
|
||||
s.SettleBlock(block)
|
||||
hasMoved := s.SettleBlock(block)
|
||||
if hasMoved {
|
||||
totalMoved += 1
|
||||
}
|
||||
}
|
||||
|
||||
s.UnsettledByZ[int(z)] = nil
|
||||
return
|
||||
}
|
||||
|
||||
// for the block:
|
||||
|
@ -59,20 +125,29 @@ func (s *Space)SettleZ(z uint) {
|
|||
// set Z for block to Z+1, settled to true
|
||||
// add block as highest settled for all the XY
|
||||
// add block to MaxSettledOnXY
|
||||
func (s *Space)SettleBlock(block *Block) {
|
||||
func (s *Space) SettleBlock(block *Block) (hasMoved bool) {
|
||||
initialZ := block.Z
|
||||
underZMax := uint(0)
|
||||
underZBlocks := make([]*Block, 0)
|
||||
// fmt.Printf("\n>> for block %s\n", block)
|
||||
for _, xy := range block.getXY() {
|
||||
underBlock, found := s.MaxSettledOnXY[xy]
|
||||
// if block.NameNum
|
||||
if found {
|
||||
underBlockMaxZ := underBlock.Z + underBlock.ZHeight
|
||||
// action := " 'skipping' "
|
||||
if underBlockMaxZ > underZMax {
|
||||
underZBlocks = []*Block{underBlock}
|
||||
underZMax = underBlockMaxZ
|
||||
// action = " 'overriding' "
|
||||
} else if underBlockMaxZ == underZMax {
|
||||
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
|
||||
}
|
||||
|
@ -86,4 +161,12 @@ func (s *Space)SettleBlock(block *Block) {
|
|||
block.IsSettled = true
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -85,3 +85,22 @@ func TestSpaceExampleSettleAll(t *testing.T) {
|
|||
// 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
|
||||
}
|
||||
|
||||
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
9
go.mod
|
@ -1,3 +1,12 @@
|
|||
module sunshine.industries/aoc2023
|
||||
|
||||
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
|
||||
)
|
||||
|
|
|
@ -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=
|
Loading…
Reference in New Issue