-> 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
Related
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.
I currently have an issue with zero padding my 2d Array. I want to transfer my current data in my array to a new array, which is the exact same array but with a border of 0's around it.
Example:
|1 2 3|
|4 5 6|
|7 8 9|
Should become
|0 0 0 0 0|
|0 1 2 3 0|
|0 4 5 6 0|
|0 7 8 9 0|
|0 0 0 0 0|
int[,] Array = new int[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 6, 7, 8 } };
int[,] ArrayZeroPad = new int[Array.GetLength(0) + 2, Array.GetLength(1) + 2];
for (int y = 0; y < Array.GetLength(1); y++)
{
for (int x = 0; x < ArrayZeroPad.GetLength(0); x++)
{
if (y == 0)
{ ArrayZeroPad[y, x] = 0; }
else if (y == ArrayZeroPad.GetLength(1))
{ ArrayZeroPad[y, x] = 0; }
else if (x == 0)
{
ArrayZeroPad[y, x] = 0;
}
else if (x == ArrayZeroPad.GetLength(0))
{ ArrayZeroPad[y, x] = 0; }
else ArrayZeroPad[y, x] = Array[y, x];
}
}
for (int y = 0; y < ArrayZeroPad.GetLength(1); y++)
{
Console.WriteLine();
for (int x = 0; x < ArrayZeroPad.GetLength(0); x++)
{ Console.Write(ArrayZeroPad[y, x]); }
Console.ReadLine();
}
}
This is what I have come to thus far, but I keep getting stuck on out of bounds errors, is there anyone who could work this out for me with some explanation?
Kind regards,
D.
This is not quite what you are asking (I thought a completely different alternative would be interesting).
Here is a No-Copy version that works for any type of array, of any size. It's appropriate if the original array is quite large (since it doesn't require a copy).
It uses a 2-dimensional indexer that either returns the default value of T (zero or null) for items on the edge, and uses the original array (with the indexes offset) for non-edge values:
public class ZeroPadArray <T>
{
private readonly T[,] _initArray;
public ZeroPadArray(T[,] arrayToPad)
{
_initArray = arrayToPad;
}
public T this[int i, int j]
{
get
{
if (i < 0 || i > _initArray.GetLength(0) + 1)
{
throw new ArgumentOutOfRangeException(nameof(i),
$#"Index {nameof(i)} must be between 0 and the width of the padded array");
}
if (j < 0 || j > _initArray.GetLength(1) + 1)
{
throw new ArgumentOutOfRangeException(nameof(j),
$#"Index {nameof(j)} must be between 0 and the width of the padded array");
}
if (i == 0 || j == 0)
{
return default(T);
}
if (i == _initArray.GetLength(0) + 1)
{
return default(T);
}
if (j == _initArray.GetLength(1) + 1)
{
return default(T);
}
//otherwise, just offset into the original array
return _initArray[i - 1, j - 1];
}
}
}
I just tested it with some Debug.Assert calls. The test coverage is weak, but it was good enough to say "this probably works":
int[,] array = new int[,] { { 1, 2, 3 }, { 11, 12, 13 }, { 21, 22, 23 } };
var paddedArray = new ZeroPadArray<int>(array);
Debug.Assert(paddedArray[0, 0] == 0);
Debug.Assert(paddedArray[4,4] == 0);
Debug.Assert(paddedArray[2,3] == 13);
And, finally, for fun, I added a nice little hack to make creating these things require less typing. When you call a method, the compiler is often able to deduce the generic type of the object from the method parameters. This doesn't work for constructors. That's why you need to specify new ZeroPadArray<int>(array) even though array is obviously an array of int.
The way to get around this is to create a second, non-generic class that you use as a static factory for creating things. Something like:
public static class ZeroPadArray
{
public static ZeroPadArray<T> Create<T>(T[,] arrayToPad)
{
return new ZeroPadArray<T>(arrayToPad);
}
}
Now, instead of typing:
var paddedArray = new ZeroPadArray<int>(array);
you can type:
var paddedArray = ZeroPadArray.Create(array);
Saving you two characters of typing (but, you need to admit that typing the <int> is frustrating).
int[,] Array = new int[,] { { 1, 2, 3 }, { 3, 4, 5 }, { 6, 7, 8 } };
int[,] ArrayZeroPad = new int[Array.GetLength(0) + 2, Array.GetLength(1) + 2];
for (int x = 0; x < ArrayZeroPad.GetLength(0); x++)
{
for (int y = 0; y < ArrayZeroPad.GetLength(0); y++)
{
//First row and last row
if (x == 0 || x == ArrayZeroPad.GetLength(0) - 1)
ArrayZeroPad[x, y] = 0;
else
{
//Fist column and last column
if (y == 0 || y == ArrayZeroPad.GetLength(0) - 1)
ArrayZeroPad[x, y] = 0;
else
{
//Content
ArrayZeroPad[x, y] = Array[x-1, y-1];
}
}
}
}
It seems that you are confusing dimensions - Array.GetLength(0) is for the first one in access Array[i, j] and Array.GetLength(1) is for the second. Also you can simplify copy by just scanning through Array elements and adjusting destination indexes by one, you don't need to explicitly set others to 0 cause it would be done for you (unless you are using stackalloc and skipping local init but I highly doubt that this is the case):
var length0 = Array.GetLength(0);
var length1 = Array.GetLength(1);
for (int i = 0; i < length0; i++)
{
for (int j = 0; j < length1; j++)
{
ArrayZeroPad[i + 1, j + 1] = Array[i, j];
}
}
And in the "print" method too - y should be the first dimension and x - second:
var length = ArrayZeroPad.GetLength(0);
for (int y = 0; y < length; y++)
{
Console.WriteLine();
var i = ArrayZeroPad.GetLength(1);
for (int x = 0; x < i; x++)
{
Console.Write(ArrayZeroPad[y, x]);
}
Console.ReadLine();
}
You can also solve this using Array.Copy(). If you require highest performance and the arrays are big enough, then this might be faster than explicitly copying each element:
public static int[,] Pad(int[,] input)
{
int h = input.GetLength(0);
int w = input.GetLength(1);
var output = new int[h+2, w+2];
for (int r = 0; r < h; ++r)
{
Array.Copy(input, r*w, output, (r+1)*(w+2)+1, w);
}
return output;
}
The (r+1)*(w+2)+1 requires some explanation. Array.Copy() treats a 2D array as a linear 1D array, and you must specify the destination offset for the copy as an offset from the start of the 1D array (in row-major order).
Since w is the width of the input array and r is the current row of the input array, the destination for the copy of the current input row will be the output row number, (r+1) times the output row width (w+2), plus 1 for to account for the left-hand column of 0 in the output array.
It's possible that using Buffer.BlockCopy() (which operates on bytes) could be even faster:
public static int[,] Pad(int[,] input)
{
int h = input.GetLength(0);
int w = input.GetLength(1);
var output = new int[h+2, w+2];
for (int r = 0; r < h; ++r)
{
Buffer.BlockCopy(input, r*w*sizeof(int), output, ((r+1)*(w+2)+1)*sizeof(int), w*sizeof(int));
}
return output;
}
As always, this is only worth worrying about if performance is critical, and even then only after you've benchmarked the code to verify that it actually is faster.
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);
}
}
How can I rotate (or shift) a 2D square array but leave any elements that are not on the "border" of the array unmoved?
Example:
1 2 3 4
12 13 14 5
11 15 16 6
10 9 8 7
What I want:
12 1 2 3
11 13 14 4
10 15 16 5
9 8 7 6
That was just an example. I need this to work on any square array of N width where 2 < N < 100
If the array is stored as a square .NET array of rank 2 the code is pretty simple mainly consisting of four loops - one for each edge:
var array = new [,] {
{ 1, 2, 3, 4, 5 },
{ 16, 17, 18, 19, 6 },
{ 15, 24, 25, 20, 7 },
{ 14, 23, 22, 21, 8 },
{ 13, 12, 11, 10, 9 }
};
// Rank = 2 and "square" and side length >= 2 checks removed for clarity.
var sideLength = array.GetLength(0);
// Save first element from top edge.
var element00 = array[0, 0];
// Rotate left edge.
for (var y = 1; y < sideLength; y += 1)
array[y - 1, 0] = array[y, 0];
// Rotate bottom edge.
for (var x = 1; x < sideLength; x += 1)
array[sideLength - 1, x - 1] = array[sideLength - 1, x];
// Rotate right edge.
for (var y = sideLength - 2; y >= 0; y -= 1)
array[y + 1, sideLength - 1] = array[y, sideLength - 1];
// Rotate top edge.
for (var x = sideLength - 2; x > 0; x -= 1)
array[0, x + 1] = array[0, x];
// Put saved element in place.
array[0, 1] = element00;
Now the original array has been rotated as described in the question.
If the array is stored as a one dimensional array it is easier to create a class to perform the rotation. This class can store properties (the array and the side length) that can be used across method calls to simplify the code.
The four loops contains the same logic even though they look different:
class ArrayRotator<T> {
public ArrayRotator(T[] array) {
if (array == null)
throw new ArgumentNullException("array");
var sideLength = (Int32) Math.Sqrt(array.Length);
if (sideLength*sideLength != array.Length)
throw new ArgumentException("Not a square.", "array");
Array = array;
SideLength = sideLength;
}
public T[] Array { get; private set; }
public Int32 SideLength { get; private set; }
public void RotateArray() {
if (SideLength < 3)
return;
// Save first element from top edge.
var element00 = Array[0];
// Rotate left edge.
for (var y = 1; y < SideLength; y += 1)
CopyElement(0, y, 0, y - 1);
// Rotate bottom edge.
for (var x = 1; x < SideLength; x += 1)
CopyElement(x, SideLength - 1, x - 1, SideLength - 1);
// Rotate right edge.
for (var y = SideLength - 2; y >= 0; y -= 1)
CopyElement(SideLength - 1, y, SideLength - 1, y + 1);
// Rotate top edge.
for (var x = SideLength - 2; x > 0; x -= 1)
CopyElement(x, 0, x + 1, 0);
// Put saved element in place.
Array[1] = element00;
}
void CopyElement(Int32 x1, Int32 y1, Int32 x2, Int32 y2) {
Array[GetIndex(x2, y2)] = Array[GetIndex(x1, y1)];
}
Int32 GetIndex(Int32 x, Int32 y) {
return y*SideLength + x;
}
}
Here is how to use the class:
var array = new [] {
1, 2, 3, 4,
12, 13, 14, 5,
11, 15, 16, 6,
10, 9, 8, 7
};
var arrayRotator = new ArrayRotator<Int32>(array);
arrayRotator.RotateArray();
Now the original array has been rotated as described in the question.
I found this question pretty interesting and fun, I've devised a little solution that works as long as the array conforms to a perfect square, this should work regardless of the side length.
NOTE: this is not the most optimized solution (I'm keen to try and make a more elegant solution, but this should suffice for now).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ArraySquareRotation
{
class Program
{
static void Main(string[] args)
{
int[] arr = new int[]
{
1, 2, 3, 4, 5, 3,
12, 13, 14, 5, 6, 1,
11, 15, 16, 6, 7, 22,
10, 9, 8, 7, 8, 30,
11, 15, 16, 6, 7, 22,
1, 2, 3, 4, 5, 3
};
// detect array size
int size = arr.Length;
// calculate the side length of the array (in terms of index)
int sideLength = BruteForceSquareDimensions(size);
// find the start of the last side of the square
int lastRowStartIndex = size - sideLength;
// a placeholder for us to generate a shifted array
int[] arrRotated = new int[size];
Console.WriteLine("Detected square with side length {0}", sideLength);
Console.WriteLine();
for (int i = 1; i <= size; i++)
{
// side rotation
if ((i % sideLength) == 0 && i != size)
{
// is multiple of
// right hand side, shift down
arrRotated[i + sideLength - 1] = arr[i - 1];
// left hand side, shift up
arrRotated[i + sideLength - (sideLength * 2)] = arr[i];
} else if (i < sideLength)
{
int lastRowIndex = sideLength * (sideLength - 1);
// first row, shift right
arrRotated[i] = arr[i - 1];
// last row, shit left
arrRotated[i + lastRowIndex - 1] = arr[i + lastRowStartIndex];
} else if(i < lastRowStartIndex)
{
// the inner square (this case may need some work)
arrRotated[i - 1] = arr[i - 1];
}
}
Console.WriteLine("Printing original array");
Console.WriteLine("======================");
PrintSquareArray(arr);
Console.WriteLine();
Console.WriteLine("Printing Shifted array");
Console.WriteLine("======================");
PrintSquareArray(arrRotated);
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
/// <summary>
/// there is definately a better way.
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
static int BruteForceSquareDimensions(int size)
{
int sideLength = 0;
for (int i = 1; i < size; i++)
{
if ((i * i) == size)
{
sideLength = i;
}
}
return sideLength;
}
/// <summary>
/// This method just prints the array in the desired readable format
/// </summary>
/// <param name="arr"></param>
static void PrintSquareArray(int[] arr)
{
int size = arr.Length;
int sideLength = BruteForceSquareDimensions(size);
for(int i = 1; i <= size; i++)
{
if ((i % sideLength) == 0)
{
Console.WriteLine(arr[i - 1]);
}
else
{
Console.Write(arr[i - 1] + "\t");
}
}
}
}
}
The output should look as follows (Square):
Detected square with side length 4
Printing original array
======================
1 2 3 4
12 13 14 5
11 15 16 6
10 9 8 7
Printing Shifted array
======================
12 1 2 3
11 13 14 4
10 15 16 5
9 8 7 6
Press any key to exit
And here's a 6 by 6
Detected square with side length 6
Printing original array
======================
1 2 3 4 5 3
12 13 14 5 6 1
11 15 16 6 7 22
10 9 8 7 8 30
11 15 16 6 7 22
1 2 3 4 5 3
Printing Shifted array
======================
12 1 2 3 4 5
11 13 14 5 6 3
10 15 16 6 7 1
11 9 8 7 8 22
1 15 16 6 7 30
2 3 4 5 3 22
Press any key to exit
Here's what I got. Tested on the 4x4 you provided and the following 5x5 square array. Also, I am assuming the data is stored in jagged arrays, such that 1 array contains n arrays each of length n.
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
static int[][] Transform(int[][] old)
{
var maxIdx = old.Length-1;
var canvas = new List<int[]>();
//top border
var top = new List<int>();
top.Add(old[1][0]);
for (var i = 0; i < maxIdx; i++)
{
top.Add(old[0][i]);
}
//bottom border
var bottom = new List<int>();
for (var i = 1; i < maxIdx+1; i++)
{
bottom.Add(old[maxIdx][i]);
}
bottom.Add(old[maxIdx - 1][maxIdx]);
//middle
var middle = new List<int[]>();
for (var i = 1; i < maxIdx; i++) //for each inner array
{
var inside = new List<int>();
inside.Add(old[i + 1][0]);
for (var j = 1; j < maxIdx; j++)
{
inside.Add(old[i][j]);
}
inside.Add(old[i - 1][maxIdx]);
middle.Add(inside.ToArray());
}
//Rebuild
canvas.Add(top.ToArray());
foreach (var arr in middle)
{
canvas.Add(arr);
}
canvas.Add(bottom.ToArray());
return canvas.ToArray();
}
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.