day18, example second parallel
This commit is contained in:
parent
568fdd9a70
commit
6efd55ae6a
190
day18/lagoon.go
190
day18/lagoon.go
|
@ -7,12 +7,13 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run() int {
|
func Run() int {
|
||||||
log.Println("hello day 18")
|
log.Println("hello day 18")
|
||||||
log.Println("problem of lagoon bgins")
|
log.Println("problem of lagoon bgins")
|
||||||
filename := "day18/example"
|
filename := "day18/input"
|
||||||
instructions := ReadInstructionas2(filename)
|
instructions := ReadInstructionas2(filename)
|
||||||
h, w := calcHeightWidth(instructions)
|
h, w := calcHeightWidth(instructions)
|
||||||
log.Printf("read %+v instructions", instructions)
|
log.Printf("read %+v instructions", instructions)
|
||||||
|
@ -210,34 +211,37 @@ type Cell struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BorderSymbol rune
|
type BorderSymbol rune
|
||||||
// '' always left to right
|
|
||||||
const (Vertical BorderSymbol = '|'
|
// ” always left to right
|
||||||
ToDown BorderSymbol = '7'
|
const (
|
||||||
ToUp BorderSymbol = 'J'
|
Vertical BorderSymbol = '|'
|
||||||
FromUp BorderSymbol = 'F'
|
ToDown BorderSymbol = '7'
|
||||||
|
ToUp BorderSymbol = 'J'
|
||||||
|
FromUp BorderSymbol = 'F'
|
||||||
FromDown BorderSymbol = 'L'
|
FromDown BorderSymbol = 'L'
|
||||||
)
|
)
|
||||||
|
|
||||||
type Field struct {
|
type Field struct {
|
||||||
Height, Width int
|
Height, Width int
|
||||||
// Cells [][]*Cell
|
// Cells [][]*Cell
|
||||||
Cells map[Coord]*Cell
|
Cells map[Coord]*Cell
|
||||||
MinRow, MaxRow, MinCol, MaxCol int
|
MinRow, MaxRow, MinCol, MaxCol int
|
||||||
BordersFromLeft map[int]map[int]BorderSymbol
|
BordersFromLeft map[int]map[int]BorderSymbol
|
||||||
}
|
}
|
||||||
func (f *Field)confirmCoord(c Coord) {
|
|
||||||
|
func (f *Field) confirmCoord(c Coord) {
|
||||||
// log.Printf("configming coord %+v", c)
|
// log.Printf("configming coord %+v", c)
|
||||||
|
|
||||||
if c.Row - 3 < f.MinRow {
|
if c.Row-3 < f.MinRow {
|
||||||
f.MinRow = c.Row - 3
|
f.MinRow = c.Row - 3
|
||||||
}
|
}
|
||||||
if c.Row + 3 > f.MaxRow {
|
if c.Row+3 > f.MaxRow {
|
||||||
f.MaxRow = c.Row + 3
|
f.MaxRow = c.Row + 3
|
||||||
}
|
}
|
||||||
if c.Col - 3 < f.MinCol {
|
if c.Col-3 < f.MinCol {
|
||||||
f.MinCol = c.Col - 3
|
f.MinCol = c.Col - 3
|
||||||
}
|
}
|
||||||
if c.Col + 3 > f.MaxCol {
|
if c.Col+3 > f.MaxCol {
|
||||||
f.MaxCol = c.Col + 3
|
f.MaxCol = c.Col + 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +249,7 @@ func (f *Field)confirmCoord(c Coord) {
|
||||||
func CreateField(height, width int) Field {
|
func CreateField(height, width int) Field {
|
||||||
return Field{
|
return Field{
|
||||||
Height: height, Width: width,
|
Height: height, Width: width,
|
||||||
Cells: make(map[Coord]*Cell),
|
Cells: make(map[Coord]*Cell),
|
||||||
BordersFromLeft: make(map[int]map[int]BorderSymbol),
|
BordersFromLeft: make(map[int]map[int]BorderSymbol),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +299,7 @@ func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int)
|
||||||
// log.Printf("inside %+v updated border amount to %d", instruction, borderAmount)
|
// log.Printf("inside %+v updated border amount to %d", instruction, borderAmount)
|
||||||
|
|
||||||
if instruction.Direction == Upward || instruction.Direction == Downward {
|
if instruction.Direction == Upward || instruction.Direction == Downward {
|
||||||
_, alreadyCountedTurn := f.BordersFromLeft[runnerCoord.Row][runnerCoord.Col]
|
_, alreadyCountedTurn := f.BordersFromLeft[runnerCoord.Row][runnerCoord.Col]
|
||||||
if !alreadyCountedTurn {
|
if !alreadyCountedTurn {
|
||||||
PutSymbIntoMMMMap(f.BordersFromLeft, runnerCoord.Row, runnerCoord.Col, Vertical)
|
PutSymbIntoMMMMap(f.BordersFromLeft, runnerCoord.Row, runnerCoord.Col, Vertical)
|
||||||
}
|
}
|
||||||
|
@ -307,7 +311,7 @@ func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTurnAsIfGoingFromLeft(directionFrom, directionTo Direction) []BorderSymbol {
|
func getTurnAsIfGoingFromLeft(directionFrom, directionTo Direction) []BorderSymbol {
|
||||||
// log.Printf("getTurnAsIfGoingFromLeft from %s to %s", directionFrom.String(), directionTo.String())
|
// log.Printf("getTurnAsIfGoingFromLeft from %s to %s", directionFrom.String(), directionTo.String())
|
||||||
|
|
||||||
var symbol BorderSymbol
|
var symbol BorderSymbol
|
||||||
|
@ -337,7 +341,6 @@ func getTurnAsIfGoingFromLeft(directionFrom, directionTo Direction) []BorderSym
|
||||||
symbol = FromUp
|
symbol = FromUp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// panic(fmt.Sprint("got strange from %s to %s", directionFrom.String(), directionTo.String()))
|
// panic(fmt.Sprint("got strange from %s to %s", directionFrom.String(), directionTo.String()))
|
||||||
return []BorderSymbol{symbol}
|
return []BorderSymbol{symbol}
|
||||||
}
|
}
|
||||||
|
@ -346,27 +349,27 @@ func (f *Field) String() string {
|
||||||
s := "text 15,15 \""
|
s := "text 15,15 \""
|
||||||
|
|
||||||
for row := f.MinRow; row <= f.MaxRow; row++ {
|
for row := f.MinRow; row <= f.MaxRow; row++ {
|
||||||
rowChars := make([]rune, f.MaxCol - f.MinCol + 1)
|
rowChars := make([]rune, f.MaxCol-f.MinCol+1)
|
||||||
for col := f.MinCol; col <= f.MaxCol; col++ {
|
for col := f.MinCol; col <= f.MaxCol; col++ {
|
||||||
|
|
||||||
rowBords := f.BordersFromLeft[row]
|
rowBords := f.BordersFromLeft[row]
|
||||||
if rowBords != nil {
|
if rowBords != nil {
|
||||||
bord, exists := rowBords[col]
|
bord, exists := rowBords[col]
|
||||||
if exists {
|
if exists {
|
||||||
rowChars[col - f.MinCol] = rune(bord)
|
rowChars[col-f.MinCol] = rune(bord)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell := f.Cells[Coord{col, row}]
|
cell := f.Cells[Coord{col, row}]
|
||||||
if cell != nil && cell.ToBeDug {
|
if cell != nil && cell.ToBeDug {
|
||||||
rowChars[col - f.MinCol] = '@'
|
rowChars[col-f.MinCol] = '@'
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.isCellDug(row, col) {
|
if f.isCellDug(row, col) {
|
||||||
rowChars[col - f.MinCol] = '#'
|
rowChars[col-f.MinCol] = '#'
|
||||||
} else {
|
} else {
|
||||||
rowChars[col - f.MinCol] = '.'
|
rowChars[col-f.MinCol] = '.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,72 +379,101 @@ func (f *Field) String() string {
|
||||||
s += "\""
|
s += "\""
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (f *Field) digInsides() (countInside int) {
|
func (f *Field) digInsides() (result int) {
|
||||||
|
lineSum := make(chan int)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
rowsCount := f.MaxRow - f.MinRow
|
||||||
|
wg.Add(rowsCount)
|
||||||
|
|
||||||
|
done := make(chan bool)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
wg.Wait()
|
||||||
|
close(lineSum)
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for rowInternalCount := range lineSum {
|
||||||
|
result += rowInternalCount
|
||||||
|
}
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
for row := f.MinRow; row < f.MaxRow; row++ {
|
for row := f.MinRow; row < f.MaxRow; row++ {
|
||||||
if row % 10000 == 0 {
|
go func(row int){
|
||||||
log.Printf("processed rows %d out of %d", row, f.MaxRow)
|
if row%10000 == 0 {
|
||||||
}
|
log.Printf("processed rows %d out of %d", row, f.MaxRow)
|
||||||
specialBorders := f.BordersFromLeft[row]
|
}
|
||||||
if len(specialBorders) == 0 {
|
specialBorders := f.BordersFromLeft[row]
|
||||||
continue
|
if len(specialBorders) == 0 {
|
||||||
}
|
wg.Done()
|
||||||
type BorderItem struct {
|
return
|
||||||
border BorderSymbol
|
}
|
||||||
col int
|
type BorderItem struct {
|
||||||
}
|
border BorderSymbol
|
||||||
rowBorders := make([]BorderItem, 0)
|
col int
|
||||||
for col, borderSymbol := range specialBorders {
|
}
|
||||||
rowBorders = append(rowBorders, BorderItem{borderSymbol, col})
|
rowBorders := make([]BorderItem, 0)
|
||||||
}
|
for col, borderSymbol := range specialBorders {
|
||||||
slices.SortFunc(rowBorders, func(a BorderItem, b BorderItem) int {
|
rowBorders = append(rowBorders, BorderItem{borderSymbol, col})
|
||||||
return a.col - b.col
|
}
|
||||||
})
|
slices.SortFunc(rowBorders, func(a BorderItem, b BorderItem) int {
|
||||||
|
return a.col - b.col
|
||||||
|
})
|
||||||
|
|
||||||
// log.Printf(">>>>>>> for row %d sorted %+v", row, rowBorders)
|
// log.Printf(">>>>>>> for row %d sorted %+v", row, rowBorders)
|
||||||
prevBorder := rowBorders[0]
|
prevBorder := rowBorders[0]
|
||||||
bordersCrossed := 0
|
bordersCrossed := 0
|
||||||
if prevBorder.border == Vertical {
|
if prevBorder.border == Vertical {
|
||||||
bordersCrossed += 1
|
|
||||||
}
|
|
||||||
for _, specialBorder := range rowBorders[1:] {
|
|
||||||
diff := specialBorder.col - prevBorder.col - 1
|
|
||||||
|
|
||||||
if specialBorder.border == ToUp && prevBorder.border == FromUp {
|
|
||||||
bordersCrossed += 1
|
bordersCrossed += 1
|
||||||
prevBorder = specialBorder
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if specialBorder.border == ToDown && prevBorder.border == FromDown {
|
|
||||||
bordersCrossed += 1
|
|
||||||
prevBorder = specialBorder
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if specialBorder.border == ToUp && prevBorder.border == FromDown {
|
|
||||||
prevBorder = specialBorder
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if specialBorder.border == ToDown && prevBorder.border == FromUp {
|
|
||||||
prevBorder = specialBorder
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
|
for _, specialBorder := range rowBorders[1:] {
|
||||||
|
diff := specialBorder.col - prevBorder.col - 1
|
||||||
|
|
||||||
if bordersCrossed % 2 == 1 { // is in
|
if specialBorder.border == ToUp && prevBorder.border == FromUp {
|
||||||
for col := prevBorder.col+1; col < specialBorder.col; col++ {
|
bordersCrossed += 1
|
||||||
// f.Cells[Coord{Col: col, Row: row}] = &Cell{
|
prevBorder = specialBorder
|
||||||
// ToBeDug: true,
|
continue
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
countInside += diff
|
if specialBorder.border == ToDown && prevBorder.border == FromDown {
|
||||||
|
bordersCrossed += 1
|
||||||
|
prevBorder = specialBorder
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if specialBorder.border == ToUp && prevBorder.border == FromDown {
|
||||||
|
prevBorder = specialBorder
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if specialBorder.border == ToDown && prevBorder.border == FromUp {
|
||||||
|
prevBorder = specialBorder
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if bordersCrossed%2 == 1 { // is in
|
||||||
|
for col := prevBorder.col + 1; col < specialBorder.col; col++ {
|
||||||
|
// f.Cells[Coord{Col: col, Row: row}] = &Cell{
|
||||||
|
// ToBeDug: true,
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
lineSum <- diff
|
||||||
|
// countInside += diff
|
||||||
|
}
|
||||||
|
|
||||||
|
if specialBorder.border == Vertical {
|
||||||
|
bordersCrossed += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
prevBorder = specialBorder
|
||||||
}
|
}
|
||||||
|
|
||||||
if specialBorder.border == Vertical {
|
wg.Done()
|
||||||
bordersCrossed += 1
|
}(row)
|
||||||
}
|
|
||||||
|
|
||||||
prevBorder = specialBorder
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
<-done
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (f *Field) digInsides() (countInside int) {
|
// func (f *Field) digInsides() (countInside int) {
|
||||||
|
|
|
@ -34,3 +34,18 @@ day18 result: 952408144115
|
||||||
|
|
||||||
952408144115
|
952408144115
|
||||||
*** YES.
|
*** YES.
|
||||||
|
*** about 1M for 4 minutes
|
||||||
|
** so, my input is ~16M rows
|
||||||
|
3.5 seconds per 10k
|
||||||
|
** well, maybe i can parallel.
|
||||||
|
*** parallel example
|
||||||
|
day18 result: 952407566854
|
||||||
|
*** and with separate done channel from the summing goroutine
|
||||||
|
952408144115
|
||||||
|
**** YES
|
||||||
|
** and
|
||||||
|
2023/12/18 23:35:31 border is 195341588; inside is 148441957805559
|
||||||
|
2023/12/18 23:35:31
|
||||||
|
|
||||||
|
day18 result: 148442153147147
|
||||||
|
* i should have used a formula. maybe then it would taken less than 4 hours
|
||||||
|
|
Loading…
Reference in New Issue