day22: initial block setting
This commit is contained in:
parent
7b34b52e5e
commit
3ede691333
|
@ -14,6 +14,7 @@ type XY struct {
|
|||
}
|
||||
|
||||
type Block struct {
|
||||
NameNum int
|
||||
XMin, XMax uint
|
||||
YMin, YMax uint
|
||||
Z uint
|
||||
|
@ -23,8 +24,8 @@ type Block struct {
|
|||
}
|
||||
|
||||
func (b *Block) String() string {
|
||||
return fmt.Sprintf("[Block x:%d-%d, y:%d-%d, z:%d, h:%d, isSettled %t]",
|
||||
b.XMin, b.XMax, b.YMin, b.YMax, b.Z, b.ZHeight, b.IsSettled)
|
||||
return fmt.Sprintf("[Block %d - x:%d-%d, y:%d-%d, z:%d, h:%d, isSettled %t]",
|
||||
b.NameNum, b.XMin, b.XMax, b.YMin, b.YMax, b.Z, b.ZHeight, b.IsSettled)
|
||||
}
|
||||
|
||||
func AtoIOrPanic(a string) int {
|
||||
|
@ -35,7 +36,8 @@ func AtoIOrPanic(a string) int {
|
|||
return n
|
||||
}
|
||||
|
||||
func ReadBlock(line string) (b Block) {
|
||||
func ReadBlock(line string, num int) (b Block) {
|
||||
b.NameNum = num
|
||||
re := regexp.MustCompile(`(\d+),(\d+),(\d+)~(\d+),(\d+),(\d+)`)
|
||||
matches := re.FindStringSubmatch(line)
|
||||
|
||||
|
@ -70,8 +72,8 @@ func ReadBlockFile(filename string) (blocks []*Block) {
|
|||
}
|
||||
|
||||
text := strings.TrimSpace(string(bytes))
|
||||
for _, line := range strings.Split(text, "\n") {
|
||||
block := ReadBlock(line)
|
||||
for i, line := range strings.Split(text, "\n") {
|
||||
block := ReadBlock(line, i)
|
||||
blocks = append(blocks, &block)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ func TestReadBlock(t *testing.T) {
|
|||
1,1,8~1,1,9`
|
||||
|
||||
for _, line := range strings.Split(lines, "\n") {
|
||||
b := ReadBlock(line)
|
||||
b := ReadBlock(line, 0)
|
||||
t.Logf("read %s into block %+v", line, b)
|
||||
t.Logf("XY coords for %+v are : %+v", b, b.getXY())
|
||||
}
|
||||
|
|
|
@ -29,4 +29,5 @@ 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.
|
||||
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)
|
||||
** i can already imagine secon part? what is the most volume that can be disintegrated? or what? most volume is just all
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package day22
|
||||
|
||||
type Space struct {
|
||||
MaxZ uint
|
||||
SettledOnZ [][]*Block
|
||||
MaxSettledOnXY map[XY]*Block
|
||||
UnsettledByZ [][]*Block
|
||||
}
|
||||
|
||||
func NewSpace(blocksByZ [][]*Block) Space {
|
||||
return Space{
|
||||
UnsettledByZ: blocksByZ,
|
||||
MaxZ: uint(len(blocksByZ)),
|
||||
MaxSettledOnXY: make(map[XY]*Block),
|
||||
SettledOnZ: make([][]*Block, len(blocksByZ)),
|
||||
}
|
||||
}
|
||||
|
||||
// settle all blocks in Z, remove Z from UnsettledByZ
|
||||
func (s *Space)SettleZ(z uint) {
|
||||
|
||||
}
|
||||
|
||||
// for the block:
|
||||
// check all XY in MaxSettledOnXY
|
||||
// if there are any settled blocks on these XY, find max of their Z
|
||||
// for all blocks with that Z - add block to their 'supports'
|
||||
// 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) {
|
||||
underZMax := uint(0)
|
||||
underZBlocks := make([]*Block, 0)
|
||||
for _, xy := range block.getXY() {
|
||||
underBlock, found := s.MaxSettledOnXY[xy]
|
||||
// if block.NameNum
|
||||
if found {
|
||||
if underBlock.Z > underZMax {
|
||||
underZBlocks = []*Block{underBlock}
|
||||
underZMax = underBlock.Z
|
||||
} else if underBlock.Z == underZMax {
|
||||
underZBlocks = append(underZBlocks, underBlock)
|
||||
}
|
||||
}
|
||||
s.MaxSettledOnXY[xy] = block
|
||||
}
|
||||
|
||||
for _, settledUnderblock := range underZBlocks {
|
||||
settledUnderblock.Supports = append(settledUnderblock.Supports, block)
|
||||
}
|
||||
|
||||
block.Z = underZMax + 1
|
||||
block.IsSettled = true
|
||||
|
||||
s.SettledOnZ[block.Z] = append(s.SettledOnZ[block.Z], block)
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package day22
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSpaceSettleSingle(t *testing.T) {
|
||||
filename := "example"
|
||||
blocks := ReadBlockFile(filename)
|
||||
byZ := BlocksByZ(blocks)
|
||||
|
||||
space := NewSpace(byZ)
|
||||
t.Logf("read space %+v", space)
|
||||
|
||||
block := blocks[2]
|
||||
t.Logf("block before setting %+v", block)
|
||||
space.SettleBlock(block)
|
||||
t.Logf("space after settings %+v:\n%+v", block, space)
|
||||
}
|
||||
|
||||
func TestSpaceSettleSecondNearby(t *testing.T) {
|
||||
filename := "example"
|
||||
blocks := ReadBlockFile(filename)
|
||||
byZ := BlocksByZ(blocks)
|
||||
|
||||
space := NewSpace(byZ)
|
||||
t.Logf("read space %+v", space)
|
||||
|
||||
block1 := blocks[0]
|
||||
block2 := blocks[3]
|
||||
t.Logf("block 1 before setting %+v", block1)
|
||||
space.SettleBlock(block1)
|
||||
t.Logf("space after settling block 1 %+v", space)
|
||||
t.Logf("block 2 before setting %+v", block2)
|
||||
space.SettleBlock(block2)
|
||||
t.Logf("space after settling block 2 %+v", space)
|
||||
t.Logf("space after settling %+v", space)
|
||||
}
|
||||
|
||||
func TestSpaceSettleThirdOnTopFirst(t *testing.T) {
|
||||
filename := "example"
|
||||
blocks := ReadBlockFile(filename)
|
||||
byZ := BlocksByZ(blocks)
|
||||
|
||||
space := NewSpace(byZ)
|
||||
t.Logf("read space %+v", space)
|
||||
|
||||
block1 := blocks[0]
|
||||
block2 := blocks[3]
|
||||
block3 := blocks[2] // should overlap X & Y coords of block 1
|
||||
t.Logf("block 1 before setting %+v", block1)
|
||||
space.SettleBlock(block1)
|
||||
t.Logf("space after settling block 1 %+v", space)
|
||||
t.Logf("block 2 before setting %+v", block2)
|
||||
space.SettleBlock(block2)
|
||||
t.Logf("space after settling block 2 %+v", space)
|
||||
t.Logf("block 3 before setting %+v", block3)
|
||||
space.SettleBlock(block3)
|
||||
t.Logf("space after settling block 3 %+v", space)
|
||||
t.Logf("space after settling %+v", space)
|
||||
|
||||
t.Logf("blocks 1 & 3 should support it: %+v , %+v", block1.Supports, block2.Supports)
|
||||
// because block 3 is 0-2, 2-2
|
||||
// and that overlaps 1-1, 0-2 AND 0-0, 0-2
|
||||
t.Logf("other blocks should not supt %+v", block3.Supports)
|
||||
}
|
Loading…
Reference in New Issue