using System.Collections.Generic;
public static void Main()
Console.WriteLine(FindSolution(new ProblemDefinition(input)).DumpCells());
private static ProblemDefinition FindSolution(ProblemDefinition prob)
Ranges ranges = prob.ToRanges();
for(int y = 0; y < 4; y++)
madeChange |= ranges.ImproveRow(y, prob.HorizSums[y]);
for(int x = 0; x < 4; x++)
madeChange |= ranges.ImproveColumn(x, prob.VerticalSums[x]);
madeChange |= ranges.ImproveDiagNorthEast(prob.DiagNorthEastSum);
madeChange |= ranges.ImproveDiagSouthEast(prob.DiagSouthEastSum);
public class ProblemDefinition
private int?[,] m_Cells = new int?[4,4];
public int[] VerticalSums = new int[4];
public int[] HorizSums = new int[4];
public int DiagNorthEastSum;
public int DiagSouthEastSum;
public ProblemDefinition(string input)
string[] lines = input.Split('\n').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();
DiagNorthEastSum = int.Parse(lines[0]);
for(int y = 0; y < 4; y++)
string line = lines[y+1];
string[] parts = line.Split('|');
HorizSums[y] = int.Parse(parts[1]);
string[] cells = parts[0].Split(',').Select(s => s.Trim()).ToArray();
for(int x = 0; x < 4; x++)
if(cells[x] == "_") continue;
m_Cells[x,y] = int.Parse(cells[x]);
string lastLine = lines[6];
VerticalSums = lastLine.Split(',').Select(s => int.Parse(s)).ToArray();
DiagSouthEastSum = VerticalSums.Last();
VerticalSums = VerticalSums.Take(4).ToArray();
public string DumpCells()
StringBuilder sb = new StringBuilder();
for(int y = 0; y < m_Cells.GetLength(1); y++)
for(int x = 0; x < m_Cells.GetLength(0); x++)
sb.Append(m_Cells[x,y]?.ToString() ?? "_");
sb.Remove(sb.Length - 1, 1);
sb.Remove(sb.Length - 1, 1);
Ranges ranges = new Ranges();
for(int y = 0; y < m_Cells.GetLength(1); y++)
for(int x = 0; x < m_Cells.GetLength(0); x++)
if(m_Cells[x,y].HasValue)
ranges.SetSingleValue(x,y,m_Cells[x,y].Value);
private int[,] m_Mins = new int[4,4];
private int[,] m_Maxes = new int[4,4];
for(int x = 0; x < m_Mins.GetLength(0); x++)
for(int y = 0; y < m_Mins.GetLength(1); y++)
public void SetSingleValue(int x, int y, int value)
m_Mins[x,y] = m_Mins[x,y] = value;
public void ImproveMin(int x, int y, int value)
m_Mins[x,y] = Math.Max(m_Mins[x,y], value);
public void ImproveMax(int x, int y, int value)
m_Maxes[x,y] = Math.Min(m_Maxes[x,y], value);
public bool ImproveRow(int y, int sum)