Skip to content

Instantly share code, notes, and snippets.

@ygra
Created May 7, 2018 21:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ygra/4d054235179ead26bea49ac65f1b8675 to your computer and use it in GitHub Desktop.
Save ygra/4d054235179ead26bea49ac65f1b8675 to your computer and use it in GitHub Desktop.
7 6
8 8 8 2 8 8
2 5 4 2 9 7
6 2 7 3 5 4
4 6 6 1 7 1
8 2 7 3 3 6
7 3 2 3 7 3
3 2 2 8 1 7
30 21 32 15 36 21
32 18 20 24 24 22 15
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Rullo
{
class Grid
{
private int[,] _data;
private bool[,] _mask;
private int[] _rowSums;
private int[] _colSums;
private int[] currentRowSums;
private int[] currentColSums;
private (int, int) _size;
private int _columns;
public Grid(int rows, int columns)
{
Size = (rows, columns);
currentRowSums = new int[rows];
currentColSums = new int[columns];
}
public (int rows, int columns) Size
{
get => _size;
set
{
_size = value;
_data = new int[value.rows, value.columns];
_mask = new bool[value.rows, value.columns];
_rowSums = new int[value.rows];
_colSums = new int[value.columns];
}
}
public int this[int row, int column]
{
get => _data[row, column];
set => _data[row, column] = value;
}
public void SetMask((int row, int column) tuple, bool value)
{
var oldValue = _mask[tuple.row, tuple.column];
_mask[tuple.row, tuple.column] = value;
var gridCell = this[tuple.row, tuple.column];
if (!oldValue && value)
{
currentColSums[tuple.column] += gridCell;
currentRowSums[tuple.row] += gridCell;
}
if (oldValue && !value)
{
currentColSums[tuple.column] -= gridCell;
currentRowSums[tuple.row] -= gridCell;
}
}
public int[] CurrentRowSums { get => currentRowSums; }
public int[] CurrentColumnSums { get => currentColSums; }
public void Display()
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write(" ");
for (int i = 0; i < Size.columns; i++)
{
Console.Write(" {0,2}/{1,2}", CurrentColumnSums[i], _colSums[i]);
}
Console.WriteLine();
for (int row = 0; row < Size.rows; row++)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("{0,2}/{1,2} ", CurrentRowSums[row], _rowSums[row]);
for (int col = 0; col < Size.columns; col++)
{
Console.ForegroundColor = _mask[row, col] ? ConsoleColor.White : ConsoleColor.DarkGray;
Console.Write(_mask[row, col] ? " {0,-3}" : " ({0})", this[row, col]);
}
Console.WriteLine();
}
}
public bool IsSolved
{
get
{
for (int i = 0; i < Size.rows; i++)
{
if (CurrentRowSums[i] != _rowSums[i])
{
return false;
}
}
for (int i = 0; i < Size.columns; i++)
{
if (CurrentColumnSums[i] != _colSums[i])
{
return false;
}
}
return true;
}
}
private IEnumerable<(int row, int column)> GetPositions((int row, int column) tuple)
{
for (int r = tuple.row; r < Size.rows; r++)
{
for (int c = r == tuple.row ? tuple.column : 0; c < Size.columns; c++)
{
yield return (r, c);
}
}
}
public bool IsInvalid
{
get
{
for (int i = 0; i < Size.rows; i++)
{
if (CurrentRowSums[i] < _rowSums[i])
{
return true;
}
}
for (int i = 0; i < Size.columns; i++)
{
if (CurrentColumnSums[i] < _colSums[i])
{
return true;
}
}
return false;
}
}
public void Solve()
{
foreach (var tuple in GetPositions((0, 0)))
{
SetMask(tuple, true);
}
foreach (var tuple in GetPositions((0, 0)))
{
if (Solve(tuple))
{
break;
}
}
}
private bool Solve((int row, int column) tuple)
{
SetMask(tuple, false);
if (IsInvalid)
{
SetMask(tuple, true);
return false;
}
if (IsSolved)
{
return true;
}
foreach (var next in GetPositions(tuple).Skip(1))
{
var result = Solve(next);
if (result)
{
return result;
}
}
SetMask(tuple, true);
return false;
}
public static Grid Load(string file)
{
var input = File.ReadAllLines(file);
var sizes = input[0].Split().Select(int.Parse).ToArray();
var rows = sizes[0];
var columns = sizes.Length > 1 ? sizes[1] : sizes[0];
var grid = new Grid(rows, columns);
string[] line;
for (var row = 0; row < rows; row++)
{
line = input[row + 1].Split();
for (var col = 0; col < columns; col++)
{
int v = int.Parse(line[col]);
grid[row, col] = v;
}
}
foreach (var tuple in grid.GetPositions((0, 0)))
{
grid.SetMask(tuple, true);
}
line = input[rows + 1].Split();
for (var x = 0; x < columns; x++)
{
grid._colSums[x] = int.Parse(line[x]);
}
line = input[rows + 2].Split();
for (var x = 0; x < rows; x++)
{
grid._rowSums[x] = int.Parse(line[x]);
}
return grid;
}
}
class Program
{
static void Main(string[] args)
{
if (args.Length < 1)
{
return;
}
var grid = Grid.Load(args[0]);
grid.Solve();
grid.Display();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment