shifting array elements to right? - c#

I can't use a built-in function for this, I must use my own logic.
I've done element shifting to the left side, but the right side doesn't work for me. Not sure why.
My method for left:
public int[] shiftLeft(int[] arr) {
int[] demo = new int[arr.length];
int index = 0;
for (int i = 0; i < arr.length - 1; i++) {
demo[index] = arr[i + 1];
index++;
}
return demo;
}
and my attempt for the right shifting:
public int[] shiftRight(int[] arr) {
int[] demo = new int[arr.length];
int index = 0;
for (int i = arr.length - 1; i >= 0; i--) {
demo[index] = arr[(i - 1 > 0) ? i - 1 : 0];
index++;
}
return demo;
}
What am I doing wrong?
By shifting I mean:
you have an array, 1 2 3 4 5 6
Shifting it to left by one: 2 3 4 5 6 1
Shifting it to right by one: 6 1 2 3 4 5

//right shift with modulus
for (int i = 0; i < arr.length; i++) {
demo[(i+1) % demo.length] = arr[i];
}

The easiest way to go:
public int[] shiftLeft(int[] arr)
{
int[] demo = new int[arr.Length];
for (int i = 0; i < arr.Length - 1; i++)
{
demo[i] = arr[i + 1];
}
demo[demo.Length - 1] = arr[0];
return demo;
}
public int[] shiftRight(int[] arr)
{
int[] demo = new int[arr.Length];
for (int i = 1; i < arr.Length; i++)
{
demo[i] = arr[i - 1];
}
demo[0] = arr[demo.Length - 1];
return demo;
}

LINQ solution, just to add some diversity.
static int[] LeftShift(int[] array)
{
// all elements except for the first one... and at the end, the first one. to array.
return array.Skip(1).Concat(array.Take(1)).ToArray();
}
static int[] RightShift(int[] array)
{
// the last element (because we're skipping all but one)... then all but the last one.
return array.Skip(array.Length - 1).Concat(array.Take(array.Length - 1)).ToArray();
}
Probably not recommended if performance matters (for large arrays).
I realize that the OP is not supposed to use a "built-in function".

public static int[] shiftRight(int[] arr){
int[] demo = new int[arr.Length];
for (int i = 0; i <= arr.Length - 2; i++)
{
demo[i + 1] = arr[i];
}
demo[0] = arr[arr.Length - 1];
return demo;
}

The problem here is that you need to special case the left shift of the first element. For every element but the first the new index of the value will be oldIndex - 1. This is essentially what the loop is doing. However the first element has a new index of oldLength - 1. This needs to be special cased somewhere in the code base.

Try this,
public int[] ShiftRight(int[] arr)
{
int[] demo = new int[arr.Length];
for (int i = 0; i < arr.Length; i++) {
demo[i] = arr[i == 0 ? (arr.Length - 1) : (i - 1)];
}
return demo;
}

Use Arra.Copy...
public int[] shiftLeft(int[] arr) {
var result = new int[arr.Length];
Array.Copy(arr, 1, result, 0, arr.Length - 1);
result[arr.Length - 1] = arr[0];
return result;
}
public int[] shiftRight(int[] arr) {
var result = new int[arr.Length];
Array.Copy(arr, 0, result, 1, arr.Length - 1);
result[0] = arr[arr.Length - 1];
return result;
}

Usually I use this code. You can rewrites to the array extension method.
public static T[] Shift<T>(T[] array, int shiftValue)
{
var newArray = new T[array.Length];
shiftValue -= array.Length;
if(shiftValue < 0)
{
shiftValue*=-1;
}
for(var i=0; i<array.Length; i++)
{
var index = (i + shiftValue) % array.Length;
newArray[i] = array[index];
}
return newArray;
}

maybe this works for anyone seeing this post :
private int[] shiftLinear(int[] linArray, int shift){
int length = linArray.Length;
int[] shifted = new int[length];
shift = shift % length;
if (shift >= 0) {
for (int n = shift ; n < length; n++) shifted[n] = linArray[n-shift];
if (shift != 0) for (int n = 0; n < shift; n++) shifted[n] = linArray[length-1-n];
} else {
for (int n = 0 ; n < length+shift; n++) shifted[n] = linArray[n-shift];
for (int n = length+shift; n < length ; n++) shifted[n] = linArray[n-length-shift];
}
return shifted;
}

Without using external array;
public static int[] right(int[] A)
{
var tempo = A[0];
for(var i=0; i<A.Length-1; i++)
{
var yolo = A[i + 1];
A[i + 1] = tempo;
tempo = yolo;
}
A[0] = tempo;
return A;
}
public static int[] left(int[] A)
{
var tempo = A[A.Length - 1];
for (var i = A.Length - 1; i >0; i--)
{
var yolo = A[i - 1];
A[i -1] = tempo;
tempo = yolo;
}
A[A.Length - 1] = tempo;
return A;
}

public int[] shiftRight(int[] arr)
{
int[] demo = new int[arr.length];
Array.Copy(arr,arr.Length-1,demo,0,1); // Copy last position to first
Array.Copy(arr,0,demo,1,arr.Length-1); // Copy the rest shifted one
return demo;
}

Related

ArrayIndexOutOfBounds exception in hackerrank Cut the sticks

I am trying to implement a problem in Hackerrank Cut the sticks. Problem can be found here
my code is this
static int[] cutTheSticks(int[] arr)
{
int n = arr.Length, k = 0;
int[] result = new int[n];
Array.Sort(arr);
Array.Reverse(arr);
while(arr.Length != 0)
{
result[k] = arr.Length;
k++;
for(int i = 0; i < n; ++i)
{
arr[i] -= arr[arr.Length - 1];
}
}
return result;
}
it shows error as-
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Solution.cutTheSticks (System.Int32[] arr) [0x00020] in solution.cs:24
line 24 is:
result[k] = arr.Length;
How to remove this?
There are several problems with your code. To name a few:
You are giving the result array a fixed size (int[] result=new int[n];), but it's size depends entirely on how many duplicate values are contained in the list.
You are supposed to remove from the array the smallest value(s) in each iteration. However you are just modifying the values (arr[i] -= arr[arr.Length - 1];), not removing them, so the array length will remain the same, and thus while (arr.Length != 0) will always be true, creating an endless loop. This causes k++ to keep incrementing until it reaches a value greater than the array length, which then results in the exception you are getting.
Since you are supposed to change the size of the input array, I suggest using List<int> instead, here's an example:
List<int> output = new List<int>();
List<int> input = new List<int>(arr);
while (input.Count > 0)
{
output.Add(input.Count);
int min = input.Min();
input.RemoveAll(x => x == min);
input.ForEach(x => x -= min);
}
return output.ToArray();
It is necessary to add condition k < n before assigning value to avoid IndexOutOfRangeException exception. In addition, there is a strong need a condition to avoid infinite while loop :
static int[] cutTheSticks(int[] arr) {
int n = arr.Length,
k = 0;
int[] result = new int[n];
Array.Sort(arr);
Array.Reverse(arr);
while (arr.Length != 0)
{
if (k < n)
result[k] = arr.Length;
else
break;
k++;
for (int i = 0; i < n; ++i)
{
arr[i] -= arr[arr.Length - 1];
}
}
return result;
}
UPDATE:
It is possible to pop out one element after every iteration like this:
static int[] cutTheSticks(int[] arr)
{
int n = arr.Length,
k = 0;
int[] result = new int[n];
var arrToBeRemoved = arr.ToList();
Array.Sort(arr);
Array.Reverse(arr);
while (arr.Length != 0)
{
if (k < n)
result[k] = arr.Length;
else
break;
if (k < arrToBeRemoved.Count)
arrToBeRemoved.RemoveAt(k);
arr = arrToBeRemoved.ToArray();
k++;
for (int i = 0; i < arr.Length; ++i)
{
arr[i] -= arr[arr.Length - 1];
}
}
return result;
}
I would do it that way:
static int[] cutTheSticks(int[] arr)
{
List<int> results = new List<int>();
int cutted = 0;
while (cutted != 1)
{
cutted = 0;
int min = GetMin(arr);
if (min == 0)
{
break;
}
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] >= min)
{
arr[i] -= min;
cutted++;
}
}
results.Add(cutted);
}
return results.ToArray();
}
static int GetMin(int[] arr)
{
int min = int.MaxValue;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] != 0 && arr[i] < min)
{
min = arr[i];
}
}
return min;
}

"rotate" values in array clockwise

Firstly thank you for taking the time to look at my question.
I have a csv file of letters for which i need to get the last letter of the array and move it to the start while "pushing" the other letters across
E.G.
--Source--
a,b,c,d,[e]
--Rotated--
e,a,b,c,d
for (var i = 0; i < Array.Length - 1; i++)
{
temp = Array[Array.Length];
Array[Array.Length] = Array[Array.Length - 1];
Array[i + 1] = Array[i];
Array[i] = temp;
}
For this I am aware that not all characters would be effected but i cant think of a loop to get all values moved
Use Copy method:
int last = arr[arr.Length - 1];
Array.Copy(arr, 0, arr, 1, arr.Length - 1);
arr[0] = last;
You can shift the numbers to right by using the modulo % operator :
int[] arr = { 1, 2, 3, 4, 5 };
int[] newArr = new int[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
newArr[(i + 1) % newArr.Length] = arr[i];
}
newArr = {5,1,2,3,4}
DEMO HERE
EDIT:
Or you could make a method that shifts the numbers in your initial array without the need for creating a new array. The method rightShiftArray takes two parameters, the initial array arr an the number of shifts (shift) you want to perform:
public void rightShiftArray(ref int[] arr, int shift)
{
for (int i = 0; i < shift; i++)
{
int temp;
for (int j = 0; j < arr.Length - 1; j++)
{
temp = arr[j];
arr[j] = arr[arr.Length - 1];
arr[arr.Length - 1] = temp;
}
}
}
For example:
int[] arr = { 1, 2, 3, 4, 5 };
rightShiftArray(ref arr, 2);
The code above shifts the numbers in the initial array arr twice to the right and gives you the following output:
arr = { 4, 5, 1, 2, 3};
DEMO HERE
if you doesn't want to allocate new array, you can use this code :
newValue = Array[Array.Length-1];
for (var i = 0; i < Array.Length; i++)
{
temp = Array[i];
Array[i] = newValue;
newValue = temp;
}

Digit difference sort

So I am trying to solve this task "Digit Difference Sort" on Codefights
Given an array of integers, sort its elements by the difference of their largest and smallest digits.
In the case of a tie, that with the larger index in the array should come first.
Example
For a = [152, 23, 7, 887, 243], the output should be digitDifferenceSort(a) = [7, 887, 23, 243, 152].
Here are the differences of all the numbers:
152: difference = 5 - 1 = 4;
23: difference = 3 - 2 = 1;
7: difference = 7 - 7 = 0;
887: difference = 8 - 7 = 1;
243: difference = 4 - 2 = 2.
23 and 887 have the same difference, but 887 goes after 23 in a, so in the sorted array it comes first.
I have an issue with two numbers having the same difference. Here's what I wrote so far:
int[] digitDifferenceSort(int[] a) {
return a.OrderBy(x => difference(x)).ToArray();
}
int difference(int x)
{
int min = 9, max = 0;
do
{
int tmp = x % 10;
min = Math.Min(min, tmp);
max = Math.Max(max, tmp);
} while ((x /= 10) > 0);
return max - min;
}
Didn't do much (for example the output is still [7, 23, 887, 243, 152] rather than [7, 887, 23, 243, 152])
How do I make element with larger index come first in result? What should I use instead of OrderBy?
I don't consider your difference method, i assume it works fine.
To your question: you have to keep revered order of the array (that the items with the same difference arrive will be sorted reverse). To do it, you could just reverse you input array: all items with not identical difference will be ordered correctly, and with the same differece will be ordered reversed:
int[] digitDifferenceSort(int[] a)
{
return a.Reverse().OrderBy(x => difference(x)).ToArray();
}
Following is my code for the above question digit difference sort. I am also getting output when running in Eclipse but when I paste the code on code signal it gives me a null pointer exception.
package NormalPrograms;
import java.util.ArrayList;
import java.util.Collections;
public class DigitDifferenceSort {
// For index wise sorting in descending order
public static int[] sortingnumberindexwise(int[] a, ArrayList<Integer> index) {
int k = 0;
int[] res = new int[index.size()];
int[] finalres = new int[index.size()];
for (int i = a.length - 1; i >= 0; i--) {
for (int j = 0; j < index.size(); j++) {
if (a[i] == (int) index.get(j)) {
res[k] = i;
index.remove(j);
k++;
break;
}
}
}
int g = 0;
k = 0;
for (int i = 0; i < res.length; i++) {
finalres[g] = a[res[k]];
g++;
k++;
}
return finalres;
}
public static int[] finddigitDifferenceandSort(int[] p) {
int[] finres = new int[p.length];
for (int i = 0; i < finres.length; i++) {
finres[i] = p[i];
}
// This finres array act as an temp array and reused to make final result array
int digit = 0;
ArrayList<Integer> A = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> B = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) {
B.add(new ArrayList<Integer>());
}
for (int i = 0; i < p.length; i++) {
int temp = 0;
temp = p[i];
while (p[i] > 0) {
digit = p[i] % 10;
p[i] /= 10;
A.add(digit);
}
int b = Collections.max(A);
int c = Collections.min(A);
int diff = b - c;
B.get(diff).add(temp);
A.clear();
}
for (int i = 0; i < B.size(); i++) {
if (B.get(i).size() > 1) {
ArrayList<Integer> C = new ArrayList<Integer>();
for (int k = 0; k < B.get(i).size(); k++) {
C.add(B.get(i).get(k));
}
B.get(i).clear();
for (int j : sortingnumberindexwise(finres, C)) {
B.get(i).add(j);
}
} else {
continue;
}
}
int k = 0;
for (int i = 0; i < B.size(); i++) {
for (int j = 0; j < B.get(i).size(); j++) {
if (B.get(i).size() == 0)
continue;
else {
finres[k] = B.get(i).get(j);
k++;
}
}
}
return finres;
}
public static void main(String[] args) {
int[] a = { 12, 21, 1, 1, 1, 2, 2, 3 };
for (int i : finddigitDifferenceandSort(a)) {
System.out.print(i + " ");
}
}
}

Arranging values of array in Ascending order

I couldn't get it to work, I am trying to arrange the values of the array in ascending order by using for loop.
int[] arr = new int[5] { 5, 6, 2, 4, 1 };
for (int i = 0; i <= arr.Length; i++)
{
if (arr[i] > arr[i + 1])
{
int temp = arr[i + 1];
arr[i] = arr[i + 1];
arr[i] = temp;
}
Console.Write(arr[i]);
}
I am assuming that you are not using Array.Sort because you are doing this as a learning exercise; there is no other way to avoid this very common library function.
The reason your algorithm does not work is that it is not enough to go through an array once, and swap items that are out of order. Try doing this as a mental experiment, when the array is almost sorted, but the first element is at the end, like this:
2 3 4 5 6 7 1
A single path would bring you closer, but it wouldn't bring you all the way to a sorted array:
2 3 4 5 6 1 7
As you can see, you have to repeat this process multiple times, until the array is sorted. How do you know that the array is sorted? You know that when the entire inner loop did not have a single swap.
Here is how you can implement this:
bool didSwap;
do {
didSwap = false;
for (int i = 0; i < arr.Length-1; i++)
{
if (arr[i] > arr[i + 1])
{
int temp = arr[i + 1];
arr[i + 1] = arr[i];
arr[i] = temp;
didSwap = true;
}
}
} while (didSwap);
for (int i = 0; i != arr.Length ; i++) {
Console.Write(arr[i]);
}
Note several changes from your code:
The printing is done in the separate loop, after the sorting is complete
The loop goes to arr.length-1, not to arr.length, because otherwise your last check will go outside the bounds of the array.
This sorting algorithm is called Bubble Sort. There are various optimizations to this algorithm that can make it go slightly faster.
In general, bubble sort is among the slower sorting algorithms. When the number of items to sort is high, you should consider an advanced algorithm, or use the library implementation.
int[] Array = { 11, 33, 5, -3, 19, 8, 49 };
int temp;
for (int i = 0; i < Array.Length - 1; i++)
{
for (int j = i + 1; j < Array.Length; j++)
{
if (Array[i] > Array[j])
{
temp = Array[i];
Array[i] = Array[j];
Array[j] = temp;
}
}
}
Console.Write("Sorted:");
foreach (int sort in Array)
Console.Write("{0} ", sort);
If you want to make your own sorting, then it's not enough to just loop through the items once and swap them. The closest to that is the bubble sort algorithm, where you loop over the array repeatedly until there is no more items to swap:
int[] arr = new int[5] { 5, 6, 2, 4, 1 };
bool swapped = true;
while (swapped) {
swapped = false;
for (int i = 0; i < arr.Length - 1; i++) {
if (arr[i] > arr[i + 1]) {
swapped = true;
int temp = arr[i + 1];
arr[i] = arr[i + 1];
arr[i] = temp;
}
}
}
for (int i = 0; i < arr.Length - 1; i++) {
Console.Write(arr[i]);
}
There are also built in methods to sort data, which is easier to use, more efficient, and already thoroughly tested:
int[] arr = new int[5] { 5, 6, 2, 4, 1 };
Array.Sort(arr);
Use Linq Order by:
int[] arr = new int[5] { 5, 6, 2, 4, 1 };
int[] ascOrderedArray = (from i in arr orderby i ascending select i).ToArray();
I think it could be easy and why do you need for loop.
using System;
namespace bubble_sort
{
class Program
{
static void Main(string[] args)
{
Program p = new Program();
int[] arr = new int[50];
int n;
Console.WriteLine("Enter no of elements you want to store in an array");
n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter elements in an array");
for (int i = 1; i <= n; i++)
{
arr[i] = Convert.ToInt32(Console.ReadLine());
}
p.bubblesort(arr, n);
Console.ReadKey();
}
public void bubblesort(int[] arr, int n)
{
int temp;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n - i; j++)
{
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
Console.WriteLine("Array after sorting");
for (int i = 1; i <= n; i++)
{
Console.WriteLine(arr[i]);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace basicsorting
{
public class Program
{
public static void Main(string[] args)
{
int i2, k, j;
Console.WriteLine("How many elements you want to sort? ");
i2 = Convert.ToInt32(Console.ReadLine());
int[] values = new int[i2];
int n1 = 0;
int n = 0; ;
int i;
Console.WriteLine("Enter the elements of array {0}", n1);
for (i = 0; i < i2; i++)
{
Console.WriteLine("Enter the elements of array {0}");
n = Convert.ToInt32(Console.ReadLine());
Convert.ToInt32(values[i] = n);
}
for (i = 0; i < i2; i++)
{
k = Convert.ToInt32(values[i]);
for (j = i - 1; j >= 0 && k < values[j]; j--)
values[j + 1] = values[j];
values[j + 1] = k;
}
for (i = 0; i < i2; i++)
{
Console.WriteLine("sorting elements {0}", values[i]);
}
Console.ReadLine();
}
}
}
int[] array = new int[] { 8, 9, 5, 6, 7, 4, 3, 2, 1 };
int[] outPut = new int[] { };
int temp = 0;
for (int i = 0; i < array.Length; i++)
{
for (int j = 0; j < array.Length; j++)
{
var first = array[i];
var second = array[j];
if (array[i] < array[j]) {
temp = first;
array[i] = second;
array[j] = temp;
}
}
}
foreach (var item in array) {
Console.WriteLine(item);
}
Console.ReadKey();
}
foreach (var item in array) {
Console.WriteLine(item);
}
Console.ReadKey();
int temp = 0;
int[] arr = new int[] { 5, 6, 2, 4, 1 };
for (int i = 0; i <= arr.Length - 1; i++)
{
for (int j = i + 1; j <= arr.Length - 1; j++)
{
if (arr[i] > arr[j]) //> Asecnding Order < Desending Order
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Console.Write(arr[i]);
}
Console.ReadLine();
public int[] sortArray(params int[] numbers)
{
for(int i = 0; i < numbers.Length; i++)
{
for(int j = i + 1; j < numbers.Length; j++)
{
if (numbers[i] < numbers[j])
{
continue;
}else if (numbers[i] > numbers[j])
{
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
return numbers;
}
You should do like :
int[] arr = new int[5] { 5, 6, 2, 4, 1 };
for (int i = 0; i < arr.Length-1; i++)
{
if (arr[i] < arr[i + 1])
{
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
// to verify sorted Array
for (int i = 0; i < arr.Length; i++)
{
console.write( arr[i].ToString());
}
For last 1 you need not to check it will be automatically ordered.
#Jon Skeet They wanted to use a for loop.
There are numerous types of sorts. The simplest is Bubble Sort.
int[] arr = new int[5] { 5, 6, 2, 4, 1 };
//bubble sort
for (int i = arr.Length - 1; i > 0; i--)
{
for (int j = 0; j <= i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int highValue = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = highValue;
}
}
}
foreach(int i in arr) Console.Write(i);

Replacing two consecutive cell in an array with one cell

I was just asking if there is a simple way of doing this.
i.e. Replacing two consecutive cell with one cell having different value.
For ex: - if my array =[0,3,1,2,3,4], and i want to replace index 0,and 1 with the value 5
to become like this array=[5,1,2,3,4]
Can you guys suggest some simple way for doing this.
i do this code but there is something wrong:
int J = 0;
if (max != 1)
{
for (int iii = 0; iii < output.Length -1; iii++)
{
if ((output[iii] == imax) && (output[iii + 1] == jmax))
{
temp = temp + 1;
output[J] = Convert.ToByte(temp);
J = J + 1;
iii = iii + 1;
}
else
{
output[J] = output[iii];
J = J + 1;
output[J] = output[iii + 1];
}
}
}
because when i want to check the 2 consecutive index ,i want to pass them to the anther 2 index
If you care about performance you want to do as little operations that can harm performance. Try this extension method:
public static int[] ReplaceConsecutiveCells(this int[] array, int startIndex, int replaceWith)
{
int[] targetArray = new int[array.Length - 1];
for (int i = 0; i < array.Length; i++)
{
if (i < startIndex)
{
targetArray[i] = array[i];
}
else if (i == startIndex)
{
targetArray[i] = replaceWith;
}
else if (i == startIndex + 1)
{
// no action
}
else
{
targetArray[i - 1] = array[i];
}
}
return targetArray;
}
Use it like this:
array = array.ReplaceConsecutiveCells(0, 5);
int[] array = new int[] { 0, 3, 1, 2, 3, 4 };
List<int> list = array.ToList();
list.RemoveRange(0,2);
list.Insert(0, 5);
array = list.ToArray();
Yet another variant
int[] array = new int[] { 0, 3, 1, 2, 3, 4 };
Array.Reverse(array);
Array.Resize(ref array, 5);
Array.Reverse(array);
array[0] = 5;
do
{
RNG_NXT =RNG +1;
for (int iii = 0; iii <Nold -1; iii++)
{
if ((output[iii] == imax) && (output[iii + 1] == jmax))
{
output[J] = Convert.ToByte(RNG_NXT);
J = J + 1;
iii = iii + 1;
}
else
{
output[J] = output[iii];
J = J + 1;
}
}
RNG++;
}
while( RNG < RNG_MAX) ;

Categories

Resources