day18: example optimized
This commit is contained in:
parent
d799b122ce
commit
b831e92e1f
136
day18/lagoon.go
136
day18/lagoon.go
|
@ -13,7 +13,7 @@ func Run() int {
|
|||
log.Println("hello day 18")
|
||||
log.Println("problem of lagoon bgins")
|
||||
filename := "day18/example"
|
||||
instructions := ReadInstructionas2(filename)
|
||||
instructions := ReadInstructionas(filename)
|
||||
h, w := calcHeightWidth(instructions)
|
||||
log.Printf("read %+v instructions", instructions)
|
||||
|
||||
|
@ -21,19 +21,22 @@ func Run() int {
|
|||
log.Println("created field")
|
||||
|
||||
// fmt.Println(field.String())
|
||||
field.digByInstructions(instructions)
|
||||
borderAmount := field.digByInstructions(instructions)
|
||||
|
||||
// fmt.Println(field.String())
|
||||
fmt.Println(field.String())
|
||||
// WriteToFile("borders.txt", field.String())
|
||||
// convert -size 3000x6000 xc:white -font "FreeMono" -pointsize 13 -fill black -draw @borders.txt borders.png
|
||||
|
||||
field.digInsides()
|
||||
insideAmount := field.digInsides()
|
||||
|
||||
log.Printf("border is %d; inside is %d", borderAmount, insideAmount)
|
||||
fmt.Println(field.String())
|
||||
// fmt.Println(field.Height, field.Width)
|
||||
// WriteToFile("fulldug.txt", field.String())
|
||||
// convert -size 3000x6000 xc:white -font "FreeMono" -pointsize 13 -fill black -draw @fulldug.txt fulldug.png
|
||||
|
||||
return field.countDugOut()
|
||||
// field.countDugOut()
|
||||
return borderAmount + insideAmount
|
||||
}
|
||||
|
||||
// determine size of field. max(sum(up), sum(down)) for height,
|
||||
|
@ -50,10 +53,13 @@ func Run() int {
|
|||
// last part is filling in isides, should be ok with horizontal scans from left by even crossings
|
||||
|
||||
type Direction int
|
||||
const (Upward Direction = iota
|
||||
|
||||
const (
|
||||
Upward Direction = iota
|
||||
Downward
|
||||
Leftward
|
||||
Rightward)
|
||||
Rightward
|
||||
)
|
||||
|
||||
func (d Direction) opposite() Direction {
|
||||
switch d {
|
||||
|
@ -133,10 +139,14 @@ func ReadInstruction2(line string) Instruction {
|
|||
hexDirection := fields[2][len(fields[2])-2 : len(fields[2])-1]
|
||||
var direction Direction
|
||||
switch hexDirection {
|
||||
case "0": direction = Rightward
|
||||
case "1": direction = Downward
|
||||
case "2": direction = Leftward
|
||||
case "3": direction = Upward
|
||||
case "0":
|
||||
direction = Rightward
|
||||
case "1":
|
||||
direction = Downward
|
||||
case "2":
|
||||
direction = Leftward
|
||||
case "3":
|
||||
direction = Upward
|
||||
}
|
||||
|
||||
dist, err := strconv.ParseUint(hexDist, 16, 64)
|
||||
|
@ -176,6 +186,7 @@ func calcHeightWidth(instructions []Instruction) (height, width int) {
|
|||
type Coord struct {
|
||||
X, Y int
|
||||
}
|
||||
|
||||
func (c Coord) applyDirection(d Direction) Coord {
|
||||
switch d {
|
||||
case Upward:
|
||||
|
@ -194,7 +205,6 @@ func (c Coord)applyDirection(d Direction) Coord {
|
|||
type Cell struct {
|
||||
IsDug bool
|
||||
ToBeDug bool
|
||||
Walls map[Direction]string
|
||||
Coord Coord
|
||||
}
|
||||
type Field struct {
|
||||
|
@ -207,11 +217,9 @@ func CreateField(height, width int) Field {
|
|||
for i := 0; i < height; i++ {
|
||||
row := make([]*Cell, width)
|
||||
rows[i] = row
|
||||
for j := 0; j < width; j++ {
|
||||
row[j] = &Cell{
|
||||
Walls: make(map[Direction]string),
|
||||
}
|
||||
}
|
||||
// for j := 0; j < width; j++ {
|
||||
// row[j] = &Cell{}
|
||||
// }
|
||||
}
|
||||
return Field{
|
||||
Height: height, Width: width,
|
||||
|
@ -225,17 +233,23 @@ func (f *Field)coordToIndices(c Coord) (row, col int) {
|
|||
return
|
||||
}
|
||||
|
||||
func (f *Field)digByInstructions(instructions []Instruction) {
|
||||
func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int) {
|
||||
runnerCoord := Coord{X: 0, Y: 0}
|
||||
row, col := f.coordToIndices(runnerCoord)
|
||||
f.Cells[row][col].IsDug = true
|
||||
f.Cells[row][col] = &Cell{
|
||||
IsDug: true,
|
||||
}
|
||||
// borderAmount += 1
|
||||
|
||||
for _, instruction := range instructions {
|
||||
log.Printf("starting instruction %+v", instruction)
|
||||
for i := 0; i < instruction.Steps; i++ {
|
||||
runnerCoord = runnerCoord.applyDirection(instruction.Direction)
|
||||
row, col := f.coordToIndices(runnerCoord)
|
||||
f.Cells[row][col].IsDug = true
|
||||
f.Cells[row][col] = &Cell{
|
||||
IsDug: true,
|
||||
}
|
||||
borderAmount += 1
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -244,19 +258,18 @@ func (f *Field)digByInstructions(instructions []Instruction) {
|
|||
func (f *Field) String() string {
|
||||
s := "text 15,15 \""
|
||||
firstNonemptyRow, lastNonemptyRow := 0, 0
|
||||
log.Print("just use", firstNonemptyRow, lastNonemptyRow)
|
||||
seenInRows := false
|
||||
firstNonemptyCol, lastNonemptyCol := 0, 0
|
||||
seenInCols := false
|
||||
|
||||
for i, row := range f.Cells {
|
||||
seenInRow := false
|
||||
for _, cell := range row {
|
||||
if cell.IsDug {
|
||||
for j := 0; j < len(row); j++ {
|
||||
if f.isCellDug(i, j) {
|
||||
seenInRow = true
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
seenInRows = seenInRows || seenInRow
|
||||
if seenInRow {
|
||||
lastNonemptyRow = i
|
||||
|
@ -269,8 +282,7 @@ func (f *Field)String() string {
|
|||
for col := 0; col < f.Width; col++ {
|
||||
seenInCol := false
|
||||
for row := 0; row < f.Height; row++ {
|
||||
cell := f.Cells[row][col]
|
||||
if cell.IsDug {
|
||||
if f.isCellDug(row, col) {
|
||||
seenInCol = true
|
||||
}
|
||||
}
|
||||
|
@ -284,16 +296,17 @@ func (f *Field)String() string {
|
|||
}
|
||||
|
||||
rowLen := lastNonemptyCol - firstNonemptyCol + 1
|
||||
for i := firstNonemptyRow; i <= lastNonemptyRow; i++ {
|
||||
rowChars := make([]rune, rowLen)
|
||||
for col := firstNonemptyCol; col <= lastNonemptyCol; col++ {
|
||||
log.Print(rowLen)
|
||||
for i := 0; i <= f.Height-1; i++ {
|
||||
rowChars := make([]rune, f.Width)
|
||||
for col := 0; col <= f.Width-1; col++ {
|
||||
cell := f.Cells[i][col]
|
||||
if cell.IsDug {
|
||||
rowChars[col-firstNonemptyCol] = '#'
|
||||
} else if cell.ToBeDug {
|
||||
rowChars[col-firstNonemptyCol] = '@'
|
||||
if cell != nil && cell.ToBeDug {
|
||||
rowChars[col] = '@'
|
||||
} else if f.isCellDug(i, col) {
|
||||
rowChars[col] = '#'
|
||||
} else {
|
||||
rowChars[col-firstNonemptyCol] = '.'
|
||||
rowChars[col] = '.'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,18 +317,17 @@ func (f *Field)String() string {
|
|||
return s
|
||||
}
|
||||
|
||||
func (f *Field)digInsides() {
|
||||
for row := 0; row < f.Height; row++ {
|
||||
func (f *Field) digInsides() (countInside int) {
|
||||
for row := 1; row < f.Height-1; row++ {
|
||||
isInside := false
|
||||
seenUp, seenDown := false, false // for detecting L---7 walls
|
||||
for col := 0; col < f.Width-1; col++ {
|
||||
cellPtr := f.Cells[row][col]
|
||||
rightCell := f.Cells[row][col+1]
|
||||
if cellPtr.IsDug {
|
||||
upCell := f.Cells[row-1][col]
|
||||
downCell := f.Cells[row+1][col]
|
||||
if !rightCell.IsDug {
|
||||
if (upCell.IsDug && seenDown) || (downCell.IsDug && seenUp) {
|
||||
rightCellIsDug := f.isCellDug(row, col+1)
|
||||
if f.isCellDug(row, col) {
|
||||
upCellIsDug := f.isCellDug(row-1, col)
|
||||
downCellIsDug := f.isCellDug(row+1, col)
|
||||
if !rightCellIsDug {
|
||||
if (upCellIsDug && seenDown) || (downCellIsDug && seenUp) {
|
||||
isInside = !isInside
|
||||
}
|
||||
seenUp, seenDown = false, false
|
||||
|
@ -323,31 +335,41 @@ func (f *Field)digInsides() {
|
|||
} else {
|
||||
// not a dug out cell, maybe inside and needs to be dug out
|
||||
if isInside {
|
||||
cellPtr.ToBeDug = true
|
||||
}
|
||||
if rightCell.IsDug {
|
||||
nextUpCell := f.Cells[row-1][col+1]
|
||||
nextDownCell := f.Cells[row+1][col+1]
|
||||
seenUp = nextUpCell.IsDug
|
||||
seenDown = nextDownCell.IsDug
|
||||
f.Cells[row][col] = &Cell{
|
||||
ToBeDug: true,
|
||||
}
|
||||
|
||||
countInside += 1
|
||||
log.Printf("tick count inside for %d %d", row, col)
|
||||
// cellPtr.ToBeDug = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if rightCellIsDug {
|
||||
seenUp = f.isCellDug(row-1, col+1)
|
||||
seenDown = f.isCellDug(row+1, col+1)
|
||||
}
|
||||
|
||||
func (f *Field)countDugOut() (result int) {
|
||||
for _, row := range f.Cells {
|
||||
for _, cell := range row {
|
||||
if cell.IsDug || cell.ToBeDug {
|
||||
result += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *Field) isCellDug(row, col int) bool {
|
||||
cell := f.Cells[row][col]
|
||||
return cell != nil && cell.IsDug
|
||||
}
|
||||
|
||||
// func (f *Field)countDugOut() (result int) {
|
||||
// for _, row := range f.Cells {
|
||||
// for _, cell := range row {
|
||||
// if cell.IsDug || cell.ToBeDug {
|
||||
// result += 1
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
func WriteToFile(filename string, content string) {
|
||||
fileBorder, err := os.Create(filename)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue