func TestListToNodeSlice(t *testing.T) { //t.SkipNow() nodeA := search.GraphNode(NewWordNode("aardvark", 0)) nodeB := search.GraphNode(NewWordNode("bonobo", 0)) nodeC := search.GraphNode(NewWordNode("chipmunk", 0)) cases := []struct { in *list.List want []search.GraphNode }{ {list.New(), []search.GraphNode{}}, {list.New(), []search.GraphNode{nodeA, nodeB, nodeC}}, //{list.New(), []search.GraphNode{nodeC, nodeB, nodeA},}, order matters } cases[1].in.PushBack(nodeA) cases[1].in.PushBack(nodeB) cases[1].in.PushBack(nodeC) // cases[2].in.PushBack(nodeA) // cases[2].in.PushBack(nodeB) // cases[2].in.PushBack(nodeC) for _, c := range cases { got := listToNodeSlice(c.in) if !reflect.DeepEqual(got, c.want) { t.Errorf("listToNodeSlice(%v), want=%v, got=%v", c.in, c.want, got) } } }
func BenchmarkSearch(b *testing.B) { // setup file, _ := os.Open("dict.txt") defer file.Close() graphRes, _, _ := grapher.ScanLinkCompress(file) benchGraph = graphRes // to prevent compiler skip srcNode, _ := graph[6]["bounce"] dstNode, _ := graph[6]["lather"] src := search.GraphNode(srcNode) dst := search.GraphNode(dstNode) b.ResetTimer() // run the Search b.N times for n := 0; n < b.N; n++ { _, _, found := search.Path(src, dst) benchFound = found // to prevent compiler skip } }
func searchCmd(src string, dst string) { if graph == nil { fmt.Println("No graph to search. Please scan a dictionary before searching.\n\n") return } if len(src) != len(dst) { fmt.Println("Source and destination words are of different lengths. This is outside the problem domain.\n\n") return } srcSubGraph, ok := graph[len(src)] if !ok { fmt.Println("Source word not found in dictionary.\n\n") return } srcNode, ok := srcSubGraph[src] if !ok { fmt.Println("Source word not found in dictionary.\n\n") return } dstSubGraph, ok := graph[len(dst)] if !ok { fmt.Println("Destination word not found in dictionary.\n\n") return } dstNode, ok := dstSubGraph[dst] if !ok { fmt.Println("Destination word not found in dictionary.\n\n") return } path, distance, found := search.Path(search.GraphNode(srcNode), search.GraphNode(dstNode)) if !found { fmt.Printf("No path was found between %s and %s.\n\n", src, dst) return } fmt.Printf("The shortest path between %s and %s is %d transformations long.\n", src, dst, distance) fmt.Printf("Full path:\n") for k, v := range path { fmt.Printf("%d: %s\n", k, v.(*grapher.WordNode).Word) } fmt.Printf("\n") }
func TestCompress(t *testing.T) { //t.SkipNow() cases := []struct { in WordGraph want WordGraph }{ //test empty input { WordGraph{}, WordGraph{}, }, //test sparse input { WordGraph{ 3: map[string]*WordNode{ "hit": NewWordNode("hit", initialEdgeCount), "hat": NewWordNode("hat", initialEdgeCount), "hot": NewWordNode("hot", initialEdgeCount), }, 4: map[string]*WordNode{ "hate": NewWordNode("hate", initialEdgeCount), "cart": NewWordNode("cart", initialEdgeCount), "part": NewWordNode("part", initialEdgeCount), }, }, WordGraph{ 3: map[string]*WordNode{ "hit": NewWordNode("hit", 0), "hat": NewWordNode("hat", 0), "hot": NewWordNode("hot", 0), }, 4: map[string]*WordNode{ "hate": NewWordNode("hate", 0), "cart": NewWordNode("cart", 0), "part": NewWordNode("part", 0), }, }, }, } // can't use a literal to assign a pointer conveniently, // so let's just manually add the associations. // here we add the initial edges, as if link() had been run cases[1].in[3]["hit"].Edges[1][0] = cases[1].in[3]["hat"] cases[1].in[3]["hit"].Edges[1][14] = cases[1].in[3]["hot"] cases[1].in[3]["hat"].Edges[1][8] = cases[1].in[3]["hit"] cases[1].in[3]["hat"].Edges[1][14] = cases[1].in[3]["hot"] cases[1].in[3]["hot"].Edges[1][0] = cases[1].in[3]["hat"] cases[1].in[3]["hot"].Edges[1][8] = cases[1].in[3]["hit"] cases[1].in[4]["part"].Edges[0][2] = cases[1].in[4]["cart"] cases[1].in[4]["cart"].Edges[0][15] = cases[1].in[4]["part"] // next we nil the sparse edges cases[1].want[3]["hit"].Edges = nil cases[1].want[3]["hat"].Edges = nil cases[1].want[3]["hot"].Edges = nil cases[1].want[4]["hate"].Edges = nil cases[1].want[4]["part"].Edges = nil cases[1].want[4]["cart"].Edges = nil // now we initialize the compressed slices to the expected size cases[1].want[3]["hit"].Neighbours = make([]search.GraphNode, 2) cases[1].want[3]["hat"].Neighbours = make([]search.GraphNode, 2) cases[1].want[3]["hot"].Neighbours = make([]search.GraphNode, 2) cases[1].want[4]["hate"].Neighbours = make([]search.GraphNode, 0) cases[1].want[4]["part"].Neighbours = make([]search.GraphNode, 1) cases[1].want[4]["cart"].Neighbours = make([]search.GraphNode, 1) // finally we link the nodes in the expected way cases[1].want[3]["hit"].Neighbours[0] = search.GraphNode(cases[1].want[3]["hat"]) cases[1].want[3]["hit"].Neighbours[1] = search.GraphNode(cases[1].want[3]["hot"]) cases[1].want[3]["hat"].Neighbours[0] = search.GraphNode(cases[1].want[3]["hit"]) cases[1].want[3]["hat"].Neighbours[1] = search.GraphNode(cases[1].want[3]["hot"]) cases[1].want[3]["hot"].Neighbours[0] = search.GraphNode(cases[1].want[3]["hat"]) cases[1].want[3]["hot"].Neighbours[1] = search.GraphNode(cases[1].want[3]["hit"]) cases[1].want[4]["part"].Neighbours[0] = search.GraphNode(cases[1].want[4]["cart"]) cases[1].want[4]["cart"].Neighbours[0] = search.GraphNode(cases[1].want[4]["part"]) for _, c := range cases { compress(c.in) if !reflect.DeepEqual(c.in, c.want) { t.Errorf("compress(), want=%v, got=%v", c.want, c.in) } //t.Logf("compress(), want=%v, got=%v", c.want, c.in) } }