Fall down elements in 2d array - c#

Hello looking for simple loop where numbers will fall down in 2d array for example
0 0 0 3 3
2 1 3 1 1
1 1 5 1 1
1 2 0 0 0
0 0 0 0 2
expected:
0 0 0 0 0
0 0 0 0 3
2 1 0 3 1
1 1 3 1 1
1 2 5 1 2
Do you have suggestions? Thank you.
Hint: Fall down means non-zero items must go down in each column!

Here is a solution:
void FallDown(ref int[,] numbers)
{
var rowCount = numbers.GetLength(0);
for (var c = 0; c < numbers.GetLength(1); c++)
{
var colValues = new List<int>();
for (var r = 0; r < rowCount; r++)
{
var colValue = numbers[r, c];
if (colValue > 0)
{
colValues.Add(colValue); // collect only non-zero values
}
}
if (colValues.Count < rowCount) // there were zeroes ...
{
do
{
colValues.Insert(0, 0); // fill it up with leading zeroes.
} while (colValues.Count < rowCount);
for (var r = 0; r < rowCount; r++) {
numbers[r, c] = colValues[r]; // put numbers back into original array
}
}
}
}
The result will be replaced in the original array, which is why it is passed in by ref.

Found this.
public void FallDown()
{
for (var row = 0; row < RowCount - 1; row++)
{
for (var column = 0; column < ColumnCount; column++)
{
if (tiles[row + 1, column] == 0 && tiles[row, column] != 0)
{
tiles[row + 1, column] = tiles[row, column];
tiles[row, column] = 0;
row = 0;
column = 0;
}
}
}
}

Related

Astar algorithm not working (possibly wrong heuristic value?)

