Converting switch statements to more elegant solution - c#

I have a 9 x 9 matrix. (think of suduko).
4 2 1 6 8 1 8 5 8
3 1 5 8 1 1 7 5 8
1 1 4 0 5 6 7 0 4
6 2 5 5 4 4 8 1 2
6 8 8 2 8 1 6 3 5
8 4 2 6 4 7 4 1 1
1 3 5 3 8 8 5 2 2
2 6 6 0 8 8 8 0 6
8 7 2 3 3 1 1 7 4
now I wanna be able to get a "quadrant". for example (according to my code) the quadrant 2 , 2 returns the following:
5 4 4
2 8 1
6 4 7
If you've noticed, this is the matrix from the very center of the 9 x 9. I've split everything up in to pairs of "3" if you know what i mean. the first "ROW" is from 0 - 3, the second from 3 - 6, the third for 6 - 9.. I hope this makes sense ( I am open to alternate ways to go about this)
anyways, heres my code. I dont really like this way, even though it works. I do want speed though beccause i am making a suduko solver.
//a quadrant returns the mini 3 x 3
//row 1 has three quads,"1", "2", 3"
//row 2 has three quads "1", "2", "3" etc
public int[,] GetQuadrant(int rnum, int qnum) {
int[,] returnMatrix = new int[3, 3];
int colBegin, colEnd, rowBegin, rowEnd, row, column;
//this is so we can keep track of the new matrix
row = 0;
column = 0;
switch (qnum) {
case 1:
colBegin = 0;
colEnd = 3;
break;
case 2:
colBegin = 3;
colEnd = 6;
break;
case 3:
colBegin = 6;
colEnd = 9;
break;
default:
colBegin = 0;
colEnd = 0;
break;
}
switch (rnum) {
case 1:
rowBegin = 0;
rowEnd = 3;
break;
case 2:
rowBegin = 3;
rowEnd = 6;
break;
case 3:
rowBegin = 6;
rowEnd = 9;
break;
default:
rowBegin = 0;
rowEnd = 0;
break;
}
for (int i = rowBegin ; i < rowEnd; i++) {
for (int j = colBegin; j < colEnd; j++) {
returnMatrix[row, column] = _matrix[i, j];
column++;
}
column = 0;
row++;
}
return returnMatrix;
}

Unless I'm missing something, why not do math? Fist of all, only store rowBegin and colBegin.
Now, simply issue:
rowBegin = (rnum-1)*3
colBegin = (qnum-1)*3
This maps 1 -> 0, 2 -> 3, and 3-> 6.
Now, you loop from colBegin to colBegin + 3, and rowBegin to rowBegin + 3. Is your default behavior really necessary? If it is, special case when rnum < 1 || rnum > 3 and qnum < 1 || qnum > 3

The common pattern for this in Python is to use a dict to map:
qmap = {
1: (0, 3),
2: (3, 6),
3: (6, 9),
}
print qmap.get(qnum, (0, 0))
I'm sure that C# supports something similar.

For a general solution (i.e.: an NxN grid) I would use some maths (you'll need the modulo operator).
If you're always using a 9x9 sudoku grid then you can pre-calculate the answers and stick them in a map or array.
Of course you can combine those ideas and pre-calculate the answers in your init() function and then store them in a map.

Related

Generating a for while foreach algorithm in c# with a pyramidal structure

I have been trying to get this to work for 3 days, and I feel like I'm using the wrong approach, if anyone can correct me I will wax your car. Background, client asked to me make a simple pyramid algorithm. I want to select add everything to a list of objects and make everything on the left side true and everything on the right side false. Every other line reads the line 2 lines prior and adds multiple entries. The first time it adds a number like 1 it's one time, then it adds two 1's for each 1 until there is 4. So the first time it enters a 1 on line 1, then on line 3 it adds a 1 two times, then on line 5 it reads from line 3 and adds each of those 1's 2 times.
Here is a visual representation.
|1|
|2| |3|
|1|1| |4|5|
|2|2|3|3| |6|7|8|9|
|1|1|1|1|4|4|5|5| |10|11|12|13|14|15|16|17|
|2|2|2|2|3|3|3|3|6|6|7|7|8|8|9|9| |18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33
The order this list would be is:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17...
I keep getting close, but it fails to generate the correct output. `
for (int i = 1; i < 50; i = i * 2)
{
Response.Write(i.ToString() + " - ");
var previousLevel = (i / 2 / 2);
foreach (var oc in infoRows.Where(x => x.level == previousLevel))
{
for (int p = i; p > 0; p--)
{
Response.Write(oc.id + "*");
}
}
while (level <= i)
{
for (int r = 1; r <= i; r++)
{
InfoRow tempInforow = new InfoRow();
tempInforow.customerCode = GenerateCustomerNumber(position);
tempInforow.id = customerId;
tempInforow.sendtoidnumber = level.ToString();
tempInforow.status = 0; // GetStatus(position, totalCount);
tempInforow.position = position;
tempInforow.level = i;
infoRows.Add(tempInforow);
customerId++;
position++;
Response.Write(tempInforow.id + "-");
level++;
}
}
}
`
Essentially this generates the following:
1 - 1-
2 - 2-3-
4 - 1*1*1*1*4-5-6-7-
8 - 2*2*2*2*2*2*2*2*3*3*3*3*3*3*3*3*8-9-10-11-12-13-14-15-
16 - 4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*6*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*7*16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-
32 -
I've tried 30 different ways with switch statements, while statements, for and foreach statements, the closest I can get to this working is level 4.
Can someone suggest another way. Maybe a multidimensional array or idk what. Thank you.
Let's write the sequence down and have a look on what's going on:
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...
seq 1 2 3 1 1 4 5 2 2 3 3 6 7 8 9 1 1 1 1 4 4 5 5 10 ...
^ ^ ^ ^ ^ ^
| |
if # is power of 2 (e.g. 8 == 2**3)
we should copy and double # / 4 items (here 8 / 4 == 2 items)
starting from # / 4 item (here 8 / 4 == 2, starting from item #2)
Time to implement this algorithm
Code:
using System.Linq;
...
private static List<int> Pyramid(int size) {
if (size < 0)
throw new ArgumentOutOfRangeException(nameof(size));
if (size <= 3)
return Enumerable.Range(1, size).ToList();
List<int> result = new List<int>(size) { 1, 2, 3 };
for (int value = 4; result.Count < size; )
if (BitOperations.IsPow2(result.Count + 1)) {
int chunk = (result.Count + 1) / 4;
for (int i = 0; i < chunk && result.Count < size; ++i) {
result.Add(result[chunk - 1 + i]);
if (result.Count >= size)
return result;
result.Add(result[chunk - 1 + i]);
}
}
else
result.Add(value++);
return result;
}
Demo:
// First 31 items from the pyramid
Console.Write(string.Join("|", Pyramid(31)));
Output:
1|2|3|1|1|4|5|2|2|3|3|6|7|8|9|1|1|1|1|4|4|5|5|10|11|12|13|14|15|16|17

c# find the same numbers in each column in a 2d matrix

So, I have this task where I have to find the competitors who won in a tie.
Basically the input is a txt file, which has the number of competitors and the number of competitions in it's first row. The second and third rows are the maximum and minimum points. The rows after the third represent competitors and they have the amount of points they won.
I have to find the number of competitors who if they won, they won in a tie and their indexes.
One input:
6 8
9 9 9 9 9 9 9 9
5 5 5 5 5 5 5 5
8 4 6 6 6 6 6 6
7 5 7 6 6 6 6 5
6 6 6 5 5 5 5 6
8 6 8 7 7 7 7 6
8 6 6 6 6 6 6 6
8 6 6 6 6 6 6 1
The first row is 6 and 8 which means there is 6 competitors and 8 competition, the maximum points are 9 the minimum points are 5.
In this case the output is:
5 1 3 4 5 6
In the first column the winning point is 8, number 1 4 5 and 6 got 8 points which means they tied and should be added to the output, in the second column the winning point is 6, number 3 4 5 6 got 6 points so 3 should be added to the output too, and so on...
I've got this so far:
static void Main(string[] args)
{
string[] fRow = Console.ReadLine().Split(' '); //splitting the first row to get N and M
int N = int.Parse(esor[0]);
int M = int.Parse(esor[1]);
int[] maxPoint = new int[M];
int[] minPoint = new int[M];
string[] maxP = new string[M];
string[] minP = new string[M];
maxP= Console.ReadLine().Split(' ');
minP = Console.ReadLine().Split(' ');
for (int i = 0; i < M; i++)
{
maxPoint[i] = Convert.ToInt32(maxP[i]);
minPoint[i] = Convert.ToInt32(minP[i]);
}
int[,] matrix = new int[N, M];
int[] s = new int[M];
int mCol = 0; int mRow = 0;
for (int i = 0; i < N; i++) //adding the points to the matrix
{
string[] row = Console.ReadLine().Split(' ');
for (int h = 0; h < N; h++)
{
s[h] = Convert.ToInt32(row[h]);
matrix[mCol, mRow] = s[h];
mCol++;
if (mCol==N)
{
mCol = 0;
mRow++;
}
}
}
int max = 0; //trying to find the greatest point in each column
int[] winPoint = new int[M];
for (int i = 0; i < M; i++)
{
for (int h = 0; h < N; h++)
{
if (matrix[i, h] > max)
{
max = matrix[i, h];
}
if (h == N-1)
{
h = 0;
}
}
}
}
And I got stuck here, I'm trying to find the greatest point in each column so they I could search for the same numbers in the colums and count the amount of ties, but I don't know how to do it. If someone could help me I'd really appreciate it, or if I should to it in a different way just tell me.

Multiply element in multidimensional array

-> Please help with the implementation of a function
Basically I want to manipulate an image
Imagine that the image can be brake apart in pixels
-> each pixel of the image will be (for an easy example) "a number"
int[,] originalImage = new int[,]
{
{ 1,2,3 },
{ 4,5,6 }
};
And I need to double the size of the image x2 (or x3, x4, etc)
the pixel "1" when double the size will be copied on te right position, down and on the corner
int[,] expectedResult = new int[,]
{
{ 1,1,2,2,3,3 },
{ 1,1,2,2,3,3 },
{ 4,4,5,5,6,6 },
{ 4,4,5,5,6,6 }
};
How does the function can be implemented?
Multiply(int[,] originalImage, int multiply)
Note there are oodles of libraries that would do this in math or image processing. However, purely for academic purposes
Given
private static int[,] DoStuff(int[,] array,int size)
{
var sizeX = array.GetLength(0);
var sizeY = array.GetLength(1);
var newArray = new int[sizeX * size, sizeY * size];
for (var i = 0; i < newArray.GetLength(0); i++)
for (var j = 0; j < newArray.GetLength(1); j++)
newArray[i, j] = array[i / size, j / size];
return newArray;
}
Usage
int[,] originalImage =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
var newArray = DoStuff(originalImage,3);
for (var i = 0; i < newArray.GetLength(0); i++)
{
for (var j = 0; j < newArray.GetLength(1); j++)
Console.Write(newArray[i, j] + " ");
Console.WriteLine();
}
Output
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
1 1 1 2 2 2 3 3 3
4 4 4 5 5 5 6 6 6
4 4 4 5 5 5 6 6 6
4 4 4 5 5 5 6 6 6

Loop without IF or SWITCH condition within it

I want to print the number like as shown below using the loop and without using if or switch condition.
1
2
3
4
5
5
5
6
6
7
8
9
9
10
Note: When loop comes to number 5 it has to iterate 3 times and when it comes to 6 and 9 it has to iterate 2 times.
Example:
I have the following code which prints numbers same as they meet the condition.
My Try:
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Print Numbers 1 To 10");
for (int i = 1; i <= 10; i++)
{
Console.WriteLine( i==5 || i == 6 || i == 9 ? i.ToString() + Environment.NewLine + i.ToString() : i.ToString());
}
Console.ReadLine();
}
}
Try this:
for (int i = 1; i <= 14; i++)
Console.WriteLine(i - i / 6 - i / 7 - i / 9 + i / 12 - i / 13 + i / 14);
At position i = 6, i = 7, i = 9 and i = 13 you want to repeat the previous value, so subtract i / _, but need to add i / 12 and i / 14 because from 12 and 14 subtractions i / 6 and i / 7 start counting twice.
For starters, the ? mark operator is an if statement. So using that is out. But you could make an array:
int[] myNums = {1,2,3,4,5,5,5,6,6,7,8,9,9};
for (int i = 0; i < myNums.length; i++) {
Console.WriteLine(myNums[i]);
}
You could store the relationship between the number and the iteration count in a dictionary. The number to print would be the key and the number of times to print would be the value. You could then achieve what you need with then following:
var printNumbers = new Dictionary<int, int> { { 1, 1 }, { 2, 1 },{ 3, 1 },{ 4, 1 },{ 5, 3 }, { 6, 2 }, { 7, 1 }, { 8, 1 }, { 9, 2 } };
foreach (var num in printNumbers)
{
for (int i = 0; i < num.Value; i++)
{
Console.WriteLine(num.Key);
}
}

create the same function in another language

Sorry for the previous question, but I was so confused and stressed :S.
I have this function in R:
shift <- function(d, k) rbind( tail(d,k), head(d,-k), deparse.level = 0 )
and this data frame:
A B value
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412
this function will transform this data frame to (in case k=1) :
A B value
3 2 0.412
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
Code:
string[] data = File.ReadAllLines("test.txt");
decimal[,] numbers = new decimal[data.Length, 3];
for(int x = 0; x < data.Length; x++)
{
string[] temp = data[x].Split(' ');
for(int y = 1; y < temp.Length; y++)
{
numbers[x,y] = Convert.ToDecimal(temp[y]);
}
}
that's the code i'm using to get the values from the text file , but i want to create the function that will rotate this table.
I want to make the same function for a text file in Java or C#.
How this can be done?
I'm storing the data in C# in a 2D array: decimal[,]
UPDATE:
your function will rotate them like the previous example, what i want to do is this:
i have this table:
A B value
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412
i want it to become(in case of shift by 2) :
A B value
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412
1 1 0.123
2 1 0.213
I think this will do what you want but I must admit I'm not that familiar with C# so I'd expect there to be a more idiomatic form with less looping:
static decimal[,] Rotate(decimal[,] input, int k)
{
int m = input.GetLength(0);
int n = input.GetLength(1);
decimal[,] result = new decimal[m, n];
for (int i=0; i<m; i++)
{
int p = (i + k) % m;
if (p < 0)
p += m;
for (int j=0; j<n; j++)
result[p, j] = input[i, j];
return result;
}
Regarding your update, that is handled by passing a negative value for k. For your example pass k=-2.

Categories

Resources