C# split 1D array into 2D array for every Nth value - c#

I have a 1D array of ints:
int[] array = { 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32,33, 34,40,41,42,43, 44};
I would like to divide this 1D array into a 2D array of 4 rows and 5 columns, where the first 5 values goes into row 1, the next 5 in row 2 and so on. The final result should look like this:
array2D:
[[10, 11, 12, 13, 14]
[20, 21, 22, 23, 24]
[30, 31, 32, 33, 34]
[40, 41, 42, 43, 44]]
In reality the array will be much longer(maybe 100+ rows), but the number of columns is 5 and number of rows is dividable by 5. I have simplified for example. This is what I have tried so far:
int[] array = { 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32,33, 34,40,41,42,43, 44};
int[,] array2D = new int[(array.Length/5),5];
int count_0 = 1;
int count_1 = 1;
int count_2 = 1;
int count_3 = 1;
int count_4 = 1;
for (int i = 0; i < array.Length; i++)
{
if (i < 5)
{
// works for the first 5 values:
array2D[0, i] = array[i];
}
// I tried this approach for the rest where I try to say that if Im at index 5,
//and every 5th element from here, append to it to index[i,0] of array2D and so on.
// This do not work, and is what I need help with.
else if (i >= 5 && i % 5 == 0)
{
array2D[count_0, 0] = array[i];
count_0++;
}
else if (i >= 6 && i % 5 == 0)
{
array2D[count_1, 1] = array[i];
count_1++;
}
else if (i >= 7 && i % 5 == 0)
{
array2D[count_2, 2] = array[i];
count_2++;
}
else if (i >= 8 && i % 5 == 0)
{
array2D[count_3, 3] = array[i];
count_3++;
}
else if (i >= 9 && i % 5 == 0)
{
array2D[count_4, 4] = array[i];
count_4++;
}
}
Of course for this example I could just say if > 5 && <10 {append to array2D} and if > 10 && <15 {append to array2D} and so on, but I want something that works for a large array of hundreds of values. If someone has a smarter way to do this please let me know.
Thank you for any help!

You can just calculate the indexes:
for(int i=0;i<array.Length;i++)
array2D[i/5, i%5] = array[i];

You can calculate the indexes easily using simple division. The row is calculated by the dividing i with the wanted column numbers. The column is simply the reminder of that division.
using System;
public class Program
{
public static T[,] SplitInto2DArray<T>(T[] array, int rows, int columns) {
T[,] result = new T[rows, columns];
for (int i = 0; i < array.Length; i++) {
result[i / columns, i % columns] = array[i];
}
return result;
}
public static void PrintArray<T>(T[,] array) {
for (int i = 0; i < array.GetLength(0); i++) {
for (int j = 0; j < array.GetLength(1); j++) {
Console.Write(array[i, j] + " ");
}
Console.WriteLine();
}
}
public static void Main()
{
int[] array = { 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44};
int[,] splittedArray = SplitInto2DArray(array, 4, 5);
PrintArray(splittedArray);
}
}

You can accomplish with LINQ using Enumerable.GroupBy.
array.GroupBy(x => x / 5)
.Select(x => x.ToArray())
.ToArray()

Related

How to return an array fibonaci numbers in C #?

