chore(day17): add open list for A*
This commit is contained in:
parent
adc01f4df9
commit
eb1eaaab43
|
@ -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 }}."
|
||||||
|
|
|
@ -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)
|
||||||
// }
|
}
|
||||||
|
|
21
search.go
21
search.go
|
@ -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(¤t)
|
return cost, NewPath(¤t)
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user