I tried to follow wiki's A* star pseudocode and I had problems creating heuristic value method, so i just used it as Shortest Reach, but the code keeps adding starting node to the closedSet.
public uint TotalNodes = 0;
uint[][] Neighbors = null;
uint[][] Weights = null;
public Graph(uint v)
{
TotalNodes = v + 1;
Neighbors = new uint[TotalNodes][];
Weights = new uint[TotalNodes][];
for (int i = 1; i < TotalNodes; i++)
{
for (int j = 1; j < TotalNodes; j++)
{
Neighbors[i] = new uint[TotalNodes];
Weights[i] = new uint[TotalNodes];
}
}
}
public void AddNeighbor(uint parent, uint neighbor, uint distance)
{
Neighbors[parent][neighbor] = neighbor;
Weights[parent][neighbor] = distance;
}
public void RunAstarAlgorithm(uint start, uint goal)
{
uint[] closedSet = new uint[TotalNodes];
uint[] openSet = new uint[TotalNodes];
uint[] g_score = new uint[TotalNodes];
uint[] f_score = new uint[TotalNodes];
uint openSetNodes = 0, closedSetNodes = 0;
uint currentNode = 0;
uint tentativePathCost = 0;
openSet[0] = start;
for (uint i = 0; i < TotalNodes; i++)
{
if (i == start) f_score[i] = 0;
else f_score[i] = uint.MaxValue;
}
f_score[start] = g_score[start] + (uint)HeuristicCostEstimate(start,goal);
while (openSet.Length != 0)
{
for (uint i = 1; i < TotalNodes; i++)
{
if (f_score[i] == f_score.Min()) currentNode = i;
}
if (currentNode == goal)
{
ReconstructPath(closedSet, currentNode);
return;
}
for (uint i = 0; i < TotalNodes; i++) if (openSet[i] == currentNode) openSet[i] = 0;
closedSet[closedSetNodes] = currentNode;
closedSetNodes++;
foreach (uint neighbor in Neighbors[currentNode])
{
for (uint i = 0; i < TotalNodes; i++)
{
if (closedSet.Contains(neighbor)) continue;
}
tentativePathCost += g_score[currentNode] + Weights[currentNode][neighbor];
if (!openSet.Contains(neighbor) || tentativePathCost < g_score[neighbor])
{
g_score[neighbor] = tentativePathCost;
f_score[neighbor] = g_score[neighbor] + (uint)HeuristicCostEstimate(neighbor,goal);
if (!openSet.Contains(neighbor))
{
openSet[openSetNodes] = neighbor;
openSetNodes++;
}
}
}
}
}
Find heuristic value:
public int HeuristicCostEstimate(uint start, uint goal)
{
Queue<uint> queue = new Queue<uint>();
queue.Enqueue(start);
bool[] visitedNodes = new bool[TotalNodes];
int[] distances = new int[TotalNodes];
for (uint i = 0; i < TotalNodes; i++) distances[i] = -1;
distances[start] = 0;
while(queue.Count > 0)
{
uint node = queue.Dequeue();
if (node == goal) break;
foreach(uint neighbor in Neighbors[node])
{
if (neighbor == 0) continue;
if(distances[neighbor] == -1)
{
distances[neighbor] = distances[node] + 1;
queue.Enqueue(neighbor);
}
}
}
return distances[goal];
}
So i have this graph:
7 node graph
and for ex. i want to go from 1 to 5, so the path should be 1-2-3-6-5 right?
My graph is represented in jagged arrays (ignore the first (0) spot, i start from 1 for printing out purposes)
Neighbors array (first line represents nodes, columns represent their neigbhors:
(0)(1)(2)(3)(4)(5)(6)(7)
(0) 0 0 0 0 0 0 0 0
(1) 0 0 1 0 0 0 0 1
(2) 0 2 0 2 2 0 0 0
(3) 0 0 3 0 3 0 3 0
(4) 0 0 4 4 0 4 0 0
(5) 0 0 0 0 5 0 5 0
(6) 0 0 0 6 0 6 0 6
(7) 0 7 0 0 0 0 7 0
And weight(distance) array (columns represent their neigbhors and what is the distance to them):
(0)(1)(2)(3)(4)(5)(6)(7)
(0) 0 0 0 0 0 0 0 0
(1) 0 0 2 0 0 0 0 5
(2) 0 2 0 3 7 0 0 0
(3) 0 0 3 0 4 0 3 0
(4) 0 0 7 4 0 6 0 0
(5) 0 0 0 0 5 0 1 0
(6) 0 0 0 2 0 1 0 10
(7) 0 5 0 0 0 0 10 0
So how could i achieve shortest path with A* algorithm?

How to get all combinations with a fixed number of flags in array

here I have an array with a specific length and also a specific number of flags which have to be set. The length and number of flags can change from case to case, so they should be generic.
Example:
var array = new bool[] { false, false, false, false, false, false };
var numberOfFlags = 2;
I'd now like to get all permutations / combinations which are possible, when always 2 flags have to be set. Example:
1 1 0 0 0 0
0 1 1 0 0 0
0 0 1 1 0 0
But also for example:
0 1 0 0 0 1
Or:
0 0 0 1 0 1
I simply need a way to get all possible combinations where the predefined number of flags are set. No pattern or anything, just all possible combinations. Preferrably in C#.
I'm really looking forward to an answer and thanks a lot!
I found this on rosettacode.org. (I changed it a little bit). It's non-recursive. It just uses a Stack. It returns the same (modified) array every time, but that can be easily changed if needed.
public static IEnumerable<int[]> Combinations(int n, int k)
{
var result = new int[k];
var stack = new Stack<int>();
stack.Push(0);
while (stack.Count > 0) {
int index = stack.Count - 1;
int value = stack.Pop();
while (value < n) {
result[index++] = value++;
stack.Push(value);
if (index == k) {
yield return result;
break;
}
}
}
}
Combinations(6, 2) will give:
[0,1], [0,2], [0,3], [0,4], [0,5], [1,2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]
Just for numberOfFlags = 2 this is a simple sollution:
static void Main(string[] args)
{
var array = new bool[] { false, false, false, false, false, false };
var length = array.Length;
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j < length; j++)
{
var arr = (bool[])array.Clone();
arr[i] = arr[j] = true;
arr.ToList().ForEach(s => Console.Write((s ? 1 : 0) + " "));
Console.WriteLine();
}
}
Console.Read();
}
Output:
1 1 0 0 0 0
1 0 1 0 0 0
1 0 0 1 0 0
1 0 0 0 1 0
1 0 0 0 0 1
0 1 1 0 0 0
0 1 0 1 0 0
0 1 0 0 1 0
0 1 0 0 0 1
0 0 1 1 0 0
0 0 1 0 1 0
0 0 1 0 0 1
0 0 0 1 1 0
0 0 0 1 0 1
0 0 0 0 1 1
The number of combinations can be calculed with:
P=(n!)/(a!·b!)
Where n is the lenght of the array, a is numberOfFlags and b is n - a.
This is a method of achieving what you want:
bool[] array = new bool[] { false, false, false,false};
int numberOfFlags = 1;
int n, a, b,_n,_a,_b;
n = array.Length;
_n = n;
a = numberOfFlags;
_a = a;
b = n - a;
_b = b;
//Calculate n!
for (int i = _n - 1; i >= 1; i--)
n = n * i;
//Calculate a!
for (int i = _a - 1; i >= 1; i--)
a = a * i;
//Calculate a!
for (int i = _b - 1; i >= 1; i--)
b = b * i;
int NumberOfPermutations = n / (a * b);
------EDIT------
This code works only for an array with only 2 possible values. Imagine that we have 3 possible values, then:
n = lenght of the array
a = repetitions of the first value
b = repetitions of the second value
c = n - (a+b) = repetitions of the third value
The number of permutations could be calculed with
P=(n!)/(a!·b!·c! ...)
In the code you should add only some variables, some loops...et voilà

How to calculate distance between two values from two different 2d array

I have two bool[5,5] arrays which look like this:
1st:
1 1 1 1 1
0 1 0 0 0
0 0 1 1 0
0 0 0 0 0
0 1 0 1 0
2nd:
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0
0 0 1 1 0
1 0 0 0 0
What I have to do is simple calculating distance between 1 from 1st array and 1 from the 2nd one. I had multiple tries to solve this problem, but I can't solve this.
The result should looks like this:
4+3+2+1+0
0+0+0+0+0
0+0+0+0+0
0+0+0+0+0
0+1+0+3+0
Let me name arrays: first[,] and second[,]
There are fiew conditions:
if (first[i,j] == true && second[i,j] == true) distance[i,j] = 0
if (first[i,j] == false) distance[i,j] = 0
if (first[i,j] == true) then I have to calculate distance between closest 1 from second[,] eg. There are 1 in first[1,4] and first[3,4] and there is 1 in second[0,4] (there was mistake), so it means that distance[3,4] = 3 - 0 (because of second array's dimensions).
This is main method to calculate:
` static public int findPicture()
{
int[,] m = new int[testBitmap.GetLength(0),
testBitmap.GetLength(1)];
foreach (var picture in pictures)
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
if (testBitmap[i,j] == true)
{
do
{
i = i + 1;
} while (picture.Value[i,j] != true);
m[i,j] += 1;
}
}
}
var total = 0;
for (int a = 0; a < 5; a++)
{
for (int b = 0; b < 5; b++)
{
total += m[a, b];
}
}
return total;
}
return -1;
}`
It was my closest version to solve.
I would be very greatful if you could give some advices to solve this trivial problem.
I'd do something like this:
static int[,] BuildDistanceArray(bool[,] array1, bool[,] array2)
{
if (array1.GetLength(0) != array2.GetLength(0) || array1.GetLength(1) != array2.GetLength(1))
throw new Exception("Array sizes must match.");
int[,] distance = new int[array1.GetLength(0), array1.GetLength(1)];
for (int i = 0; i < array1.GetLength(0); ++i)
{
for (int j = 0; j < array1.GetLength(1); ++j)
{
distance[i, j] = array1[i, j] ? GetDistance(array2, i, j) : 0;
}
}
return distance;
}
static int GetDistance(bool[,] array, int row, int column)
{
int maxColumn = array.GetLength(1);
int distance = 0;
bool again;
do
{
again = false;
if (column - distance >= 0)
{
if (array[row, column - distance])
return distance;
again = true;
}
if (column + distance < maxColumn)
{
if (array[row, column + distance])
return distance;
again = true;
}
distance++;
} while (again);
return 0;
}
It gives the results you're looking for and it works for any size array.
This function calculates distance between 2 rows converted to int32. It's written in java, so some minor transformation will be required.
int distance(int x, int y) {
int count = Integer.bitCount(x);
int totalDist = 0;
for (int offset = 0; offset < 5 && x != 0; offset++) {
x = x ^ (x & (y << offset) & 0b11111);
x = x ^ (x & (y >>> offset));
int nextCount = Integer.bitCount(x);
totalDist += (count - nextCount) * offset;
count = nextCount;
}
return totalDist;
}

Algorithm to "spread" decreasing value on 3D array

I need to find an efficient algorithm that does this:
byte[,] initialArray
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 5 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
To this:
byte[,] resultArray
0 0 0 1 2 1 0 0 0 0
0 0 1 2 3 2 1 0 0 0
0 1 2 3 4 3 2 1 0 0
1 2 3 4 5 4 3 2 1 0
0 1 2 3 4 3 2 1 0 0
0 1 2 2 3 2 1 0 0 0
1 2 3 2 2 1 0 0 0 0
2 3 4 3 2 1 0 0 0 0
3 4 5 4 3 2 1 0 0 0
2 3 4 3 2 1 0 0 0 0
What's happening
The initial array has two cells that are set to an initial value, the other cells are set to 0. The algorithm needs to "spread" that value to neighbor cells (no diagonals, just up/down/left/right). Each time the value spreads to a new cell, the value is decreased by 1 and spreads again, recursively. When the value reaches 0 it stops.
If the value is spreading to a cell with value > 0, the largest of the two values should be kept, instead of simply overwriting.
The example shows a 2D array but I'm actually working with a 3D array.
My attempt
I've managed to make a simple recursive algorithm in C#. It works but it must be terribly inefficient. It's way to slow on a large 3D array with 4 initial cells with value >= 10. There must be a much better way of doing this (for those who are familiar, this is the method the Minecraft game uses to determine light intensity of each cell in the game. Minecraft level arrays are massive and can contain many light sources)
I'm looking for the most efficient way of doing this. Here is my C# implementation for 3D arrays:
main ... {
List<int[]> toCheck = new List<int[]>();
// This list will keep a record of the initial cells that have a value > 0
// For loop over each cell to find those with initial value > 0
for (int x=0; x<worldX; x++){
for (int y=0; y<worldY; y++){
for (int z=0; z<worldZ; z++){
if (data[x,y,z].light > 0)
toCheck.Add (new int[] {x,y,z});
}
}
}
// For each cell w/ initial value > 0, spread the light
foreach (int[] i in toCheck)
SpreadLight(i[0],i[1],i[2],(byte)(data[i[0],i[1],i[2]].light - 1));
}
void SpreadLight(int x, int y, int z, byte light) {
try {
// Make sure this cells current value is smaller than the value we want to assign to it
if (data[x,y,z].light < light) {
data[x,y,z].light = (byte)light;
}
// If the value at this cell is > 0, get adjacent cells and spread the light to each of them
if (light > 0) {
int[][] adjBlocks = GetAdjacentBlocks(x,y,z);
for (int i = 0; i < 6; i++) {
SpreadLight(adjBlocks[i][0], adjBlocks[i][1], adjBlocks[i][2],(byte)(light-1));
}
}
}
catch { return; } // I'm not proud if this, it's the easiest way I found to avoid out of array bounds error
}
// This method simply returns an array with the 3D coordinates of each adjacent cell
int[][] GetAdjacentBlocks(int x, int y, int z) {
int[][] result = new int[6][];
// Top
result[0] = new int[] {x, y+1, z};
// North
result[1] = new int[] {x, y, z+1};
// East
result[2] = new int[] {x+1, y, z};
// South
result[3] = new int[] {x, y, z-1};
// West
result[4] = new int[] {x-1, y, z};
// Bottom
result[5] = new int[] {x, y-1, z};
return result;
}
Try this. In my experience 1D arrays work much faster than 2D arrays. Also implemented are several shortcuts for the calculations.
2D version
class Program
{
static void Main(string[] args)
{
Area A=new Area(10, 10);
A[3, 4]=5;
A[8, 2]=5;
Console.WriteLine(A);
//0 0 0 0 0 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
//0 0 0 0 5 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
//0 0 5 0 0 0 0 0 0 0
//0 0 0 0 0 0 0 0 0 0
bool spread1=A.CheckSpread();
Console.WriteLine();
Console.WriteLine("Spreading...");
A.Spread();
bool spread2=A.CheckSpread();
Console.WriteLine(A);
//0 0 0 1 2 1 0 0 0 0
//0 0 1 2 3 2 1 0 0 0
//0 1 2 3 4 3 2 1 0 0
//1 2 3 4 5 4 3 2 1 0
//0 1 2 3 4 3 2 1 0 0
//0 1 2 2 3 2 1 0 0 0
//1 2 3 2 2 1 0 0 0 0
//2 3 4 3 2 1 0 0 0 0
//3 4 5 4 3 2 1 0 0 0
//2 3 4 3 2 1 0 0 0 0
}
}
public struct Area
{
byte[] map;
int rows, columns;
public Area(int rows, int columns)
{
this.map=new byte[rows*columns];
this.columns=columns;
this.rows=rows;
}
public Area(Area other)
: this(other.rows, other.columns)
{
Array.Copy(other.map, this.map, other.map.Length);
}
public Area(byte[,] array)
{
this.rows=array.GetLength(0);
this.columns=array.GetLength(1);
this.map=new byte[rows*columns];
for (int i=0; i<rows; i++)
{
for (int j=0; j<columns; j++)
{
this.map[i*columns+j]=array[i, j];
}
}
}
public int Rows { get { return rows; } }
public int Columns { get { return columns; } }
public byte[] Map { get { return map; } }
public byte this[int index]
{
get { return map[index]; }
set { map[index]=value; }
}
public byte this[int row, int column]
{
get { return map[row*columns+column]; }
set { map[row*columns+column]=value; }
}
public byte[,] ToArray2()
{
byte[,] array=new byte[rows, columns];
for (int i=0; i<rows; i++)
{
for (int j=0; j<columns; j++)
{
array[i, j]=map[i*columns+j];
}
}
return array;
}
public void Spread()
{
bool changed;
do // CAUTION: This is not guaranteed to exit. Or is it?
{
changed=false;
for (int k=0; k<map.Length; k++)
{
byte x=map[k];
if (x<=1) continue; // cannot affect neighbors
int i=k/columns;
int j=k%columns;
int k_N=i>0?(i-1)*columns+j:-1;
int k_S=i<rows-1?(i+1)*columns+j:-1;
int k_E=j<columns-1?i*columns+j+1:-1;
int k_W=j>0?i*columns+j-1:-1;
if (k_N>=0&&map[k_N]+1<x) { map[k_N]=(byte)(x-1); changed=true; }
if (k_S>=0&&map[k_S]+1<x) { map[k_S]=(byte)(x-1); changed=true; }
if (k_E>=0&&map[k_E]+1<x) { map[k_E]=(byte)(x-1); changed=true; }
if (k_W>=0&&map[k_W]+1<x) { map[k_W]=(byte)(x-1); changed=true; }
}
} while (changed);
}
public bool CheckSpread()
{
for (int k=0; k<map.Length; k++)
{
byte x=map[k];
if (x<=1) continue; // cannot affect neighbors
int i=k/columns;
int j=k%columns;
int k_N=i>0?(i-1)*columns+j:-1;
int k_S=i<rows-1?(i+1)*columns+j:-1;
int k_E=j<columns-1?i*columns+j+1:-1;
int k_W=j>0?i*columns+j-1:-1;
if (k_N>=0&&map[k_N]+1<x) return false;
if (k_S>=0&&map[k_S]+1<x) return false;
if (k_E>=0&&map[k_E]+1<x) return false;
if (k_W>=0&&map[k_W]+1<x) return false;
}
return true;
}
public override string ToString()
{
string[] table=new string[rows];
for (int i=0; i<rows; i++)
{
string[] row=new string[columns];
for (int j=0; j<columns; j++)
{
row[j]= string.Format("{0,-3}", map[i*columns+j]);
}
table[i]= string.Join(" ", row);
}
return string.Join(Environment.NewLine, table);
}
}
3D version
public struct Area3
{
byte[] map;
int rows, columns, pages;
public Area3(int rows, int columns, int pages)
{
this.map=new byte[rows*columns*pages];
this.columns=columns;
this.rows=rows;
this.pages=pages;
}
public Area3(Area3 other)
: this(other.rows, other.columns, other.pages)
{
Array.Copy(other.map, this.map, other.map.Length);
}
public Area3(byte[, ,] array)
{
this.rows=array.GetLength(0);
this.columns=array.GetLength(1);
this.pages=array.GetLength(2);
this.map=new byte[rows*columns*pages];
for (int i=0; i<rows; i++)
{
for (int j=0; j<columns; j++)
{
for (int l=0; l<pages; l++)
{
this.map[(l*rows+i)*columns+j]=array[i, j, l];
}
}
}
}
public int Rows { get { return rows; } }
public int Columns { get { return columns; } }
public int Pages { get { return pages; } }
public byte[] Map { get { return map; } }
public byte this[int index]
{
get { return map[index]; }
set { map[index]=value; }
}
public byte this[int row, int column, int page]
{
get { return map[(page*rows+row)*columns+column]; }
set { map[(page*rows+row)*columns+column]=value; }
}
public byte[, ,] ToArray3()
{
byte[, ,] array=new byte[rows, columns, pages];
for (int i=0; i<rows; i++)
{
for (int j=0; j<columns; j++)
{
for (int l=0; l<pages; l++)
{
array[i, j, l]=map[(l*rows+i)*columns+j];
}
}
}
return array;
}
public void Spread()
{
bool changed;
do
{
changed=false;
for (int k=0; k<map.Length; k++)
{
byte x=map[k];
if (x<=1) continue; // cannot affect neighbors
int l=k/(rows*columns);
int i=(k%(rows*columns))/columns;
int j=(k%(rows*columns))%columns;
int k_N=i>0?(l*rows+i-1)*columns+j:-1;
int k_S=i<rows-1?(l*rows+i+1)*columns+j:-1;
int k_E=j<columns-1?(l*rows+i)*columns+j+1:-1;
int k_W=j>0?(l*rows+i)*columns+j-1:-1;
int k_U=l<pages-1?((l+1)*rows+i)*columns+j:-1;
int k_D=l>0?((l-1)*rows+i)*columns+j:-1;
if (k_N>=0&&map[k_N]+1<x) { map[k_N]=(byte)(x-1); changed=true; }
if (k_S>=0&&map[k_S]+1<x) { map[k_S]=(byte)(x-1); changed=true; }
if (k_E>=0&&map[k_E]+1<x) { map[k_E]=(byte)(x-1); changed=true; }
if (k_W>=0&&map[k_W]+1<x) { map[k_W]=(byte)(x-1); changed=true; }
if (k_U>=0&&map[k_U]+1<x) { map[k_U]=(byte)(x-1); changed=true; }
if (k_D>=0&&map[k_D]+1<x) { map[k_D]=(byte)(x-1); changed=true; }
}
} while (changed);
}
}
No visualization coded for 3D.
The following implementation (2D) should be faster - it keeps object creation and unnecessary function calls to the minimum. Extending to 3D would be quite straightforward:
class Program
{
class ArrayPoint { public int x; public int y;}
private static byte[,] startArray =
{
{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,5,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,5,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0}
};
private static int rows = startArray.GetLength(0);
private static int cols = startArray.GetLength(1);
static void Main(string[] args)
{
Spread(startArray);
}
static void Spread(byte[,] array)
{
var points = GetStartPoints(array);
foreach (var point in points.ToList())
SpreadPoint(array, point.x, point.y);
Display(array);
}
static void SpreadPoint(byte[,] array, int x, int y)
{
for (var i = x-1; i < x+2; i++)
for (var j = y-1; j < y+2; j++)
if ( (i==x || j==y) && !(i==x && j==y) && (i >= 0 && i < rows && j >= 0 && j < cols)
&& array[i, j] + 1 < array[x, y])
{
array[i, j] = (byte)(array[x, y] - 1);
SpreadPoint(array, i, j);
}
}
static void Display(byte[,] array)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
Console.Write("{0} ",array[i,j]);
Console.WriteLine();
}
Console.WriteLine();
}
static IEnumerable<ArrayPoint> GetStartPoints(byte[,] array)
{
for (var i = 0; i < rows; i++)
for (var j = 0; j < cols; j++)
if (array[i, j] != 0)
yield return new ArrayPoint {x = i, y = j};
}
}
Output is:
0 0 0 1 2 1 0 0 0 0
0 0 1 2 3 2 1 0 0 0
0 1 2 3 4 3 2 1 0 0
1 2 3 4 5 4 3 2 1 0
0 1 2 3 4 3 2 1 0 0
0 1 2 2 3 2 1 0 0 0
1 2 3 2 2 1 0 0 0 0
2 3 4 3 2 1 0 0 0 0
3 4 5 4 3 2 1 0 0 0
2 3 4 3 2 1 0 0 0 0
My two cents: consider expanding the points at the same time along wavefronts. Individual wavefronts could thus be terminated when done earlier than others.
A simplified JavaScript example:
var s = new Array(81)
for (var i=0; i<81; i++){
s[i] = i == 40 ? 5 : 0
}
var max = 5, m = 9, n = 9
function expand(wavefront){
while (wavefront.val > 0) {
//Southwest
var tmpLoc = wavefront.loc--
for (var i=0; i<max - 1 - wavefront.val; i++){
s[tmpLoc] = wavefront.val
tmpLoc += n + 1
}
//Southeast...
//...
wavefront.val--
}
}
expand({loc: 49, val: 4})
s now looks like this:
[0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0
,0,0,0,0,0,0,0,0,0
,0,0,0,0,5,0,0,0,0
,0,1,2,3,0,0,0,0,0
,0,0,1,2,0,0,0,0,0
,0,0,0,1,0,0,0,0,0
,0,0,0,0,0,0,0,0,0]

