using System.Collections.Generic;
public class WastedSandCounter
public int Count(int[,] sandPile)
int rows = sandPile.GetLength(0);
int columns = sandPile.GetLength(1);
for(int i = 0; i < rows; i++)
for(int j = 0; j < columns; j++)
sandPile = CollapseOnNeighbouringPositions(sandPile, i, j);
for(int i = 0; i < rows; i++)
for(int j = 0; j < columns; j++)
Console.Write(sandPile[i, j]);
throw new NotImplementedException();
public int[,] CollapseOnNeighbouringPositions(int[,] sandPile, int i, int j)
int rows = sandPile.GetLength(0);
int columns = sandPile.GetLength(1);
sandPile = CollapseInTheCornerPositions(sandPile, i, j, i, j+1, i+1, j);
else if(i == 0 && j == columns-1){
sandPile = CollapseInTheCornerPositions(sandPile, i, j, i, j-1, i+1, j);
else if(i == rows-1 && j == 0)
sandPile = CollapseInTheCornerPositions(sandPile, i, j, i-1, j, i, j+1);
else if(i == rows-1 && j == columns-1){
sandPile = CollapseInTheCornerPositions(sandPile, i, j, i-1, j, i, j-1);
else if(i>0 && i<rows-1 && j == 0){
sandPile = CollapseInTheIntermediatePositions(sandPile,i, j, i-1, j, i, j+1, i+1, j);
else if(i>0 && i<rows-1 && j == columns-1){
sandPile = CollapseInTheIntermediatePositions(sandPile, i, j, i-1, j, i, j-1, i+1, j);
else if(j > 0 && j < columns-1 && i == 0){
sandPile = CollapseInTheIntermediatePositions(sandPile, i, j, i, j-1, i+1, j, i, j+1);
else if(j > 0 && j < columns-1 && i == rows - 1){
sandPile = CollapseInTheIntermediatePositions(sandPile, i, j, i, j-1, i-1, j, i, j+1);
else if(i > 0 && i < rows-1 && j > 0 && j < columns-1){
sandPile = CollapseInTheMiddlePositions(sandPile, i, j, i-1, j, i, j+1, i+1, j, i, j-1);
public int[,] CollapseInTheCornerPositions(int[,] sandPile, int i, int j, int neighb_i1, int neighb_j1, int neighb_i2, int neighb_j2)
sandPile[neighb_i1, neighb_j1] += 1;
sandPile[neighb_i2, neighb_j2] += 1;
sandPile[i, j] = sandPile[i, j] - 4;
sandPile = CollapseOnNeighbouringPositions(sandPile, i, j);
if(sandPile[neighb_i1, neighb_j1] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i1, neighb_j1);
if(sandPile[neighb_i2, neighb_j2] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i2, neighb_j2);
public int[,] CollapseInTheIntermediatePositions(int[,] sandPile, int i, int j, int neighb_i1, int neighb_j1, int neighb_i2, int neighb_j2, int neighb_i3, int neighb_j3)
sandPile[neighb_i1, neighb_j1] += 1;
sandPile[neighb_i2, neighb_j2] += 1;
sandPile[neighb_i3, neighb_j3] += 1;
sandPile[i, j] = sandPile[i, j] - 4;
sandPile = CollapseOnNeighbouringPositions(sandPile, i, j);
if(sandPile[neighb_i1, neighb_j1] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i1, neighb_j1);
if(sandPile[neighb_i2, neighb_j2] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i2, neighb_j2);
if(sandPile[neighb_i3, neighb_j3] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i3, neighb_j3);
public int[,] CollapseInTheMiddlePositions(int[,] sandPile, int i, int j, int neighb_i1, int neighb_j1, int neighb_i2, int neighb_j2, int neighb_i3, int neighb_j3, int neighb_i4, int neighb_j4)
sandPile[neighb_i1, neighb_j1] += 1;
sandPile[neighb_i2, neighb_j2] += 1;
sandPile[neighb_i3, neighb_j3] += 1;
sandPile[neighb_i4, neighb_j4] += 1;
sandPile[i, j] = sandPile[i, j] - 4;
sandPile = CollapseOnNeighbouringPositions(sandPile, i, j);
if(sandPile[neighb_i1, neighb_j1] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i1, neighb_j1);
if(sandPile[neighb_i2, neighb_j2] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i2, neighb_j2);
if(sandPile[neighb_i3, neighb_j3] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i3, neighb_j3);
if(sandPile[neighb_i4, neighb_j4] > 3)
sandPile = CollapseOnNeighbouringPositions(sandPile, neighb_i4, neighb_j4);
public static void Main()
private static void Run()
new WastedSandCounterTests().Start();
public class WastedSandCounterTests
Tests.Run("WastedSandCounter should", (it) =>
it.Should(NotCountSandFallingOnTheTable,
"not count sand that falls on the table");
it.Should(CountAllSandFallingOffTheTable,
"count sand that falls off the table");
it.Should(FullyCollapseTallSandPiles,
"fully collapse tall piles of the sand");
public void NotCountSandFallingOnTheTable()
var counter = new WastedSandCounter();
counter.Count(table).ShouldBe(0);
public void CountAllSandFallingOffTheTable()
var counter = new WastedSandCounter();
counter.Count(table).ShouldBe(12);
public void FullyCollapseTallSandPiles()
var counter = new WastedSandCounter();
counter.Count(table).ShouldBe(6);
public static void Run(string testGroup, Action<Tests> tests)
public static void StartTests(string testGroup)
Console.WriteLine("====================================================");
Console.WriteLine(testGroup);
Console.WriteLine("====================================================");
public void Should(Action test, string testName)
Console.WriteLine(testName);
Console.WriteLine(" Passed");
Console.WriteLine(" Failed");
Console.WriteLine(" " + e.Message);
public static void EndTests()