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?
|
** 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
|
||||||
|
|
|
@ -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 {
|
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
|
||||||
}
|
}
|
||||||
|
|
103
day22/space.go
103
day22/space.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
9
go.mod
|
@ -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
|
||||||
|
)
|
||||||
|
|
|
@ -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