day21, part2, did not like
This commit is contained in:
parent
b10a6250b1
commit
99c2269df8
|
@ -78,7 +78,7 @@ EOEOEOEOEOE
|
|||
*** yes, sounds good
|
||||
|
||||
|
||||
** TODO after getting all new points. get coords of all fields we're working on.
|
||||
** CANCELLED after getting all new points. get coords of all fields we're working on.
|
||||
( there already should be no points in saturated fields )
|
||||
for each such field, check if it is saturated.
|
||||
|
||||
|
@ -86,5 +86,20 @@ for each such field, check if it is saturated.
|
|||
|
||||
if field saturated - add the coord into set
|
||||
and remove all the points
|
||||
** TODO on the last step, when n is 0
|
||||
** CANCELLED on the last step, when n is 0
|
||||
return len(startingAt) + (all saturated fields) * (amount of elems in their phase)
|
||||
** calculating points in even 7356 and odd 7321 phases
|
||||
* so need to scrap things and do a more analytics approach.
|
||||
no blocks on horizontal & vertical from (S)
|
||||
meaning diamond expands to left & right well
|
||||
* 26501365 = 202300 * 131 + 65 where 131 is the dimension of the grid
|
||||
* if there is a formula A*i^2 + B*i + C = D
|
||||
where i is full iteration
|
||||
* for initial steps :
|
||||
2023/12/21 13:25:23 after steps 65. full iter 0. got count 3701
|
||||
2023/12/21 13:25:24 after steps 196. full iter 1. got count 33108
|
||||
2023/12/21 13:25:27 after steps 327. full iter 2. got count 91853
|
||||
2023/12/21 13:25:42 after steps 458. full iter 3. got count 179936
|
||||
|
||||
* https://www.dcode.fr/newton-interpolating-polynomial
|
||||
14669x^2 + 14738*x+3701
|
||||
|
|
|
@ -7,15 +7,12 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func Run() (result int) {
|
||||
func Run() int {
|
||||
fmt.Print("hello day21")
|
||||
filename := "day21/input"
|
||||
field := ReadField(filename)
|
||||
log.Print(field)
|
||||
|
||||
initialSaturatedFields := make(map[Coord]any)
|
||||
log.Print(initialSaturatedFields)
|
||||
|
||||
// for i := 6; i <= 10; i++ {
|
||||
// reachableBySteps := field.ReachableBySteps(i, map[Coord]any{
|
||||
// Coord{Row: field.RowStart, Col: field.ColStart}: struct{}{},
|
||||
|
@ -25,17 +22,28 @@ func Run() (result int) {
|
|||
// field.PrintCoord(reachableBySteps, 1)
|
||||
// }
|
||||
|
||||
steps := 26501365
|
||||
reachableBySteps := field.ReachableBySteps(
|
||||
steps,
|
||||
map[FieldPoint]any{
|
||||
FieldPoint{
|
||||
InField: Coord{Row: field.RowStart, Col: field.ColStart},
|
||||
}: struct{}{}},
|
||||
make(map[Coord]int),
|
||||
steps)
|
||||
result = reachableBySteps
|
||||
log.Print("reachable after steps : ", steps, result)
|
||||
// initialSolutions := make(map[int]int)
|
||||
|
||||
// for fullIter := 0; fullIter < 4; fullIter++ {
|
||||
// steps := 65 + fullIter * 131
|
||||
// reachableBySteps := field.ReachableBySteps(steps, map[FieldPoint]any{
|
||||
// FieldPoint{
|
||||
// InField: Coord{Row: field.RowStart, Col: field.ColStart},
|
||||
// }: struct{}{},
|
||||
// })
|
||||
// log.Printf("after steps %d. full iter %d. got count %d", steps, fullIter, len(reachableBySteps))
|
||||
// initialSolutions[fullIter] = len(reachableBySteps)
|
||||
// }
|
||||
|
||||
log.Println("will try to use the values to get coeff of Ax^2 + Bx + C = 0")
|
||||
log.Println("then solve for x == 202300")
|
||||
// f(x) = 14714x^2 + 14603x + 3791
|
||||
// no.
|
||||
// 14669x^2 + 14738*x+3701
|
||||
|
||||
x := 202300
|
||||
result := 14669*x*x + 14738*x+3701
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
@ -46,9 +54,8 @@ func Run() (result int) {
|
|||
// OR. just breath first traversal
|
||||
|
||||
type Field struct {
|
||||
RowStart, ColStart int
|
||||
symbols [][]rune
|
||||
SaturatedEvenCount, SaturatedOddCount int
|
||||
RowStart, ColStart int
|
||||
symbols [][]rune
|
||||
}
|
||||
|
||||
type Coord struct {
|
||||
|
@ -60,87 +67,31 @@ type FieldPoint struct {
|
|||
MetaField Coord
|
||||
}
|
||||
|
||||
func (f Field) ReachableBySteps(n int, startingAt map[FieldPoint]any, saturatedFields map[Coord]int, initialSteps int) (countReachable int) {
|
||||
func (f Field) ReachableBySteps(n int, startingAt map[FieldPoint]any) map[FieldPoint]any {
|
||||
if n%100 == 0 {
|
||||
log.Println("going step: ", n)
|
||||
}
|
||||
if n == 0 {
|
||||
sizeOfUnsaturated := len(startingAt)
|
||||
sizeOfSaturated := 0
|
||||
// log.Printf("> before adding saturated fields. central is in even %t\n", CentralFieldIsInEven(initialSteps, n))
|
||||
for saturatedField := range saturatedFields {
|
||||
isEven := FieldIsInEven(initialSteps, n, saturatedField)
|
||||
// log.Printf("> adding saturated field %+v. it is in even %t\n", saturatedField, isEven)
|
||||
if isEven {
|
||||
sizeOfSaturated += f.SaturatedEvenCount
|
||||
} else {
|
||||
sizeOfSaturated += f.SaturatedOddCount
|
||||
}
|
||||
}
|
||||
|
||||
return sizeOfUnsaturated + sizeOfSaturated
|
||||
if n == 0 {
|
||||
return startingAt
|
||||
}
|
||||
// else collect directly available
|
||||
|
||||
oneStepExpanded := make(map[FieldPoint]any)
|
||||
for cur := range startingAt {
|
||||
for _, neighbor := range f.Neighbors(cur, saturatedFields) {
|
||||
for _, neighbor := range f.Neighbors(cur) {
|
||||
oneStepExpanded[neighbor] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
metaFields := make(map[Coord]int)
|
||||
for next := range oneStepExpanded {
|
||||
metaFields[next.MetaField] += 1
|
||||
}
|
||||
|
||||
for workedUponFieldCoord, amount := range metaFields {
|
||||
isEven := FieldIsInEven(initialSteps, n, workedUponFieldCoord)
|
||||
if workedUponFieldCoord.Col == 0 && workedUponFieldCoord.Row == 0 {
|
||||
// log.Printf("checking %+v : %d as worked fields for saturation. isEven %t", workedUponFieldCoord, amount, isEven)
|
||||
}
|
||||
if isEven && amount == f.SaturatedEvenCount {
|
||||
log.Printf(">>> adding %+v to saturated, with amount %d\n", workedUponFieldCoord, amount)
|
||||
saturatedFields[workedUponFieldCoord] = n
|
||||
}
|
||||
if !isEven && amount == f.SaturatedOddCount {
|
||||
log.Printf(">>> adding %+v to saturated, with amount %d\n", workedUponFieldCoord, amount)
|
||||
saturatedFields[workedUponFieldCoord] = n
|
||||
}
|
||||
}
|
||||
|
||||
for point := range oneStepExpanded {
|
||||
saturatedAtStep, fromSaturated := saturatedFields[point.MetaField]
|
||||
// hack. to not remove points from saturated fields too early
|
||||
if fromSaturated && (saturatedAtStep - n > 200) {
|
||||
delete(oneStepExpanded, point)
|
||||
}
|
||||
}
|
||||
|
||||
// if n < 4 {
|
||||
// log.Print("reachable after steps : ", n, len(oneStepExpanded))
|
||||
// f.PrintCoord(oneStepExpanded, 5)
|
||||
// }
|
||||
|
||||
return f.ReachableBySteps(n-1, oneStepExpanded, saturatedFields, initialSteps)
|
||||
return f.ReachableBySteps(n-1, oneStepExpanded)
|
||||
}
|
||||
|
||||
func CentralFieldIsInEven(initialSteps, currentSteps int) bool {
|
||||
// off by one here because on initial step we first do 'neighbors' then comparicons
|
||||
return (initialSteps-currentSteps)%2 != 0
|
||||
}
|
||||
|
||||
func FieldIsInEven(initialSteps, currentSteps int, metaCoord Coord) bool {
|
||||
centralIsInEven := CentralFieldIsInEven(initialSteps, currentSteps)
|
||||
fieldIsInSyncWithCentral := (metaCoord.Col+metaCoord.Row)%2 == 0
|
||||
if fieldIsInSyncWithCentral {
|
||||
return centralIsInEven
|
||||
} else {
|
||||
return !centralIsInEven
|
||||
}
|
||||
}
|
||||
|
||||
func (f Field) Neighbors(c FieldPoint, saturatedFields map[Coord]int) (resut []FieldPoint) {
|
||||
func (f Field) Neighbors(c FieldPoint) (resut []FieldPoint) {
|
||||
closeCoords := []FieldPoint{
|
||||
{InField: Coord{Row: c.InField.Row + 1, Col: c.InField.Col}, MetaField: c.MetaField},
|
||||
{InField: Coord{Row: c.InField.Row - 1, Col: c.InField.Col}, MetaField: c.MetaField},
|
||||
|
@ -176,10 +127,11 @@ func (f Field) Neighbors(c FieldPoint, saturatedFields map[Coord]int) (resut []F
|
|||
for _, close := range closeCoords {
|
||||
if f.ValidCoord(close.InField.Row, close.InField.Col) {
|
||||
symb := f.symbols[close.InField.Row][close.InField.Col]
|
||||
_, fieldIsAlreadySaturated := saturatedFields[close.MetaField]
|
||||
if (symb == '.' || symb == 'S') && !fieldIsAlreadySaturated {
|
||||
if symb == '.' || symb == 'S' {
|
||||
resut = append(resut, close)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,9 +179,6 @@ func ReadField(filename string) (result Field) {
|
|||
}
|
||||
}
|
||||
result.symbols = rows
|
||||
odd, even := result.PointsInEachPhase()
|
||||
result.SaturatedEvenCount = even
|
||||
result.SaturatedOddCount = odd
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -260,30 +209,3 @@ func (f Field) PrintCoord(coords map[FieldPoint]any, expandByField int) {
|
|||
|
||||
return
|
||||
}
|
||||
|
||||
// if the field is fully saturated, what is amount of 'visited' points?
|
||||
// odd - meaning one step around 'S', even - meaning with standing on 'S'
|
||||
func (f Field) PointsInEachPhase() (pointsIfOddPhase, pointsIfEvenPhase int) {
|
||||
remainderOfEvenPhase := (f.RowStart + f.ColStart) % 2
|
||||
text := "\n"
|
||||
for i, row := range f.symbols {
|
||||
for j, cell := range row {
|
||||
if cell != '#' {
|
||||
if (i+j)%2 == remainderOfEvenPhase {
|
||||
pointsIfEvenPhase += 1
|
||||
text += "E"
|
||||
} else {
|
||||
pointsIfOddPhase += 1
|
||||
text += "O"
|
||||
}
|
||||
} else {
|
||||
text += "#"
|
||||
}
|
||||
}
|
||||
text += "\n"
|
||||
}
|
||||
fmt.Println(text)
|
||||
log.Printf("calculating points in even and odd phases", pointsIfEvenPhase, pointsIfOddPhase)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue