print diagonal routes array - c#

I make this code to print array if the number of array is
{
1, 2, 3, 4, 5,
6, 7, 8, 9,
10,11,12,13,
14,15,16,17,
18,19,20,21,
22,23,24,25
}
the out put of this code is
1,2,6,3,7,11,4,6,12,16,5,9,13,17,21,10,14,18,21,15,19,23,20,24,25
I want to make change in this my code to be the out put begging from
21 16 22 11 17 23 6 12 18 24 1 7 13 19 25 2 8 14 203 9 15 4 10 5
and this my Code
int [,] p = new int [5,5];
int sum = 1;
for (int i = 1; i <= 5; i++)
{
for (int j = 1; j <= 5; j++)
{
p[i, j] = sum;
richTextBox1.Text += p[i, j].ToString();
sum++;
}
}
int C;
int R=1;
for (int i = 1; i <= 5; i++)
{
C = i;
for (int r = 1; r <= i; r++)
{
Output = Output + p[r, C];
C--;
}
}
richTextBox2.Text += Output.ToString();
for (int i = 2; i >= 5; i++)
{
R = i;
for (C = 5; C >= i; C--)
{
Output = Output + p[R, C];
R++;
}
}
richTextBox2.Text += Output.ToString();

This is more fiddly than you might think!
You want to traverse the diagonals of this matrix:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
starting at the bottom left and traversing each diagonal as depicted in this very badly-drawn diagram:
I've written a helper method called DiagonalIndices() that for a given maximum index (in the case of your 5x5 matrix, it will be 4) will produce a sequence of (row,col) indices in the correct order to traverse all the diagonals.
Note that the input array MUST be square - I'm assuming that is the case for your data! It clearly is for a 5x5 matrix.
The output of the following program is
21 16 22 11 17 23 6 12 18 24 1 7 13 19 25 2 8 14 20 3 9 15 4 10 5
Here's the code:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
public sealed class Index
{
public Index(int row, int col)
{
Row = row;
Col = col;
}
public readonly int Row;
public readonly int Col;
}
public static class Program
{
private static void Main()
{
int [,] p = new int[5, 5];
for (int i = 0, n = 1; i < 5; ++i)
for (int j = 0; j < 5; ++j, ++n)
p[i, j] = n;
// This is the bit you will use in your program.
// Replace the Console.WriteLine() with your custom code
// that uses p[index.Row, index.Col]
int maxIndex = p.GetUpperBound(1);
foreach (var index in DiagonalIndices(maxIndex))
Console.Write(p[index.Row, index.Col] + " ");
Console.WriteLine();
}
public static IEnumerable<Index> DiagonalIndices(int maxIndex)
{
for (int i = 0; i <= maxIndex; ++i)
for (int j = 0; j <= i; ++j)
yield return new Index(maxIndex-i+j, j);
for (int i = 0; i < maxIndex; ++i)
for (int j = 0; j < maxIndex-i; ++j)
yield return new Index(j, i+j+1);
}
}
}

This is a more efficient of printing only the diagonal values in a positive direction in a matrix.
int [,] p = new int [5,5]
{
{1, 2, 3, 4,5},
{6, 7, 8, 9},
{10,11,12,13},
{14,15,16,17},
{18,19,20,21},
{22,23,24,25}
};
for (int i = 4, j = 4; i >= 0 && j > = 0; i--, j--)
{
Console.Writeline(p[ i, j ]);
}

Related

Generate non duplicate random number

I'm trying to make a lottery console app, but have a problem with duplicated numbers in some rows.
A lottery coupon is 10 row with 7 numbers, min number is 0, max number is 36.
How can i check if the number is exist in same row in my for loop?
here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obligatorisk_Opgave_2
{
class Program
{
static void Main(string[] args)
{
int min = 0; // minimum number
int max = 36; // maximum number
int rows = 10; // number of rows in my copun
int col = 7; // number of column in my copun
// Get the date of PC
string NameDate;
NameDate = DateTime.Now.ToString("yyyy.MM.dd");
string Week = "1-uge";
string ComName = "LYN LOTTO";
Random rnd = new Random();
Console.WriteLine("{0,22} \n {1,15} \n{2,18}", NameDate, Week, ComName);
for (int i = 0; i < rows; i++)
{
Console.Write($"{i + 1}.");
for (int j = 0; j < col; j++)
Console.Write("{1,4}", i, rnd.Next(min, max));
Console.WriteLine();
}
Console.WriteLine("***** JOKER TAL *****");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < col; j++)
Console.Write("{0,4}", rnd.Next(1,9));
Console.WriteLine();
}
}
}
}
You can use a recursive function to do this:
private static List<int> GetRandomRow(List<int> row, int colCount, int min, int max)
{
if(colCount <= 0)
{
return row;
}
var next = rnd.Next(min, max);
if(row.Contains(next))
{
return GetRandomRow(row, colCount, min, max);
}
row.Add(next);
return GetRandomRow(row, colCount - 1, min, max);
}
Then you can use your program like:
private static Random rnd = new Random();
static void Main(string[] args)
{
int min = 0; // minimum number
int max = 36; // maximum number
int rows = 10; // number of rows in my copun
int col = 7; // number of column in my copun
// Get the date of PC
string NameDate;
NameDate = DateTime.Now.ToString("yyyy.MM.dd");
string Week = "1-uge";
string ComName = "LYN LOTTO";
Random rnd = new Random();
Console.WriteLine("{0,22} \n {1,15} \n{2,18}", NameDate, Week, ComName);
for (int i = 0; i < rows; i++)
{
Console.Write($"{i + 1}.");
var row = new List<int>();
var currentRow = GetRandomRow(row, col, min, max);
foreach (var currentCol in currentRow)
{
Console.Write("{1,4}", i, currentCol);
}
Console.WriteLine();
}
Console.WriteLine("***** JOKER TAL *****");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < col; j++)
Console.Write("{0,4}", rnd.Next(1, 9));
Console.WriteLine();
}
}
Instead of random numbers you could Shuffle your List.
Shuffle Function:
public static List<T> Shuffle<T> (List<T> list) {
Random rnd = new Random();
for (int i = 0; i < list.Count; i++)
{
int k = rnd.Next(0, i);
T value = list[k];
list[k] = list[i];
list[i] = value;
}
return list;
}
Now you can call that function and shuffle the content of your List.
Example:
int min = 0;
int max = 36;
int rows = 10;
List<int> mylist = new List<int>();
for (int i = max; i >= min; i--) {
mylist.Add(i);
}
mylist = Shuffle(mylist);
for (int i = 0; i < rows; i++) {
Console.WriteLine(mylist[i]);
}
Console.ReadLine();
simply you can define variable from string data type and add each column in this variable but before add operation you should check if this column exists in this string or not
code is updated
i have definde rndNumber as an integer type before check then i have assigned rnd.Next(min, max) to it, because if i check for rnd.Next(min, max) and if it was not exist so when add it in checkNumber may be it changed again for example...
if(checkNumber.Contains(rnd.Next(min, max))) // if value of rnd.Next(min, max) was 15 and this number not exist in checkNumber so i can add it
{
checkNumber += rnd.Next(min, max); // maybe value of rnd.Next(min, max) change to will be 20
}
notice that every time you call rnd.Next(min, max) it's value will be changed
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obligatorisk_Opgave_2
{
class Program
{
static void Main(string[] args)
{
int min = 0; // minimum number
int max = 36; // maximum number
int rows = 10; // number of rows in my copun
int col = 7; // number of column in my copun
string checkColumn = ""; // string variable for storing rows values
// Get the date of PC
string NameDate;
NameDate = DateTime.Now.ToString("yyyy.MM.dd");
string Week = "1-uge";
string ComName = "LYN LOTTO";
Random rnd = new Random();
Console.WriteLine("{0,22} \n {1,15} \n{2,18}", NameDate, Week, ComName);
for (int i = 0; i < rows; i++)
{
Console.Write($"{i + 1}.");
for (int j = 0; j < col; j++)
{
// check here if string does not contains this random value then add this it into string and write this number, else will be written duplicated number
int rndNumber = rnd.Next(min, max);
if ( !checkColumn.Contains(rndNumber.ToString()+", ") )
{
checkColumn += rndNumber.ToString()+", ";
Console.Write("{1,4}", i, rndNumber);
}
else
{
Console.Write("duplicated number");
}
}
checkColumn += "\n";
Console.WriteLine();
}
Console.WriteLine("***** JOKER TAL *****");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < col; j++)
Console.Write("{0,4}", rnd.Next(1,9));
Console.WriteLine();
}
}
}
}
I'd use something more like:
for (int i = 1; i <= rows; i++)
{
Console.Write((i + ".").PadRight(3));
var row = Enumerable.Range(min, (max - min) + 1).OrderBy(x => rnd.Next()).Take(col).ToList();
foreach(var num in row) {
Console.Write(num.ToString("00").PadLeft(3));
}
Console.WriteLine();
}
Producing:
1. 33 14 24 27 07 29 30
2. 12 31 03 19 04 02 30
3. 34 03 14 23 20 09 04
4. 09 11 24 07 00 30 17
5. 26 04 22 02 25 20 12
6. 28 26 12 08 04 25 35
7. 09 26 20 34 17 03 23
8. 25 26 35 08 29 06 01
9. 29 33 00 04 09 35 36
10. 00 14 19 25 03 21 33

C++ vector vs C# List. Why are they producing different results?

I'm translating some code from C++ to C#. The code is simple enough and most of the syntax involved is almost the same, however the C++ version uses a vector<vector<int>> structure that doesn't exists in C#, so I replaced it with a List<List<int>> which I initialized with empty "rows" since I need it to represent a table with a fixed number of rows (See the code below).
The logic is exactly the same but somehow i'm not getting the same outputs. I suspect it has to do with the behaviour of List<List<int>> but I'm not sure. Any hints would be appreciated.
This is the original C++ code:
void LIS(int arr[], int n)
{
vector<vector<int>> L(n);
L[0].push_back(arr[0]);
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if ((arr[i] > arr[j]) && (L[i].size() < L[j].size() + 1)){
L[i] = L[j];
}
}
L[i].push_back(arr[i]);
}
vector<int> max = L[0];
for (vector<int> x : L)
if (x.size() > max.size())
max = x;
for(int e : max){
cout<<e<<endl;
}
}
This is my C# version:
public static void LIS(int[] arr, int n)
{
// Here I replace the vector<vector<int>> with a List<List<int>>
// and I fill it with n empty lists.
List<List<int>> L = new List<List<int>>();
for(int x = 0; x < n; x++)
{
L.Add(new List<int>());
}
L[0].Add(arr[0]);
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if ((arr[i] > arr[j]) && (L[i].Count < L[j].Count + 1))
{
L[i] = L[j];
}
}
L[i].Add(arr[i]);
}
List<int> max = L[0];
foreach (List<int> x in L)
{
if (x.Count > max.Count)
{
max = new List<int>(x);
}
}
foreach(int e in max){
Console.WriteLine(e);
}
I'm testing with this array:
int[] arr = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 };
int n = arr.Length;
In the C++ version I get:
0 2 6 9 11 15
and in the C# version I get:
0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15
In the C++ code doesn't L[i] = L[j]; make a copy of the vector at L[j] and store it in L[i] (similar thing for the variable max)? To achieve a similar result in C#, you could do L[i] = L[j].ToList() to copy the list.

Reading a multi-dimensional array in a different order

So I have a number array like this
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
And know what I want to know is how to make it read the number 7 after the number 3, and number 8 after number 4. And so on, like this:
0 -> 1 -> 2 -> 3
|
\/
4 <- 5 <- 6 <- 7
|
\/
8 -> 9 -> 10 -> 11
|
\/
12 <- 13 <- 14 <- 15
However if I use nested incremental for it will read in normal sequential order.
I have no idea how to make it read from 3 to 7, 4 to 8 and so on...
How can I achieve that?
You can store a flag indicating if the next iteration is going to start on the left or right. So...
static void Main(string[] args)
{
// initializing values
int[,] arr = new int[4, 4];
int n = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
arr[i, j] = n++;
}
}
n = 0;
// initialization end
// starts from the left
bool left = true;
// go line by line
for (int i = 0; i < 4; i++)
{
// if it starts from the left, set start point a index 0
// otherwise start from max index
for (int j = left ? 0 : 3; left ? j < 4 : j >= 0; )
{
arr[i, j] = n++;
// increment/decrements depending on the direction
j = left ? j + 1 : j - 1;
}
// if it started from the left, the next iteration will
// start from the right
left = !left;
}
}
Results:
Initialized:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
After navigating on it:
0 1 2 3
7 6 5 4
8 9 10 11
15 14 13 12
If you have:
_arr = new int[,] { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
Then try:
public void PrintArr()
{
for (int i = 0; i < 4; i++)
{
if (i % 2 == 0)
{
for (int j = 0; j < 4; j++)
Console.Write(_arr[i, j] + " ");
Console.WriteLine();
}
else
{
for (int j = 3; j >= 0; j--)
Console.Write(_arr[i, j] + " ");
Console.WriteLine();
}
}
}
Here's a short, simple solution:
int h = array.GetLength(0), w = array.GetLength(1);
for(int i = 0, j = 0, c = 1; i < h; i++, c = -c, j += c)
{
for(int k = 0; k < w; k++, j += c)
{
Console.WriteLine(array[i, j]);
}
}

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;
}
}

Finding the column total in an array

I have an 1-dimensional array with random elements, got through a m*n grid. I want to find out the row total and column total, present in it.
Here is how the 1 dimensional array is:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
I want to treat it like :
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20
Now i want to find the reo total and column total.
Row total is done as follows:
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalColumns; j++)
{
rowTotal[i] += numbers[temp + j];
}
temp += totalColumns;
}
I am trying to do the same with Column.
Here is the code:
for (int i = 0; i < totalColumns; i++)
{
tempk = 0;
for (int j = 0; j < totalRows; j++)
{
blockTotal[i] += numbers[i+j+tempk];
tempk += totalColumns;
}
}
Am not able to get the column total, as intended. Please Help.
You can get both in the same loop
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalColumns; j++)
{
rowTotal[i] += numbers[i * totalColumns + j];
blockTotal[j] += numbers[i * totalColumns + j];
}
}
The easiest thing to do is to write a little method that translates a "logical" (row, col) address to an index:
int numberAt(int row, int col)
{
return numbers[row * totalColumns + col];
}
int[] colTotals = new int[totalColumns];
int[] rowTotals = new int[totalRows];
for (int row = 0; row < totalRows; ++row)
{
for (int col = 0; col < totalColumns; ++col)
{
int number = numberAt(row, col);
rowTotals[row] += number;
colTotals[col] += number;
}
}
Edit in response to question in comments below:
Here's a complete compilable example that demonstrates it working on a non-square array:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
class Program
{
// Array will 4x3 (rows x cols):
//
// 1 2 3 | 6
// 4 5 6 | 15
// 7 8 9 | 24
// 10 11 12 | 33
// ---------
// 22 26 30
int[] numbers = Enumerable.Range(1, 12).ToArray();
int totalColumns = 3;
int totalRows = 4;
int numberAt(int row, int col)
{
return numbers[row * totalColumns + col];
}
void test()
{
int[] colTotals = new int[totalColumns];
int[] rowTotals = new int[totalRows];
for (int row = 0; row < totalRows; ++row)
{
for (int col = 0; col < totalColumns; ++col)
{
int number = numberAt(row, col);
rowTotals[row] += number;
colTotals[col] += number;
}
}
Console.WriteLine("Row totals");
foreach (int rowTotal in rowTotals)
Console.Write(rowTotal + " ");
Console.WriteLine("\nCol totals");
foreach (int colTotal in colTotals)
Console.Write(colTotal + " ");
Console.WriteLine();
}
static void Main()
{
new Program().test();
}
}
}
Total by rows
for(int r = 0; r < totalRows; r++)
{
for(int c = 0; c < totalColumns; c++)
{
rowTotal[r] += numbers[r * totalColumns + c];
}
}
Total by columns
for(int c = 0; c < totalColumns; c++)
{
for(int r = 0; r < totalRows; r++)
{
colTotal[c] += numbers[r * totalColumns + c];
}
}

Categories