chore(day17): add open list for A*
Some checks failed
Go Bump / bump (push) Successful in 8s
Go Test / build (push) Failing after 4m29s

This commit is contained in:
xuu 2024-01-01 14:12:53 -07:00
parent adc01f4df9
commit eb1eaaab43
Signed by: xuu
GPG Key ID: 8B3B0604F164E04F
3 changed files with 26 additions and 19 deletions

View File

@ -28,6 +28,6 @@ jobs:
go-version: 1.21.3 go-version: 1.21.3
- name: Test - name: Test
run: go test --race -cover ./... run: go test -timeout 240s -race -cover ./...
- run: echo "🍏 This job's status is ${{ job.status }}." - run: echo "🍏 This job's status is ${{ job.status }}."

View File

@ -13,8 +13,8 @@ import (
//go:embed example.txt //go:embed example.txt
var example []byte var example []byte
// //go:embed input.txt //go:embed input.txt
// var input []byte var input []byte
func TestExample(t *testing.T) { func TestExample(t *testing.T) {
is := is.New(t) is := is.New(t)
@ -28,14 +28,14 @@ func TestExample(t *testing.T) {
is.Equal(result.valuePT2, 94) is.Equal(result.valuePT2, 94)
} }
// func TestSolution(t *testing.T) { func TestSolution(t *testing.T) {
// is := is.New(t) is := is.New(t)
// scan := bufio.NewScanner(bytes.NewReader(input)) scan := bufio.NewScanner(bytes.NewReader(input))
// result, err := run(scan) result, err := run(scan)
// is.NoErr(err) is.NoErr(err)
// t.Log(result) t.Log(result)
// is.Equal(result.valuePT1, 843) is.Equal(result.valuePT1, 843)
// is.Equal(result.valuePT2, 1017) is.Equal(result.valuePT2, 1017)
// } }

View File

@ -61,13 +61,15 @@ type pather[C number, N comparable] interface {
// FindPath uses the A* path finding algorithem. // FindPath uses the A* path finding algorithem.
// g is the graph source that implements the pather interface. // g is the graph source that implements the pather interface.
// C is an numeric type for calculating cost/potential //
// N is the node values. is comparable for storing in visited table for pruning. // C is an numeric type for calculating cost/potential
// N is the node values. is comparable for storing in visited table for pruning.
//
// start, end are nodes that dileniate the start and end of the search path. // start, end are nodes that dileniate the start and end of the search path.
// The returned values are the calculated cost and the path taken from start to end. // The returned values are the calculated cost and the path taken from start to end.
func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N) { func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N) {
var zero C var zero C
visited := make(map[N]bool) closed := make(map[N]bool)
type node struct { type node struct {
cost C cost C
@ -94,6 +96,7 @@ func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N) {
pq := PriorityQueue(less) pq := PriorityQueue(less)
pq.Enqueue(node{position: start}) pq.Enqueue(node{position: start})
closed[start] = false
defer func() { defer func() {
Log("queue max depth = ", pq.maxDepth, "total enqueue = ", pq.totalEnqueue, "total dequeue = ", pq.totalDequeue) Log("queue max depth = ", pq.maxDepth, "total enqueue = ", pq.totalEnqueue, "total dequeue = ", pq.totalDequeue)
@ -114,10 +117,10 @@ func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N) {
cost, potential, n := current.cost, current.potential, current.position cost, potential, n := current.cost, current.potential, current.position
seen := seenFn(n) seen := seenFn(n)
if visited[seen] { if closed[seen] {
continue continue
} }
visited[seen] = true closed[seen] = true
if cost > 0 && potential == zero && targetFn(current.position) { if cost > 0 && potential == zero && targetFn(current.position) {
return cost, NewPath(&current) return cost, NewPath(&current)
@ -125,7 +128,7 @@ func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N) {
for _, nb := range g.Neighbors(n) { for _, nb := range g.Neighbors(n) {
seen := seenFn(nb) seen := seenFn(nb)
if visited[seen] { if closed[seen] {
continue continue
} }
@ -136,7 +139,11 @@ func FindPath[C integer, N comparable](g pather[C, N], start, end N) (C, []N) {
cost: cost, cost: cost,
potential: g.Potential(nb, end), potential: g.Potential(nb, end),
} }
pq.Enqueue(nextPath) // check if path is in open list
if _, open := closed[seen]; !open {
pq.Enqueue(nextPath)
closed[seen] = false // add to open list
}
} }
} }
return zero, nil return zero, nil