Numbers cube, each row rotated to left by one

Basic C# question:
I need to have that result when entering some number (this case was entered 4):
4 3 2 1 0
3 2 1 0 4
2 1 0 4 3
1 0 4 3 2
I was trying that code, but cant figure out my mistake:
Console.WriteLine("Please write a Number: ");
Console.Write("Number: ");
int num = int.Parse(Console.ReadLine());
for (int i = 0; i <= num; i++)
{
for (int j = num - i; j >= 0; j--)
{
Console.Write(j);
}
for (int j = 1; j <= i; j++)
{
Console.Write(j);
}
Console.WriteLine();
}
Console.ReadLine();
This is the output I get:
4 3 2 1 0
3 2 1 0 1
2 1 0 1 2
1 0 1 2 3
0 1 2 3 4
Try this:
Console.WriteLine("Please write a Number: ");
Console.Write("Number: ");
int num = int.Parse(Console.ReadLine());
for (int i = 0; i <= num; i++)
{
for (int j = num - i; j >= 0; j--)
{
Console.Write(j);
}
for (int j = num; j > num - i; j--)
{
Console.Write(j);
}
Console.WriteLine();
}
Console.ReadLine();
The problem is that your second inner loop is starting at one and counting up rather than starting from num and counting down.
Change that loop to:
for (int j = num; j > num -i; j--)
{
Console.Write(j);
}
Also I'm not clear if you want the last line of 04321 or not. If you don't (as in the original example) then just change your loop check to i<num.
Try something like this
get a number(x) from user.
create a list of integer containing x to 0.
run a loop for x times.
every time print the list and pop the first number and push it at the end
var ints = new List<int> { 4, 3, 2, 1, 0 };
for (int i = 0; i < 4; i++)
{
ints.ForEach(n => Console.Write(n + " "));
Console.WriteLine("");
var a = ints[0];
ints.RemoveAt(0);
ints.Add(a);
}
As a hint I give you the main loop as a pseudo code:
for i from 0 to number_input-1 {
for j from number_input to 0 {
print((j-i)%(number_input+1) + " ")
}
print("\n")
}
Just for fun:
const int NUM = 4; // num from user
for (int start = NUM; start > 0; start--)
{
for (int i = 0; i <= NUM; i++)
{
int current = (start - i) >= 0 ? start - i : NUM + (start - i) + 1;
Console.Write(current + " ");
}
Console.WriteLine();
}
Honestly this is a classic sorting task. it's just hidden beyond "user types and bla bla bla" but I remember at school it was..
There is an array [4,3,2,1,0].. so
we swap 1 and 2 and get [3,4,2,1,0].
we swap 2 and 3 and get [3,2,4,1,0].
we swap 3 and 4 and get [3,2,1,4,0].
we swap 4 and 5 and get [3,2,1,0,4].
so just simple code
int[] numbers let say you have this array [4,3,2,1,0]
for(int i = 0; i < numbers.length - 2; i++){
for(int y = 0; y < numbers.length - 1; y++){
int buf = numbers[y];
numbers[y] = numbers[y + 1];
numbers[y + 1] = buf;
}
}

Categories