I want to make a function that takes an array of integers as input and print an array of int as Fibonaci series like: third element= second element + first element.
Here is my code so far:
static void Result(int[] arr)
{
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] < 0)
Console.WriteLine("arr[i]", arr[i], " number to get must be greater or equal than 0");
var n = arr[i] + 1;
var a = new int[n];
arr[0] = 0;
if (arr[i] == 0)
{
a[1] = 1;
}
for ( i = 2; i < n; i++)
{
a[i] = a[i - 2] + a[i - 1];
}
}
}
public static void Main()
{
int[] arr = {7, 8, 3, 9, 11,16,14,91, };
Result(arr);
}
if input is : 1 ,3 ,4 ,6, 7 ,8 10, 11, 15 ,25 output should be: 1, 3, 4, 7, 11 so 1+3=4, 4+3=7 and so on.
I took a look at your code and you were very close.
The biggest issue was you were starting at i = 0 which would cause errors if you attempted to access arr[-1] and arr[-2].
We can solve that by starting with i = 2.
For example:
static int[] Result(int[] arr)
{
int[] result = arr;
for (int i = 2; i < arr.Length; i++)
{
result[i] = result[i-1] + result[i-2];
}
return result;
}
int[] arr = { 1 ,3 ,4 ,6, 7 ,8, 10, 11, 15 ,25 };
arr = Result(arr);
Console.WriteLine(string.Join(", ",arr));
// outputs: 1, 3, 4, 7, 11, 18, 29, 47, 76, 123
Another side note is that unless you're passing the int[] arr as a reference you will need to return a new int[] as the result since Result()'s changes to arr are not reflected on the array.

Last number in an array becomes first

I know that's easy, but I don't understand how I should do it.
1 23 29 18 43 20 5
to
5 1 23 29 18 43 20
I think we should use for-loop:
for (int i = 0; i < numbers.Count - 1; i++)
{
}
but I don't know what to do in it. Something like numbers[i] = numbers[i - 1] but it isn't working. I think there are some if checks which I miss.
The most straightforward way that comes to mind is a reverse loop.
int[] numbers = { 1, 23, 29, 18, 43, 20, 5};
int lastVal = numbers[numbers.Length - 1];
for (int i = numbers.Length -1; i > 0; i--)
numbers[i] = numbers[i-1];
numbers[0] = lastVal;
Just looping from the end (after saving the last value) and moving "up" the values, finally replacing the first value with the last
Here's a oneliner:
var numbers = new[] {1, 23, 29, 18, 43, 20, 5};
numbers = new[] {numbers.Last()}.Concat(numbers.Take(numbers.Length - 1)).ToArray();
This creates a new array containing the last element, then concatenates it with the original array excluding the last element.
What you want to do is make another array of the same size as the original one, then assign the last element and loop through the array up to the previous to last element.
Something like this:
int[] original = {1, 23, 29, 18, 43, 20, 5};
int[] altered = new int[original.length];
altered[0] = original[original.length - 1];
for (int i = 1; i < original.length - 1; i++)
{
altered[i] = original[i - 1];
}
You can perform a left rotation to the table by six positions on your case and create the requested new table
int[] myArray = new int[] { 1, 23, 29, 18, 43, 20, 5 };
var newArray = LeftRotationByD(myArray, 6);
and your function for the rotation would be:
private static int[] LeftRotationByD(int[] a, int k)
{
int[] b = new int[a.Length];
int index;
int length = a.Length;
int place;
for (int i = 0; i < length; i++)
{
index = i - k;
place = length + index;
if (index >= 0) b[index] = a[i];
else b[place] = a[i];
}
return b;
}
You can use this method to shift right:
void ShiftRight(int[] array, int count)
{
var clone = (int[])array.Clone();
for (var i = 0; i < array.Length; i++)
array[(i + count) % array.Length] = clone[i];
}
And use it this way:
var a = new int[] { 1, 2, 3, 4 };
ShiftRight(a, 1);

How to remove all occurrences in array and shift leftovers left?

We have two arrays of integers a1 and a2 as parameters and we should remove all occurrences of a2 values from a1. Element is "removed" by shifting all subsequent elements one index to the left to cover it up, placing a 0 into the last index. The original relative ordering of a1 elements should be retained.
i'm having problem with shifting it's element.
Example:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1};
int[] a2 = { 42, 2222, 9};
the final result should be like this:
{3, 0, 17, 8, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
so here is my code:
for(int i = 0; i < a1.Length; i++)
{
foreach(var element in a2)
{
if (element == a1[i])
{
for(int j = i; j < a1.Length-1; j++)
{
a1[j] = a1[j+1];
}
a1[a1.Length - 1] = 0;
}
}
}
You need to use i--; when your item matches. Because you're shifting your entire array. Also you need to use break; your inner foreach loop after i--;.
Explanation
1) With your arrays, for i = 0 and first element in foreach(var element in a2) both will be 42. So first your array will be shifted one index. Now if you are not using i-- then it will check for i=1 which should be 3 but as we already shifted our array so 3 value is at index 0. So this value will never getting checked for match.
2) And use of break, as your match already found and array is shifted there is no requirement for check further.
Your code should be like below.
for(int i = 0; i < a1.Length; i++)
{
foreach(var element in a2)
{
if (element == a1[i])
{
for(int j = i; j < a1.Length-1; j++)
{
a1[j] = a1[j+1];
}
a1[a1.Length - 1] = 0;
i--;
break;
}
}
}
If You can use Linq then try as below, First get filters elements first. Then add 0 for rest indexes.
int[] a1= { 42,3,9,42,42,0,42,9,42,42,17,8,2222,4,9,0,1};
int[] a2= { 42,2222,9};
var a3 = a1.Where(x => !a2.Contains(x)).ToArray();
for (int i = 0; i < a1.Length; i++) {
if (i < a3.Length)
a1[i] = a3[i];
else
a1[i] = 0;
}
You can do this without creating any extra arrays like so:
static void Main()
{
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
int j = 0;
for (int i = 0; i < a1.Length; ++i)
if (Array.IndexOf(a2, a1[i]) < 0) // Don't remove this value.
a1[j++] = a1[i];
Array.Clear(a1, j, a1.Length-j);
Console.WriteLine(string.Join(", ", a1));
}
We make two passes: Firstly to remove all the elements of a1 that are contained in a2 (via the explicit loop) and then to overwrite all the "removed" values with 0 (via Array.Clear().
Just a different approach by first filtering and then adding the needed zeros:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
var zeros = Enumerable.Repeat(0, int.MaxValue);
var valids = a1.Where(v => !a2.Contains(v));
var result = valids.Concat(zeros).Take(a1.Length);
Console.WriteLine(String.Join(", ", result));
Yet another approach, using Array.Copyfor shifting:
public static void Main()
{
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
for(int i = 0; i < a1.Length; i++)
{
if(a2.Contains(a1[i]))
{
//notice i-- here because iterating array shifted to left
ShiftToLeft(a1, i--+1);
}
}
Console.WriteLine(string.Join(",", a1));
}
private static void ShiftToLeft(int[] array, int fromIndex)
{
Array.Copy(array, fromIndex, array, fromIndex-1, array.Length - fromIndex);
array[array.Length-1] = 0;
}
Try This:
int[] a1 = { 42, 3, 9, 42, 42, 0, 42, 9, 42, 42, 17, 8, 2222, 4, 9, 0, 1 };
int[] a2 = { 42, 2222, 9 };
var result = a1.Where(x => !a2.Contains(x)).Concat(new int[a1.Length]).Take(a1.Length);
Console.WriteLine(String.Join(", ", result));

Multidimensional array column sorting

assume i create this code to generate the idv-th random number. But i have a difficulty in sorting the array depends on the last column.
let say the individual size is [idv, width] = [8,6]
and i want to sort all the row with column 6th... and i want to take the 4 top list in the array after it sorted. How can i implement this case to the code??
public static void population(double[,] individual, int width, int idv, Random rnd)
{
for (int i = 0; i < idv; i++)
{
Console.Write("individual {0} :\t", i+1);
for (int j = 0; j < width; j++)
{
individual[i, j] = Math.Round(rnd.NextDouble() * 10, 2);
Console.Write("{0} ", individual[i, j]);
}
Console.WriteLine("\n");
}
}
Thank you
I suggest you using jagged arrays double[][] instead of 2d ones double[,]. Jagged array is just an array of array which you can easily sort, filter, etc. usually with a help of Linq:
double[][] individual = new double[][] {
new double[] {81, 82, 83, 84, 85, 86},
new double[] {11, 12, 13, 14, 15, 16},
new double[] {41, 42, 43, 44, 45, 46},
new double[] {31, 32, 33, 34, 35, 36},
new double[] {51, 52, 53, 54, 55, 56},
new double[] {21, 22, 23, 24, 25, 26},
new double[] {61, 62, 63, 64, 65, 66},
new double[] {71, 72, 73, 74, 75, 76},
};
double[][] fragment = individual
.OrderBy(line => line[line.GetUpperBound(0)]) // by last column
.Take(4)
.ToArray();
One more Linq to test the results:
String test = String.Join(Environment.NewLine, fragment
.Select(line => String.Join("\t", line)));
Console.Write(test);
The result is
11 12 13 14 15 16
21 22 23 24 25 26
31 32 33 34 35 36
41 42 43 44 45 46
If you use multidimensional arrays, there's no easy way to work with them using LINQ, you'll need to rely on good old for.
static void Main ()
{
// Input array
double[,] u = {
{ 1, 9, 3 },
{ 0, 3, 4 },
{ 3, 4, 5 },
{ 3, 6, 8 },
{ 3, 5, 7 },
};
// Get dimension sizes, specify column to order by
int count = u.GetLength(0), length = u.GetLength(1), orderBy = 2;
// Result array
double[,] v = new double[count, length];
// Construct a list of indices to sort by
var indices = Enumerable.Range(0, count).OrderBy(i => u[i, orderBy]).ToList();
// Copy values from input to output array, based on these indices
for (int i = 0; i < count; i++)
for (int j = 0; j < length; j++)
v[i, j] = u[indices[i], j];
PrintArray(u);
Console.WriteLine();
PrintArray(v);
}
static void PrintArray (double[,] a)
{
for (int i = 0; i < a.GetLength(0); i++) {
for (int j = 0; j < a.GetLength(1); j++)
Console.Write(a[i, j]);
Console.WriteLine();
}
}
If you need only top 4 rows, you can add Take(4) before ToList() call and adjust result array creation and copying of values into it appropriately.
Multidimenional arrays are more efficient and use less memory, so if your arrays are big enough or you need to work with them faster, you may need to write a little more code and use multidimenional arrays instead of jagged arrays which are easier to work with.
For rectangular array [,] you can copy the desired column in a single-dimensional array together with indices, sort it, and then get rows with first 4 indices.
static IEnumerable<Tuple<int, double>> GetColumn(int columnIndex, double[,] a)
{
for (int i = a.GetLowerBound(0); i <= a.GetUpperBound(0); i++)
yield return Tuple.Create(i, a[i, columnIndex]);
}
double [,] data = ...;
var column = GetColumn(4, data);
var top4Indices = column.OrderBy(v => v.Second)
.Take(4)
.Select(v => v.First);
foreach (int i in top4Indices)
for (int j = data.GetLowerBound(1); j <= data.GetUpperBound(1); j++)
data[i, j]...

Get the value of a specific array number in relation to a given value

I am trying to determine what the neighbour bets would be for a given number on a roulette wheel.
At the moment I pass a pocket number to a function and below is my code. "pocket_number()[0]" is the value of the number I want to determine the neighbours of.
int[] neightbourbets = neighbourbets(pocket_number()[0]);
neighbourbets() is as follows (this outputs an array of element numbers so elsewhere in my program I can extract them from the same array structure). At the moment I have a crude way of determining the the neighbour bets and getting the function to state which numbers are 6 numbers either side of it.
Is there a better way to do this? I've found one of the problems (that I've overcome with the below) is if I want to know the neighbours for "0" for example which means the code needs to get the numbers from the end of the array.
public int[] neighbourbets(int x)
{
int[] pocket_array = new[] {0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26};
int predictednum = Array.IndexOf(pocket_array,x); //element number of pocket_array for chosen number
int[] neighbourbets = new[] {0,0,0,0,0,0,0,0,0,0,0,0,0};
neighbourbets[0] = predictednum;
neighbourbets[1] = predictednum+1;
neighbourbets[2] = predictednum+2;
neighbourbets[3] = predictednum+3;
neighbourbets[4] = predictednum+4;
neighbourbets[5] = predictednum+5;
neighbourbets[6] = predictednum+6;
neighbourbets[7] = predictednum-1;
neighbourbets[8] = predictednum-2;
neighbourbets[9] = predictednum-3;
neighbourbets[10] = predictednum-4;
neighbourbets[11] = predictednum-5;
neighbourbets[12] = predictednum-6;
for (int i = 0; i < neighbourbets.Length; i++)
{
//clockwise neighours
if (neighbourbets[i] == -1) {
neighbourbets[i] = 36;
}
if (neighbourbets[i] == -2) {
neighbourbets[i] = 35;
}
if (neighbourbets[i] == -3) {
neighbourbets[i] = 34;
}
if (neighbourbets[i] == -4) {
neighbourbets[i] = 33;
}
if (neighbourbets[i] == -5) {
neighbourbets[i] = 32;
}
if (neighbourbets[i] == -6) {
neighbourbets[i] = 31;
}
//anticlockwise neighbours
if (neighbourbets[i] == 37) {
neighbourbets[i] = 0;
}
if (neighbourbets[i] == 38) {
neighbourbets[i] = 1;
}
if (neighbourbets[i] == 39) {
neighbourbets[i] = 2;
}
if (neighbourbets[i] == 40) {
neighbourbets[i] = 3;
}
if (neighbourbets[i] == 41) {
neighbourbets[i] = 4;
}
if (neighbourbets[i] == 42) {
neighbourbets[i] = 5;
}
}
return neighbourbets;
}
Any helps or guidence is appreciated! :)
Write a small helper function to wrap around the index:
private int GetPocketIndex( int start, int offset, int count )
{
int pos = ( start + offset ) % count;
if( pos >= 0 )
return pos;
else
return count + pos; // pos is negative so we use +
}
The modulus there will help it wrap around when it goes above the maximum, and the if will do it for the minimum. This could probably be done easier though, but it eludes me at the moment.
Then, if you need that specific order, perhaps something like this:
int[] offsets = new int[] { 0,
1, 2, 3, 4, 5, 6,
-1, -2, -3, -4, -5, -6 };
int[] neighbourbets = new int[offsets.Length];
for( int i = 0; i < offsets.Length; i++ )
neighbourbets[i] = GetPocketIndex( predictednum, offsets[i], pocket_array.Length );
Or, if any order will do:
int count = 6;
int[] neighbourbets = new int[count * 2 + 1];
for( int i = 0; i < neighbourbets.Length; i++ )
neightbourbets[i] = GetPocketIndex( predictednum, i - count, pocket_array.Length );
The following would give you the result with the x in the middle of the result array and the neighbours to the left and right of it:
public static int[] neighbourbets2(int x, int neighborCount)
{
int[] pocket_array = new[] { 0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26 };
int predictednum = Array.IndexOf(pocket_array, x);
// Initialize the result array. Its size is double the neighbour count + 1 for x
int[] result = new int[neighborCount * 2 + 1];
// Calc the start index. We begin at the most left item.
int startAt = predictednum - neighborCount;
// i - position in the result array
// j - position in the pocket_array
for (int i = 0, j = startAt; i < result.Length; i++, j++)
{
// Adjust j if it's less then 0 to wrap around the array.
result[i] = pocket_array[j < 0 ? j + pocket_array.Length : j];
// If we are at the end then start from the beginning.
if (j == pocket_array.Length)
{
j = 0;
}
}
return result;
}

Categories