import java.util.*;

public class WeightedNineTailModel extends NineTailModel {
  /** Tworzenie modelu */
  public WeightedNineTailModel() {
    // Tworzenie krawędzi
    List<WeightedEdge> edges = getEdges();
    
    // Tworzenie grafu
    WeightedGraph<Integer> graph = new WeightedGraph<>(
      edges, NUMBER_OF_NODES); 

    // Pobieranie drzewa najkrótszych ścieżek, którego korzeniem jest węzeł docelowy
    tree = graph.getShortestPath(511);
  }

  /** Tworzenie wszystkich krawędzi grafu */
  private List<WeightedEdge> getEdges() {
    // Przechowywanie krawędzi
    List<WeightedEdge> edges = new ArrayList<>(); 

    for (int u = 0; u < NUMBER_OF_NODES; u++) {
      for (int k = 0; k < 9; k++) {
        char[] node = getNode(u); // Pobieranie węzła reprezentującego wierzchołek u
        if (node[k] == 'H') {
          int v = getFlippedNode(node, k);
          int numberOfFlips = getNumberOfFlips(u, v);
          
          // Dodawanie krawędzi (v, u) oznaczającej przejście z węzła u do węzła v
          edges.add(new WeightedEdge(v, u, numberOfFlips));
        }
      }
    }

    return edges;
  }
  
  private static int getNumberOfFlips(int u, int v) {
    char[] node1 = getNode(u);
    char[] node2 = getNode(v);

    int count = 0; // Zliczanie odwracanych komórek
    for (int i = 0; i < node1.length; i++)
      if (node1[i] != node2[i]) count++;

    return count;
  }

  public int getNumberOfFlips(int u) {
    return (int)((WeightedGraph<Integer>.ShortestPathTree)tree)
      .getCost(u);
  }
}
