package main

type Expression struct {
	variable string
	constant float64
}

func calcEquation(equations [][]string, values []float64, queries [][]string) []float64 {
	process := func() map[string]([]Expression) {
		g := make(map[string]([]Expression), 0)

		for i, eq := range equations {
			x, y := eq[0], eq[1]

			if g[x] == nil {
				g[x] = make([]Expression, 0)
			}
			g[x] = append(g[x], Expression{
				variable: y,
				constant: values[i],
			})

			if g[y] == nil {
				g[y] = make([]Expression, 0)
			}
			g[y] = append(g[y], Expression{
				variable: x,
				constant: 1 / values[i],
			})
		}

		return g
	}
	graph := process()

	var dfs func(map[string]bool, string, string, float64, *float64)
	dfs = func(visited map[string]bool, src, dest string, product float64, result *float64) {
		if visited[src] {
			return
		}
		visited[src] = true

		if src == dest {
			*result = product
			return
		}

		neighbors, hasNeighbors := graph[src]
		if !hasNeighbors {
			return
		}

		for _, nextSrc := range neighbors {
			dfs(visited, nextSrc.variable, dest, product*nextSrc.constant, result)
		}
	}

	getResult := func(src, dst string) float64 {
		result := -1.0

		visited := make(map[string]bool, 0)
		if graph[src] != nil {
			dfs(visited, src, dst, 1.0, &result)
		}

		return result
	}

	results := make([]float64, len(queries))
	for i, query := range queries {
		results[i] = getResult(query[0], query[1])
	}

	return results
}