package sudoku;

import java.util.stream.Collectors;
import java.util.stream.Stream;
import common.graph.BasicGraph;
import common.graph.Graph;

/**
 * <p>A bipartite graph of Rules and Claims.</p>
 * @author fiveham
 *
 */
public class SudokuNetwork extends BasicGraph<NodeSet<?,?>> implements Sudoku{
	
	/**
	 * <p>The fundamental order of the target to which the nodes of this graph pertain, 
	 * equal to the square root of the {@link #sideLength side length}.</p>
	 */
	protected final int magnitude;
	
	/**
	 * <p>The number of coordinates along a dimension of the target to which the nodes 
	 * of this graph belong.</p>
	 */
	protected final int sideLength;
	
	public SudokuNetwork(int magnitude) {
		this.magnitude = magnitude;
		this.sideLength = magnitude*magnitude;
	}
	
	public SudokuNetwork(int magnitude, Graph<NodeSet<?,?>> connectedComponent){
		this(magnitude);
		this.nodes.addAll(connectedComponent.nodeStream().collect(Collectors.toList()));
	}
	
	/**
	 * <p>Returns true if this SudokuNetwork is solved, false otherwise. A 
	 * SudokuNetwork is solved iff all of its {@code Fact}s each have only 
	 * one {@code Claim}.</p>
	 * @return true if this SudokuNetwork is solved, false otherwise
	 */
	@Override
	public boolean isSolved(){
		return factStream().allMatch(Fact::isSolved);
	}
	
	@Override
	public Stream<Fact> factStream(){
		return nodes.stream().filter(Fact.class::isInstance).map(Fact.class::cast);
	}
	
	/**
	 * <p>Returns a Stream of all the {@code Claim}-type nodes in this 
	 * Puzzle's underlying graph.</p>
	 * @return a Stream of all the {@code Claim}-type nodes in this 
	 * Puzzle's underlying graph.
	 */
	@Override
	public Stream<Claim> claimStream(){
		return nodes.stream().filter(Claim.class::isInstance).map(Claim.class::cast);
	}
	
	@Override
	public int magnitude(){
		return magnitude;
	}
	
	@Override
	public int sideLength(){
		return sideLength;
	}
	
	@Override
	public String toString(){ //TODO implement SudokuNetwork.toString()
		return super.toString();
	}
}

@@ -10,16 +10,133 @@
 udoku;%0A%0A
+import common.graph.BasicGraph;%0Aimport common.graph.Graph;%0Aimport java.util.Map;%0Aimport java.util.function.Function;%0A
 import j
@@ -206,58 +206,27 @@
 ort 
-common.graph.BasicGraph;%0Aimport common.graph.Graph
+sudoku.parse.Parser
 ;%0A%0A/
@@ -2026,39 +2026,518 @@
 g()%7B
- //TODO implement SudokuNetwork
+%0A%09%09Map%3CInteger,Fact%3E cells = factStream()%0A%09%09%09%09.filter(Rule.class::isInstance)%0A%09%09%09%09.map(Rule.class::cast)%0A%09%09%09%09.filter(Puzzle.RuleType.CELL::isTypeOf)%0A%09%09%09%09.collect(Collectors.toMap(%0A%09%09%09%09%09%09(cell) -%3E NodeSet.linearizeCoords(0, cell.dimA().intValue(), cell.dimB().intValue(), sideLength()), %0A%09%09%09%09%09%09Function.identity()));%0A%09%09%0A%09%09StringBuilder result = new StringBuilder();%0A%09%09String empty;%0A%09%09%7B%0A%09%09%09StringBuilder empt = new StringBuilder();%0A%09%09%09for(int i=0; i%3CsideLength(); ++i)%7B%0A%09%09%09%09empt.append(%22 %22);%0A%09%09%09%7D%0A%09%09%09empty = empt
 .toS
@@ -2547,23 +2547,564 @@
 ng()
+;
 %0A%09%09
-return super
+%7D%0A%09%09%0A%09%09for(int y = 0; y %3C sideLength(); ++y)%7B%0A%09%09%09for(int x = 0; x %3C sideLength(); ++x)%7B%0A%09%09%09%09result.append(%22%7C%22);%0A%09%09%09%09Fact cell = cells.get(NodeSet.linearizeCoords(0, y, x, sideLength()));%0A%09%09%09%09if(cell == null)%7B%0A%09%09%09%09%09result.append(empty);%0A%09%09%09%09%7D else%7B%0A%09%09%09%09%09for(int z=0; z%3CsideLength(); ++z)%7B%0A%09%09%09%09%09%09int val = cell.contains(cell.getPuzzle().claim(x, y, z)) ? z : 0;%0A%09%09%09%09%09%09String text = val == 0 ? %22 %22 : Integer.toString(val,Parser.MAX_RADIX);%0A%09%09%09%09%09%09result.append(text);%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%09result.append(%22%7C%22 + System.lineSeparator());%0A%09%09%7D%0A%09%09%0A%09%09return result
 .toS

implement SudokuNetwork.toString()