how to compute a bitmap? - c#

I am looking for a way to get all combination of a list item.
what i thinking is to have a two dimention array, similary to a bit map
e.g bit[][] mybitmap;
for example if i have 4 item in my list "A, B, C, D"
i want my bitmap to be populate like this
A B C D
0, 0, 0, 1 --> D
0, 0, 1, 0 --> C
0, 0, 1, 1 --> C, D
0, 1, 0, 0 --> B
0, 1, 0, 1
0, 1, 1, 0
0, 1, 1, 1
1, 0, 0, 0
1, 0, 0, 1
1, 0, 1, 0
1, 0, 1, 1 --> A, C, D
1, 1, 0, 0
1, 1, 0, 1
1, 1, 1, 0
1, 1, 1, 1 --> A, B, C, D
but how can i write some C# code to populate my bit map?
(PS: my list might have items around 80 to 90, not 100 to 200, just confirmed)
Thanks

So... just count from 1 to 15 (=(2^n)-1), and write as binary, perhaps using shift operations.
This is sane for small numbers... but gets rather large quite quickly. For 64 items you can model in a long, but that is 18,446,744,073,709,551,615 combinations... hint: you are never, ever, ever going to loop that far.
For small cases:
int n = 4;
int max = 1 << n;
for (long val = 1; val < max; val++)
{
long mask = 1 << (n - 1);
for (int bit = 0; bit < n; bit++)
{
bool set = (val & mask) != 0;
Console.Write(set ? "1 " : "0 ");
mask >>= 1;
}
Console.WriteLine();
}

Agree with Marc Gravell. You cannot pretend to generate a list like the one you describe and then collect the elements you need.
I've been doing something similar, but I only needed a subset of all the combinations, so I was filtering my elements during the list generation process. This way, each recursive iteration (I was using F#) does not create the elements that I already know that will be discarded at the end.
With this approach I could perform variations of 200 elements and get the list of valid results (which I already knew it was going to be not so big...)
In case you are interested, the problem you are describing is a combinatory problem. There's a nice article in C# here

I believe you don't need to store all combinations in memory.
Just start from array with all zero bits (first combination). To get next combination just add 1 to last bit of previous combination (it is easily implementing operation). And so on.
Low memory usage, support of up to 2 billions of digits. :)
private void button1_Click(object sender, EventArgs e)
{
string[] items = {"A", "B", "C", "D"};
bool[] bits = new bool[items.Length];
for (int i = 0; i < bits.Length; i++)
{
bits[i] = false;
}
while (!bits.All(x => x))
{
listBox1.Items.Add(string.Join(", ", GetCombination(items, bits)));
AddBit(bits, bits.Length - 1);
}
}
public string[] GetCombination(string[] items, bool[] bits)
{
List<string> combination = new List<string>();
for (int i = 0; i < bits.Length; i++)
{
if (bits[i])
{
combination.Add(items[i]);
}
}
return combination.ToArray();
}
private void AddBit(bool[] bits, int pos)
{
if (pos < 0)
{
// overflow :)
return;
}
if (bits[pos])
{
bits[pos] = false;
AddBit(bits, pos - 1);
}
else
{
bits[pos] = true;
}
}

Related

How do I trace back the shortest path found in a Binary Matrix using a BFS algorithm

So I've implemented a BFS algorithm and I can successfully get the amount of steps it took in order to get from A -> B where A is the top left most coordinate, and B is the bottom left most coordinate.
In my Grid Binary Matrix I have 2 different values.
0 which is "Traversable".
1 which is "Non Traversable"
And in my Visited grid I also change values that I've visited to 2. I was going to try to use the 2 to show the path I took by looking up the coordinate of each value that was 2 but that would only show me everything that I've visited and not the shortest path.
Take this grid for instance
int[][] grid = new[]
{
new int[] { 0, 0, 0, 0},
new int[] { 1, 1, 0, 0},
new int[] { 1, 0, 0, 0},
new int[] { 1, 1, 0, 0}
};
There are two paths which can be built which are considered the shortest
Either way, the result is 5 which my implementation prints out.
I want to print out the actual path it found, for instance, if the algorithm were to take the path shows in the first image, it would print out 0,0 - 0,1 - 1,2 - 2,2 - 3,3.
I'm thinking that I need to keep track of the parent node every time I visit a node, in order to know where I came from, but I'm not sure how I would do that.
Here's my implementation
int[][] dirs = new[]
{
new[] { 0, 1 }, //Bottom
new[] { 1, 1 }, //Bottom right
new[] { 1, 0 }, //Right
new[] { 1, -1 }, //Top right
new[] { 0, -1 }, //Top
new[] { -1, -1 }, //Top left
new[] { -1, 0 }, //Left
new[] { -1, 1 } //Bottom left
};
public int BinaryMatrix(int[][] grid)
{
/* Length of the rows */
var rowLength = grid.Length;
/* The length of each col */
var colLength = grid[0].Length;
/* Can't find a path */
if (grid[0][0] == 1 || grid[rowLength - 1][colLength - 1] == 1)
return -1;
var Queue = new Queue<int[]>(); /* Coordinates */
/* Make a copy of the grid on order to update and perform checks without manipulating the original one. */
int[][] visited = new int[rowLength][];
for (int i = 0; i < visited.Length; i++)
visited[i] = new int[colLength];
Queue.Enqueue(new[] { 0, 0 });
visited[0][0] = 2;
int steps = 1;
while (Queue.Count != 0)
{
int levelSize = Queue.Count;
for (int r = 0; r < levelSize; r++)
{
int[] coord = Queue.Dequeue();
var cy = coord[0]; /* Y */
var cx = coord[1]; /* X */
/* If what we just popped has the same coordinates as the destination */
if (cy == rowLength - 1 && cx == colLength - 1)
{
/* Traceback */
return steps;
}
for (int i = 0; i < dirs.Length; i++)
{
int neighborY = dirs[i][0] + cy;
int neighborX = dirs[i][1] + cx;
/* Bounds check */
if (neighborX >= 0 && neighborX < colLength && neighborY >= 0 && neighborY < rowLength)
{
/* Visited check */
if (visited[neighborY][neighborX] == 0 && grid[neighborY][neighborX] == 0)
{
Queue.Enqueue(new[] { neighborY, neighborX });
visited[neighborY][neighborX] = 2;
}
}
}
}
/* Increment once we're done traversing through a level */
steps++;
}
return -1;
}
I would just use the "visited"-array to keep track of the source node. You could for example store visited[neighborY][neighborX] = i + 2 to keep track of the direction, and then traverse the tree in reverse to build a list of nodes.
Note that I would really recommend creating a Vector2i (i.e. a pair of int) data type to manage coordinates instead of arrays, that should give shorter and easier to understand code. I would also consider using multidimensional arrays, i.e. int[,] instead of jagged, int[][].
Another approach would be to use a Queue<(Vector2i Coordinate, Vector2i[] Path)> to store the paths explicitly. That would require more memory, but for small data sets the memory usage should be irrelevant.

Sort a sequence (a sub-array in a array) in decreasing order by their elements (elements in the sub-array of an array)

I have been trying for days to find a solution for this problem using c#. I was able to sort them by length but I cannot figure out the solution to sort the array by from their left-most to their right-most.
The hint they gave is to define a class Sequence to hold a sequence of elements. We will implement IComparable<Sequence> to compare sequences by length in decreasing order (and by elements in decreasing order when the length is the same). Later we will use our TreeMultiSet class. Inside we will keep the first 10 sub-sequences of S, i.e. multi-set of the lucky sub-sequences of P, kept in decreasing order by length (and in decreasing order of their content when the length is the same). When we have 10 sub-sequences inside the multi-set and we add 11th sequence, it would take its correct place in the order, because of the IComparable<Sequence> defined. After that we can delete the 11th subsequence, because it is not amongst the first 10
Here is the problem:
We are given a sequence P containing L integers L (1 < L < 50,000) and a number N. We call a “lucky sub-sequence within P” every subsequence of integers from P with a sum equal to N. Imagine we have a sequence S, holding all the lucky sub-sequences of P, kept in decreasing order by their length. When the length is the same, the sequences are ordered in decreasing order by their elements: from the leftmost to the rightmost. Write a program to return the first 10 elements of S
Example: We are given N = 5 and the sequence P = {1, 1, 2, 1, -1, 2, 3, -1, 1, 2, 3, 5, 1, -1, 2, 3}. The sequence S consists of the following 13 sub-sequences of P:
[1, -1, 2, 3, -1, 1]
[1, 2, 1, -1, 2]
[3, -1, 1, 2]
[2, 3, -1, 1]
[1, 1, 2, 1]
[1, -1, 2, 3]
[1, -1, 2, 3]
[-1, 1, 2, 3]
[5, 1, -1]
[2, 3]
[2, 3]
[2, 3]
[5]
My solution:
Actually, when reading the hint I was not able to understand the idea so I came up with another way.
class Find
{
//Function to manually create an array with N elements
public static int[] ArrCreate(int n, int[] Arr)
{
for (int i = 0; i < n; i++)
{
Arr[i] = Convert.ToInt32(Console.ReadLine());
}
return Arr;
}
//Create a Dictionary class type to hold sub-array with sum of sub-array equal to given number k
public static Dictionary<int, ArrayList> SubSeqEqual2N()
{
Console.WriteLine("Input k: ");
int k = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Input n element to create an Array: ");
int n = Convert.ToInt32(Console.ReadLine());
int[] Arr = new int[n];
int[] newArr = ArrCreate(n, Arr);
int keyIndex = 0;
//ArrayList arlist = new ArrayList();
Dictionary<int, ArrayList> SeqofLuckyArr = new Dictionary<int, ArrayList> { };
//Create a loop to find sub-array with the sum equal to given number K.
for (int i = 0; i < newArr.Length; i++)
{
int sum = 0;
for (int j = i; j < newArr.Length; j++)
{
sum = sum + newArr[j];
if (sum == k)
{
//When sub-array with the sum equal to given number K is found then add them into a temp Arraylist, also increment the keyIndex.
keyIndex++;
ArrayList temp = new ArrayList();
for (int ko = i; ko <= j; ko++)
{
temp.Add(newArr[ko]);
}
//DEBUG PURPOSE
/*Console.Write("{");
foreach (var hehe in temp)
{
Console.Write("{0}", string.Join(", ", hehe));
}
Console.Write("}");
Console.WriteLine("");
arlist.AddRange(temp);*/
//Then add that temp array as value into a Dictionary <key,value>type with that KeyIndex.
SeqofLuckyArr.Add(keyIndex,temp);
}
}
}
//DEBUG PURPOSE
//My method to sort the sub-array in the Dictionary by sub-array length and by key index.
foreach(KeyValuePair<int,ArrayList> kvp in SeqofLuckyArr.OrderByDescending(x => x.Value.Count).ThenBy(y => y.Key))
{
Console.Write("Key={0} ",kvp.Key);
Console.Write(",");
Console.Write("Value={ ");
foreach (var hoho in kvp.Value)
{
Console.Write("{0} ", string.Join(", ", hoho));
}
Console.WriteLine("}");
Console.WriteLine("");
arlist.AddRange(kvp.Value);
}
//DEBUG PURPOSE
return SeqofLuckyArr;
}
}
I try to find the sub-array with the sum equal to the given number K first then add them into the Dictionary as value with its key as index. Then sort -sub-array by length use OrderByDecreasing method.
The result:
Key=4 ,Value={ 1 -1 2 3 -1 1 }
Key=2 ,Value={ 1 2 1 -1 2 }
Key=1 ,Value={ 1 1 2 1 }
Key=3 ,Value={ 1 -1 2 3 }
Key=6 ,Value={ 2 3 -1 1 }
Key=7 ,Value={ 3 -1 1 2 }
Key=8 ,Value={ -1 1 2 3 }
Key=12 ,Value={ 1 -1 2 3 }
Key=11 ,Value={ 5 1 -1 }
Key=5 ,Value={ 2 3 }
Key=9 ,Value={ 2 3 }
Key=13 ,Value={ 2 3 }
Key=10 ,Value={ 5 }
But the result is not the same as the example. My problem is that I am stuck at "When the length is the same, the sequences are ordered in decreasing order by their elements: from the leftmost to the rightmost". As I thought left-most to right most is the key index of the sub-array from low to high.
Can anyone help me to find the appropriate way to order the sub-array in decreasing order by the elements? If my edition is not also appropriate to ask on SO I will delete my question.
Thank you!
It seems the problem lies solely in your ordering. The contents of the sequences are identical to the example.
First, the line you are ordering doesn't quite follow the rules specified:
foreach(KeyValuePair<int,ArrayList> kvp in SeqofLuckyArr
.OrderByDescending(x => x.Value.Count)
.ThenBy(y => y.Key))
[...] kept in decreasing order by their length. When the length is the same, the sequences are ordered in decreasing order by their elements: [...]
The first ordering seems correct (OrderByDescending(x => x.Value.Count)) by descending order of the sequences' length. The second ordering is currently ordered by the sequences' "key index" and in ascending order. This should have been in descending/decreasing (ThenByDescending) order based on the contents of the "lucky sub-sequences".
One way you can fix all this is by introducing an IComparer implementation a bit similar to the hint given. The IComparer below is able to take two sequences (int[]) as input and tell which of the two should come before the other (see the documentation for an explanation of what the return value of IComparer.Compare means):
public class IntArrayComparer : IComparer<int[]>
{
public int Compare(int[] x, int[] y)
{
// Ensure we don't get a null-ref exception further down
if (x == null || y == null)
// x should come before (-1) or after (1) y (default ascending order)
return y == null ? -1 : 1;
// If the lengths are different, the length is the first ordering priority
if (x.Length != y.Length)
// Use the built-in 'CompareTo' method for the 'int' type
return x.Length.CompareTo(y.Length);
// Lengths are the same, so we compare the contents
for (var i = 0; i < x.Length; i++)
{
var comparison = x[i].CompareTo(y[i]);
// If the elements in the two seq. are different, we return the ordering
if (comparison != 0)
return comparison;
}
return 0;
}
}
Now the previous mentioned line with your ordering becomes a little simpler (subjective opinion :)):
foreach(KeyValuePair<int,ArrayList> kvp in SeqofLuckyArr
.OrderByDescending(x => x.Value, new IntArrayComparer()))
Check out this fiddle for a test run of the ordering part.
Hint: You actually don't even need to store your subsequences in a Dictionary - a List would suffice.
Sorry for late response. After referring the Imcomparer implementation above. I was able to get the output the same as example. Here is my code for anyone facing the same issues as me.
class Find
{
public static int[] ArrCreate(int n, int[] Arr)
{
for (int i = 0; i < n; i++)
{
Arr[i] = Convert.ToInt32(Console.ReadLine());
}
return Arr;
}
public static void SubSeqEqual2N()
{
Console.WriteLine("Input k: ");
int k = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Input n element to create an Array: ");
int n = Convert.ToInt32(Console.ReadLine());
int[] Arr = new int[n];
int[] newArr = ArrCreate(n, Arr);
//int keyIndex = 0;
//ArrayList arlist = new ArrayList();
//Dictionary<int, ArrayList> SeqofLuckyArr = new Dictionary<int, ArrayList> { };
//Create a List of int array to store
List<int[]> luckyArray = new List<int[]>{ };
for (int i = 0; i < newArr.Length; i++)
{
int sum = 0;
for (int j = i; j < newArr.Length; j++)
{
sum = sum + newArr[j];
if (sum == k)
{
//keyIndex++;
ArrayList temp = new ArrayList();
for (int ko = i; ko <= j; ko++)
{
temp.Add(newArr[ko]);
}
//Convert ArrayList temp into int array for applying IComparer.Compare<Int[],Int[]>
int[] luckySubArray = temp.ToArray(typeof(int)) as int[];
luckyArray.Add(luckySubArray);
//SeqofLuckyArr.Add(keyIndex,temp);
}
}
}
var orderedSeq = luckyArray.OrderByDescending(s => s, new IntArrayComparer());
foreach(var seq in orderedSeq)
{
Console.Write("[ ");
foreach (var i in seq)
{
Console.Write("{0} ", string.Join(", ", i));
}
Console.Write(" ]");
Console.WriteLine("");
}
}
}
public class IntArrayComparer : IComparer<int[]>
{
public int Compare(int[] x, int[] y)
{
// Ensure we don't get a null-ref exception further down
if (x == null || y == null)
// x should come before (-1) or after (1) y (default ascending order)
return y == null ? -1 : 1;
// If the lengths are different, the length is the first ordering priority
if (x.Length != y.Length)
// Use the built-in 'CompareTo' method for the 'int' type
return x.Length.CompareTo(y.Length);
// Lengths are the same, so we compare the contents
for (var i = 0; i < x.Length; i++)
{
var comparison = x[i].CompareTo(y[i]);
// If the elements in the two seq. are different, we return the ordering
if (comparison != 0)
return comparison;
}
return 0;
}
}
And the output:
[ 1 -1 2 3 -1 1 ]
[ 1 2 1 -1 2 ]
[ 3 -1 1 2 ]
[ 2 3 -1 1 ]
[ 1 1 2 1 ]
[ 1 -1 2 3 ]
[ 1 -1 2 3 ]
[ -1 1 2 3 ]
[ 5 1 -1 ]
[ 2 3 ]
[ 2 3 ]
[ 2 3 ]
[ 5 ]

LeetCode: Prison Cells After N Days

Stack, I can't quite wrap my head around this oddity. I'm evaluating the positions within the array, each time. How is it that by initializing the array each time I receive different results... I would appreciate if someone can explain this.
In While Loop: Correct
0,1,0,1,1,0,0,1
0,1,1,0,0,0,0,0
0,0,0,0,1,1,1,0
0,1,1,0,0,1,0,0
0,0,0,0,0,1,0,0
0,1,1,1,0,1,0,0
0,0,1,0,1,1,0,0
0,0,1,1,0,0,0,0
Outside While Loop (Initialized Once): Incorrect
0,1,0,1,1,0,0,1
0,1,1,0,0,0,0,0
0,0,1,0,1,0,1,0
0,0,1,1,0,0,1,0
0,0,0,1,0,0,1,0
0,1,1,0,1,1,0,0
0,0,1,1,1,0,1,0
0,0,0,0,1,1,0,0
Question Details
There are 8 prison cells in a row, and each cell is either occupied or vacant.
Each day, whether the cell is occupied or vacant changes according to the following rules:
If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied.
Otherwise, it becomes vacant.
(Note that because the prison is a row, the first and the last cells in the row can't have two adjacent neighbors.)
We describe the current state of the prison in the following way: cells[i] == 1 if the i-th cell is occupied, else cells[i] == 0.
Given the initial state of the prison, return the state of the prison after N days (and N such changes described above.)
Example 1: Expected Output
Input: cells = [0,1,0,1,1,0,0,1], N = 7
Output: [0,0,1,1,0,0,0,0]
Explanation:
The following table summarizes the state of the prison on each day:
Day 0: [0, 1, 0, 1, 1, 0, 0, 1]
Day 1: [0, 1, 1, 0, 0, 0, 0, 0]
Day 2: [0, 0, 0, 0, 1, 1, 1, 0]
Day 3: [0, 1, 1, 0, 0, 1, 0, 0]
Day 4: [0, 0, 0, 0, 0, 1, 0, 0]
Day 5: [0, 1, 1, 1, 0, 1, 0, 0]
Day 6: [0, 0, 1, 0, 1, 1, 0, 0]
Day 7: [0, 0, 1, 1, 0, 0, 0, 0]
Method
static public int[] PrisonAfterNDays(int[] cells, int N)
{
int counter = 0;
//Doesn't work if it's here
//int[] temp = new int[8];
while(counter < N)
{
Console.WriteLine(String.Join(",",cells));
//Works if it's here ?!?!?!
int[] temp = new int[8];
for(int j = 1; j < 8-1; j++)
{
if(cells[j-1] == cells[j+1])
{
temp[j] = 1;
}
else
{
temp[j] = 0;
}
}
cells = temp;
counter++;
}
return cells;
}
Remember that even though int is a value type, arrays are reference types, so int[] is a reference type. (See What is the difference between a reference type and value type in c#?)
When you execute cells = temp;, you point cells and temp at the exact same array! You can test this with the following code:
int[] a = new int[2];
int[] b = a;
b[0] = 85;
b[1] = 3;
Console.WriteLine(a[0]); // prints 85
Console.WriteLine(a[1]); // prints 3
So this means that on the second iteration of the outer loop, the following code changes both cells[j] and temp[j]:
temp[j] = 1;
Which, clearly, means you will get strange results.
For this reason, I'd argue that you should define temp within the loop.
class Solution:
def prisonAfterNDays(self, states: List[int], n: int) -> List[int]:
# Since we have 6 cells moving cells (two wil remain unchaged at anytime)
# the cycle will restart after 14 iteration
# 1- The number of days if smaller than 14 -> you brute force O(13)
# 2- The number is bigger than 14
# - You do a first round of 14 iteration
# - Than you do a second round of n%14 iteration
# ===> O(27)
if n < 14:
# iif n
for _ in range(n):
states = self.getNewStates(states)
else:
for _ in range(14):
states = self.getNewStates(states)
for _ in range(n%14):
states = self.getNewStates(states)
return states
def getNewStates(self, states: List[int]) -> List[int]:
newStates = ["0"] * len(states)
for i in range(1, len(states)):
if i != 0 and i != len(states) - 1 and states[i-1] == states[i+1]:
newStates[i] = "1"
return newStates

How do I exclude the zeros from outputting in my array?

I have this code. I would like to only display the parts of the array that are greater than 0.
For example... A bunch of numbers are entered and stored as a variable. But not all of the variables in the array will be used. The ones that aren't are stored as 0. So when I display the array, the numbers are displayed as:
"140, 180, 298, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " etc.
I don't want the zeros to be displayed.
int[] scores = {score1, score2, score3, score4, score5, score6, score7, score8, score9, score10, score11, score12, score13, score14, score15};
Console.WriteLine("Your scores as you entered them: " + (string.Join(", ", scores)));
Console.ReadKey();
Use linq's Where:
string.Join(", ", scores.Where(x => x != 0))
In the description above you also said the parts of the array that are greater than 0. So if that is the case you can change it to:
string.Join(", ", scores.Where(x => x > 0))
For a non linq solution use a List<int> and a simple foreach (or for) loop:
List<int> result = new List<int>();
foreach(int item in scores)
{
if(item != 0)
result.Add(item);
}
If you don't understand LINQ yet, you can look into this piece of code:
int[] scores = { 1, 2, 3, 0, 0, 4, 5, 0, 0, 6};
int[] withoutZeros = WithoutZeros (scores);
And the core method:
public static int[] WithoutZeros (int[] input)
{
int zerosCount = 0; // we need to count how many zeros are in the input array
for (int i = 0; i < input.Length; i++)
{
if (input[i] == 0) zerosCount = zerosCount + 1;
}
// now we know number of zeros, so we can create output array
// which will be smaller than then input array (or not, if we don't have any zeros in the input array)
int[] output = new int[input.Length - zerosCount]; // can be smaller, equal, or even empty
// no we need to populate non-zero values from the input array to the output array
int indexInOutputArray = 0;
for (int i = 0; i < input.Length; i++)
{
if (input[i] != 0)
{
output[indexInOutputArray] = input[i];
indexInOutputArray = indexInOutputArray + 1;
}
}
return output;
}
To get the answer of your question have a look at Gilad Green's answer.
I just wanted to give you a little feedback about the code I see.
Since, I dont see all your code I am making a lot of assumptions here, so sorry if I am wrong.
If you want to fill an array with 15 values, you should consider refactoring your code to use a loop.
In the following example I will use a for loop but it could be solved with different loops.
int[] scores = new int[15]; //initialize an array of ints with a length of 15
for (int i = 0; i < scores.Length; i++) //loop from 0 till smaller than the length of the array (0-14 = 15 iterations)
scores[i] = int.Parse(Console.ReadLine()); //fill the scores array with the index of i with the console input

How to shift one array element wrap around?

I am trying to write a function which iterates through an array and when it finds a certain type of value it will shift it to the right a defined number of places.
I know how to shift elements by temporarily storing a value, shifting the right side elements to the left and then writing the temporary value in the correct place.
The bit I am struggling with is if the certain character appears near the end of the array I need it to wrap around and continue from the start of the array, so is circular.
So an array shifting, for example, capital letters to the right 3 places and special characters to the left 1 place:
{ M, y, N, a, m, e, P} becomes...
{ y, M, P, a, N, m, e}
To shift an element of 8 to the right 3 places I have below, but this only works if 8 appears earlier than 3 elements from the end of the array and will not wrap around.
input array:
{0, 1, 2, 3, 4, 5, 6, 7, **8**, 9}
desired output:
{0, **8**, 1, 2, 3, 4, 5, 6, 7, 9}
int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = array.Length - 1; i >= 0; i--)
{
if (array[i] == 8)
{
int temp = array[i];
int j = 0;
for (j = i; j < i + 3; j++)
{
array[j] = array[j + 1];
}
array[j] = temp;
}
}
Just use modulo arithmetic so that instead of writing to the element at index j as you shift, instead write to the element at index j % array.Length. Thusly:
public void FindAndShift<T>(T[] array, T value, int shift) {
int index = Array.IndexOf(array, value);
int shiftsRemaining = shift;
for(int currentPosition = index; shiftsRemaining > 0; shiftsRemaining--) {
array[currentPosition % array.Length] = array[(currentPosition + 1) % array.Length];
}
array[(index + shift) % array.Length] = value;
}
I have excluded error checking.
You can do it with an if statement, check if there is room enough before the end of the array and if it isn't you have to calculate how many steps to shift in the beginning of the array aswell.
I also think that you can do it by calculating the positions modulo the length of the array when you do the shifting, I can't try it at the moment but the logic in my head says that it should work.

Categories