Example #1
0
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)
		}
	}
}
Example #2
0
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
	}
}
Example #3
0
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")
}
Example #4
0
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)
	}
}