Related
How can I quickly shift all the items in an array one to the left, padding the end with null?
For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
Edit: I said quickly but I guess I meant efficiently. I need to do this without creating a List or some other data structure. This is something I need to do several hundred thousand times in as short amount of time as possible.
Here's my test harness...
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
var destination = new int?[source.Length];
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000;i++)
{
Array.Copy(source, 1, destination, 0, source.Length - 1);
}
s.Stop();
Console.WriteLine(s.Elapsed);
Here are the performance results for 1 million iterations of each solution (8 Core Intel Xeon E5450 # 3.00GHz)
100 elements 10000 elements
For Loop 0.390s 31.839s
Array.Copy() 0.177s 12.496s
Aaron 1 3.789s 84.082s
Array.ConstrainedCopy() 0.197s 17.658s
Make the choice for yourself :)
The quickest way to do this is to use Array.Copy, which in the final implementation uses a bulk memory transfer operation (similar to memcpy):
var oldArray = new int?[] { 1, 2, 3, 4, 5, 6 };
var newArray = new int?[oldArray.Length];
Array.Copy(oldArray, 1, newArray, 0, oldArray.Length - 1);
// newArray is now { 2, 3, 4, 5, 6, null }
Edited: according to the documentation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
So if you don't want to allocate a new array, you can pass in the original array for both source and destination--although I imagine the tradeoff will be a somewhat slower performance since the values go through a temporary holding position.
I suppose, as in any investigation of this kind, you should do some quick benchmarking.
Here is my solution, similar to Task's in that it is a simple Array wrapper and that it takes O(1) time to shift the array to the left.
public class ShiftyArray<T>
{
private readonly T[] array;
private int front;
public ShiftyArray(T[] array)
{
this.array = array;
front = 0;
}
public void ShiftLeft()
{
array[front++] = default(T);
if(front > array.Length - 1)
{
front = 0;
}
}
public void ShiftLeft(int count)
{
for(int i = 0; i < count; i++)
{
ShiftLeft();
}
}
public T this[int index]
{
get
{
if(index > array.Length - 1)
{
throw new IndexOutOfRangeException();
}
return array[(front + index) % array.Length];
}
}
public int Length { get { return array.Length; } }
}
Running it through Jason Punyon's test code...
int?[] intData = Enumerable.Range(1, 100).Cast<int?>().ToArray();
ShiftyArray<int?> array = new ShiftyArray<int?>(intData);
Stopwatch watch = new Stopwatch();
watch.Start();
for(int i = 0; i < 1000000; i++)
{
array.ShiftLeft();
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Takes ~29ms, regardless of the array size.
Use the Array.Copy() method as in
int?[] myArray = new int?[]{0,1,2,3,4};
Array.Copy(myArray, 1, myArray, 0, myArray.Length - 1);
myArray[myArray.Length - 1] = null
The Array.Copy is probably the way, Microsoft wanted us to copy array elements...
Couldn't you use a System.Collections.Generic.Queue instead of an array ?
I feel like you need to perform actions on your value the discard it, thus using a queue seems to be more appropriate :
// dummy initialization
System.Collections.Generic.Queue<int> queue = new Queue<int>();
for (int i = 0; i < 7; ++i ) { queue.Enqueue(i); }// add each element at the end of the container
// working thread
if (queue.Count > 0)
doSomething(queue.Dequeue());// removes the last element of the container and calls doSomething on it
For any pour soul finding this thread and about to implement one of the highly rated answers. All of them are trash, I'm not sure why that is. Maybe Dested asked for a new array implementation at first or something that has now been removed from the question. Well if you simply want to shift the array and don't need a new one, see an answer like tdaines's answer. And read up on things like the Circular Buffer / Ring Buffer : http://en.wikipedia.org/wiki/Circular_buffer. No moving of the actual data is necessary. The performance of shifting an array should not be tied to the size of the array.
If it absolutely has to be in an array, then I would recommend the most obvious code possible.
for (int index = startIndex; index + 1 < values.Length; index++)
values[index] = values[index + 1];
values[values.Length - 1] = null;
This gives the optimizer the most opportunities to find the best way on whatever target platform the program is installed on.
EDIT:
I just borrowed Jason Punyon's test code, and I'm afraid he's right. Array.Copy wins!
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
int indexToRemove = 4;
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000; i++)
{
Array.Copy(source, indexToRemove + 1, source, indexToRemove, source.Length - indexToRemove - 1);
//for (int index = indexToRemove; index + 1 < source.Length; index++)
// source[index] = source[index + 1];
}
s.Stop();
Console.WriteLine(s.Elapsed);
Array.Copy takes between 103 and 150 ms on my machine.
for loop takes between 269 and 338 ms on my machine.
Can't you
allocate the array with an extra 1000 elements
have an integer variable int base = 0
instead of accessing a[i] access a[base+i]
to do your shift, just say base++
Then after you've done this 1000 times, copy it down and start over.
That way, you only do the copy once per 1000 shifts.
Old joke:
Q: How many IBM 360s does it take to shift a register by 1 bit?
A: 33. 32 to hold the bits in place, and 1 to move the register. (or some such...)
You can use the same array as source and destination for fast in-place copy:
static void Main(string[] args)
{
int[] array = {0, 1, 2, 3, 4, 5, 6, 7};
Array.ConstrainedCopy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = 0;
}
You might do it like this:
var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 }; // Your array
var itemList = new List<int?>(items); // Put the items in a List<>
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
items = itemList.ToArray(); // Turn the list back into an array
Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:
var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
The best and most efficient method I believe is using Buffer.BlockCopy function.
You will set both source and destination to your array, the offset of the source is 1. Depending on your array type (I assume it is int), 1 int = 4 bytes, so you must pass in 4 as the second parameter of this function. Note that the offset is byte offset.
So it looks like this:
int bytes2copy = yourArray.length - 4;
Buffer.BlockCopy(yourArray, 4, yourArray, 0, bytes2copy);
yourArray[yourArray.length-1] = null;
Try this! using Linq. No need of second Array.
var i_array = new int?[] {0, 1, 2, 3, 4, 5, 6 };
i_array = i_array.Select((v, k) => new { v = v, k = k }).
Where(i => i.k > 0).Select(i => i.v).ToArray();
Array.Resize(ref i_array, i_array.Length + 1);
Output:
[0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
If you own the memory you could consider using Unsafe Code and good old fashioned pointers.
Make yourself a memory stream and lock it down or use Marshal.AllocHGlobal
Construct all your arrays in it with a little bit of padding at the beginning and end.
increment or decrement all of the array pointers at once. You'll still need to loop back and set your nulls.
If you need to selectively increment or decrement the arrays you would have to add padding between them.
Arrays are incredibly low level data structures, if you treat them in a low level way you can get huge performance out of them.
A baytrail doing this could outperform Jason's with all its copying 8 Core Intel Xeon E5450 # 3.00GHz
Not tested this code, but it should shifts all the values to right by one. Note that the last three lines of code is all you require to efficiently shift the array.
public class Shift : MonoBehaviour {
//Initialize Array
public int[] queue;
void Start () {
//Create Array Rows
queue = new int[5];
//Set Values to 1,2,3,4,5
for (int i=0; i<5;i++)
{
queue[i] = i + 1;
}
//Get the integer at the first index
int prev = queue[0];
//Copy the array to the new array.
System.Array.Copy(queue, 1, queue, 0, queue.Length - 1);
//Set the last shifted value to the previously first value.
queue[queue.Length - 1] = prev;
Implementation with Extension methods passing shifting direction as Enum.
"for" statements and indexers only (don't use Array.Copy method).
using System;
namespace ShiftArrayElements
{
public static class EnumShifter
{
public static int[] Shift(int[] source, Direction[] directions)
{
for (var i = 0; i < directions.Length; i++)
{
var direction = directions[i];
if (direction == Direction.Left)
{
source.LeftShift();
}
else if (direction == Direction.Right)
{
source.RightShift();
}
else
{
throw new InvalidOperationException("Direction is invalid");
}
}
return source;
}
public static void LeftShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[0];
for (int j = 0; j + 1 < source.Length; j++)
{
source[j] = source[j + 1];
}
source[lastIndex] = temp;
}
public static void RightShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[lastIndex];
for (int j = lastIndex; j > 0; j--)
{
source[j] = source[j - 1];
}
source[0] = temp;
}
}
}
Array copying is an O(n) operation and creates a new array.
While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:
using System;
using System.Text;
public class ArrayReindexer
{
private Array reindexed;
private int location, offset;
public ArrayReindexer( Array source )
{
reindexed = source;
}
public object this[int index]
{
get
{
if (offset > 0 && index >= location)
{
int adjustedIndex = index + offset;
return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
}
return reindexed.GetValue( index );
}
}
public void Reindex( int position, int shiftAmount )
{
location = position;
offset = shiftAmount;
}
public override string ToString()
{
StringBuilder output = new StringBuilder( "[ " );
for (int i = 0; i < reindexed.Length; ++i)
{
output.Append( this[i] );
if (i == reindexed.Length - 1)
{
output.Append( " ]" );
}
else
{
output.Append( ", " );
}
}
return output.ToString();
}
}
By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...
ArrayReindexer original = new ArrayReindexer( SourceArray );
Console.WriteLine( " Base array: {0}", original.ToString() );
ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
reindexed.Reindex( 1, 1 );
Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
Will produce the output:
Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
Shifted array: [ 0, 2, 3, 4, 5, 6, null ]
I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )
It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.
Hope this helps!
Incorrect and slightly amusing answer (thanks, i'll be here all night !)
int?[] test = new int?[] {0,1,2,3,4,5,6 };
int?[] t = new int?[test.Length];
t = test.Skip(1).ToArray();
t[t.Length - 1] = null;
In the spirit of still using Skip (dont ask me, i know worst usage of LINQ extension methods ever), the only way I thought of rewriting it would be
int?[] test = new int?[] { 0, 1, 2, 3, 4, 5, 6 };
int?[] t = new int?[test.Length];
Array.Copy(test.Skip(1).ToArray(), t, t.Length - 1);
But it's in NO WAY faster than the other options.
I know this is an old question but coming from Google there was no simple example so thanks to this is the easiest way to reorder a list, and you don't have to supply the type it will work it out at runtime,
private static List<T> reorderList<T>(List<T> list){
List<T> newList = new List<T>();
list.ForEach(delegate(T item)
{
newList.Add(item);
});
return newList;
}
using System;
using System.Threading;
namespace ShiftMatrix
{
class Program
{
static void Main(string[] args)
{
MatrixOperation objMatrixOperation = new MatrixOperation();
//Create a matrix
int[,] mat = new int[,]
{
{1, 2},
{3,4 },
{5, 6},
{7,8},
{8,9},
};
int type = 2;
int counter = 0;
if (type == 1)
{
counter = mat.GetLength(0);
}
else
{
counter = mat.GetLength(1);
}
while (true)
{
for (int i = 0; i < counter; i++)
{
ShowMatrix(objMatrixOperation.ShiftMatrix(mat, i, type));
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
public static void ShowMatrix(int[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
for (int k = 0; k < rows; k++)
{
for (int l = 0; l < columns; l++)
{
Console.Write(matrix[k, l] + " ");
}
Console.WriteLine();
}
}
}
class MatrixOperation
{
public int[,] ShiftMatrix(int[,] origanalMatrix, int shift, int type)
{
int rows = origanalMatrix.GetLength(0);
int cols = origanalMatrix.GetLength(1);
int[,] _tmpMatrix = new int[rows, cols];
if (type == 2)
{
for (int x1 = 0; x1 < rows; x1++)
{
int y2 = 0;
for (int y1 = shift; y2 < cols - shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
y2--;
for (int y1 = 0; y1 < shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
}
}
else
{
int x2 = 0;
for (int x1 = shift; x2 < rows - shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
x2--;
for (int x1 = 0; x1 < shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
}
return _tmpMatrix;
}
}
}
See C# code below to remove space from string. That shift character in array. Performance is O(n). No other array is used. So no extra memory either.
static void Main(string[] args)
{
string strIn = System.Console.ReadLine();
char[] chraryIn = strIn.ToCharArray();
int iShift = 0;
char chrTemp;
for (int i = 0; i < chraryIn.Length; ++i)
{
if (i > 0)
{
chrTemp = chraryIn[i];
chraryIn[i - iShift] = chrTemp;
chraryIn[i] = chraryIn[i - iShift];
}
if (chraryIn[i] == ' ') iShift++;
if (i >= chraryIn.Length - 1 - iShift) chraryIn[i] = ' ';
}
System.Console.WriteLine(new string(chraryIn));
System.Console.Read();
}
a is array of ints & d is number of times array has to shift left.
static int[] rotLeft(int[] a, int d)
{
var innerLoop = a.Length - 1;
for(var loop=0; loop < d; loop++)
{
var res = a[innerLoop];
for (var i= innerLoop; i>=0; i--)
{
var tempI = i-1;
if (tempI < 0)
{
tempI = innerLoop;
}
var yolo = a[tempI];
a[tempI] = res;
res = yolo;
}
}
return a;
}
Simple way to do it when you need to resize the same array.
var nLength = args.Length - 1;
Array.Copy(args, 1, args, 0, nLength);
Array.Resize(ref args, nLength);
Okay, I know that this code is crude, and all around a messy, but I am no programmer, so bear with me. I have this code that lists a bunch of numbers, but I want it to not list any circular copies of the numbers.
For example, if the number 111262 is on my list, I don't want 112621, 126211, 262111, 621112, or 211126 to be listed.
Sorry, that number cannot be on the list.
For a true example, if the number 111252 is on my list, I don't want 112521, 125211, 252111, 521112, or 211125 to be listed.
Any help is appreciated!
namespace Toric_Classes
{
class Program
{
static void Main(string[] args)
{
int number_of_perms=0;
bool badsubsum1;
bool badsubsum2;
int subsum1 = 0;
int subsum2 = 0;
int sum = 0;
int class_length=6;
int[] toric_class=new int[class_length];
// The nested for loops scroll through every possible number of length class_length, where each digit can have a value of 1,2,..., or class_length-1
// Each number is looked at as an array, and is not stored anywhere, only printed if it satisfies certain conditions
for(int i1=1; i1<class_length; i1++)
{
toric_class[0] = i1;
for (int i2 = 1; i2 < class_length; i2++)
{
toric_class[1] = i2;
for (int i3 = 1; i3 < class_length; i3++)
{
toric_class[2] = i3;
for (int i4 = 1; i4 < class_length; i4++)
{
toric_class[3] = i4;
for (int i5 = 1; i5 < class_length; i5++)
{
toric_class[4] = i5;
for (int i6 = 1; i6 < class_length; i6++)
{
badsubsum1 = false;
badsubsum2 = false;
toric_class[5] = i6;
// Find the value of the sum of the digits of our array.
// We only want numbers that have a total digit sum being a multiple of class_length
for (int k = 0; k < class_length; k++)
{
sum += toric_class[k];
}
// The follwong two nested loops find the value of every contiguous subsum of our number, but not the total subsum.
// We *do not* want any subsum to be a multiple of class_length.
// That is, if our number is, say, 121342, we want to find 1+2, 1+2+1, 1+2+1+3, 1+2+1+3+4, 2+1, 2+1+3, 2+1+3+4, 2+1+3+4+2, 1+3, 1+3+4, 1+3+4+2, 3+4, 3+4+2, and 4+2
// The following checks 1+2, 1+2+1, 1+2+1+3, 1+2+1+3+4, 2+1, 2+1+3, 2+1+3+4, 1+3, 1+3+4, and 3+4
for (int i = 0; i < class_length - 1; i++)
{
for (int j = i + 1; j < class_length - 1; j++)
{
for (int k = i; k < j; k++)
{
subsum1 += toric_class[k];
}
if (subsum1 % class_length == 0)
{
badsubsum1 = true;
break;
}
subsum1 = 0;
}
}
// The following checks 2+1, 2+1+3, 2+1+3+4, 2+1+3+4+2, 1+3, 1+3+4, 1+3+4+2, 3+4, 3+4+2, and 4+2
for (int i = 1; i < class_length; i++)
{
for (int j = i + 1; j < class_length; j++)
{
for (int k = i; k < j; k++)
{
subsum2 += toric_class[k];
}
if (subsum2 % class_length == 0)
{
badsubsum2 = true;
break;
}
subsum2 = 0;
}
}
// We only want numbers that satisfies the following conditions
if (sum % class_length == 0 && badsubsum1 == false && badsubsum2 == false)
{
foreach (var item in toric_class)
{
Console.Write(item.ToString());
}
Console.Write(Environment.NewLine);
number_of_perms++;
}
sum = 0;
subsum1 = 0;
subsum2 = 0;
}
}
}
}
}
}
Console.WriteLine("Number of Permuatations: "+number_of_perms);
Console.Read();
}
}
}
EDIT
To clarify, I am creating a list of all numbers with length n that satisfy certain conditions. Consider the number d1d2...dn, where each di is a digit of our number. Each di may have value 1,2,...,n. Our number is in the list if it satisfies the following
The sum of all the digits is a multiple of n, that is,
d1+d2+...+dn = 0 mod n
Every contiguous subsum of the digits is not a multiple of n, aside from the total sum, that is, if i !=1 and j != n, then
di+d(i+1)+...+dj != 0 mod n
I should mention again that a "number" does not strictly use the numbers 0-9 in its digits. It may take any value between 1 and n. In my code, I am using the case where n=6.
The code works by creating an array of length class_length (in the code above, I use class_length=6). We first have 6 nested for loops that simply assign values to the array toric_class. The first for assigns toric_class[0], the second for assigns toric_class[1], and so on. In the first go around, we are generating the array 111111, then 111112, up to 111115, then 111121, etc. So essentially, we are looking at all heximal numbers that do not include 0. Once we reach our sixth value in our array, we check the array toric_class and check its values to ensure that it satisfies the above conditions. If it does, we simply print the array in a line, and move on.
Here is my easy and inefficient way that should work with minimal changes to your code. It requires shared string list var strList = new List<string>(); to store the used numbers. Then this part:
foreach (var item in toric_class)
{
Console.Write(item.ToString());
}
Console.Write(Environment.NewLine);
number_of_perms++;
becomes something like this:
string strItem = " " + string.Join(" ", toric_class) + " "; // Example: int[] {1, 12, 123} becomes " 1 12 123 "
if (!strList.Any(str => str.Contains(strItem))) // Example: if " 1 12 123 1 12 123 " contains " 1 12 123 "
{
Console.WriteLine(strItem);
strItem += strItem.Substring(1); // double the string, but keep only one space between them
strList.Add(strItem);
}
number_of_perms++; // not sure if this should be in the if statement
The idea is that for example the string " 1 1 1 2 5 2 1 1 1 2 5 2 " contains all circular copies of the numbers {1, 1, 1, 2, 5, 2}. I used string as a lazy way to check if array contains sub-array, but you can use similar approach to store copy of the used numbers in a list of arrays new List<int[]>() and check if any of the arrays in the list is circular copy of the current array, or even better HashSet<int[]>() approach similar to #slavanap's answer.
The first version of my answer was the easiest, but it works only with array of single digit items.
List is almost the same as array (new List<string>() instead of new string[]), but makes it much easier and efficient to add items to it. For example {1,2}.Add(3) becomes {1,2,3}.
str => str.Contains(strItem) is shortcut for a function that accepts parameter str and returns the result of str.Contains(strItem). That "function" is then passed to the .Any LINQ extension, so
strList.Any(str => str.Contains(strItem))
is shortcut for something like this:
foreach(string str in strList)
{
if (str.Contains(strItem))
{
return true;
}
}
return false;
The following method:
private static List<int> GetCircularEquivalents(int value)
{
var circularList = new List<int>();
var valueString = value.ToString();
var length = valueString.Length - 1;
for (var i = 0; i < length; i++)
{
valueString = valueString.Substring(1, length) + valueString.Substring(0, 1);
circularList.Add(int.Parse(valueString));
}
return circularList;
}
will return a list of the circular numbers derived from the input value. Using your example, this method can be called like this:
var circularList = GetCircularEquivalents(111262);
var dirtyList = new List<int> { 1, 112621, 2, 126211, 3, 262111, 4, 621112, 5, 211126, 6 };
var cleanList = dirtyList.Except(circularList).ToList();
which would result in a cleanList made up of the numbers 1 through 6, i.e. the dirtyList with all the circular numbers derived from 111262 removed.
That's where OOP really benefits. Comments inlined.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication3 {
struct MyInt : IEquatable<MyInt> {
private int _value;
public MyInt(int value) {
_value = value;
}
// make it look like int
static public implicit operator MyInt(int value) {
return new MyInt(value);
}
public static explicit operator int(MyInt instance) {
return instance._value;
}
// main difference in these 3 methods
private int GetDigitsNum() {
int temp, res;
for (res = 0, temp = Math.Abs(_value); temp > 0; ++res, temp /= 10);
return res;
}
public bool Equals(MyInt other) {
int digits = other.GetDigitsNum();
if (digits != this.GetDigitsNum())
return false;
int temp = other._value;
// prepare mul used in shifts
int mul = 1;
for (int i = 0; i < digits - 1; ++i)
mul *= 10;
// compare
for (int i = 0; i < digits; ++i) {
if (temp == _value)
return true;
// ROR
int t = temp % 10;
temp = temp / 10 + t * mul;
}
return false;
}
public override int GetHashCode() {
// hash code must be equal for "equal" items,
// that's why use a sum of digits.
int sum = 0;
for (int temp = _value; temp > 0; temp /= 10)
sum += temp % 10;
return sum;
}
// be consistent
public override bool Equals(object obj) {
return (obj is MyInt) ? Equals((MyInt)obj) : false;
}
public override string ToString() {
return _value.ToString();
}
}
class Program {
static void Main(string[] args) {
List<MyInt> list = new List<MyInt> { 112621, 126211, 262111, 621112, 211126 };
// make a set of unique items from list
HashSet<MyInt> set = new HashSet<MyInt>(list);
// print that set
foreach(int item in set)
Console.WriteLine(item);
}
}
}
Output:
112621
How do you compute the smallest cost traversal of an integer array using steps and jumps, while also counting the first and last element of the array? A step is moving to the next immediate value in the array e.g. array[currentIndex + 1], and a jump is moving two spots e.g. array[currentIndex + 2]. I have the following function which I want to return the minimum sum started, it adds the first and last elements to the sum, but I'm stuck on the middle values of the array.
An example of this would be {2, 10, 4, 14, 44, 28, 16, 18} -> 66
which would add indexes 0, 2, 3, 5, and 7.
====
public int Cost(int[] board)
{
int sum = board[0];
int index = 0;
while (index < board.Length)
{
//Add the final array value to the sum
if (index + 1 == board.length)
{
sum += board[index];
break;
}
//Add other values here
index++;
}
return sum;
}
You can try this:
public int Cost(int[] board)
{
int[] cost = new int[board.Length];
for (int i = 0; i < board.Length; i++) {
if (i == 0) {
cost[i] = board[0];
} else if (i == 1) {
cost[i] = board[1] + cost[0];
} else {
cost[i] = board[i] + Math.Min(cost[i - 1], cost[i - 2]);
}
}
return cost[board.Length - 1];
}
One possible solution:
public int Cost(int[] board, int step = 1)
{
if (board == null) return -1;
if (board.Length == 0) return 0;
// always add first and last index (if its not the first)
int sum = board[0];
if (board.Length > 1) sum += board[board.Length - 1];
// assumes step is > 0
for (int i = step; i < (board.Length - 1); i += step)
{
sum += board[i];
}
return sum;
}
This allows for step to be a parameter. Maybe now you want to step either 1 or 2 away from the start. Maybe later you want to step 5 spots away.
This solution factorizes a number (numInput), it works perfectly well except for a logic error I can't seem to find no matter how much I track the solution. The logic error causes the returned result to be 0 no matter the value initialized for numInput.
using System;
namespace factorizer
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(factorialise());
Console.ReadKey();
}
private static int factorialise()
{
int numInput = int.Parse(Console.ReadLine());
int[] number = new int[numInput];
for (int i = 1; i < numInput; i++) //stores the (n-1)...(n-i) value for the number input'd in the array number[i]
{
number[i - 1] = numInput - i; //the element indicating the index number is 'i - 1' index values start from zero
}
for (int index = 0; index < number.Length; index++) //multiplies the element corresponding the index number with the number input'd
{
numInput = numInput * number[index];
}
return numInput;
}
}
}
Your last item in array stays uninitialized (i.e. equal to zero). Change items count:
int[] number = new int[numInput-1];
Also why not simply use for loop?
int result = 1;
for(int i = 1; i <= numInput; i++)
result *= i;
And another sample just for fun
Enumerable.Range(1, numInput).Aggregate(1, (a,i) => a * i)
How can I quickly shift all the items in an array one to the left, padding the end with null?
For example, [0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
Edit: I said quickly but I guess I meant efficiently. I need to do this without creating a List or some other data structure. This is something I need to do several hundred thousand times in as short amount of time as possible.
Here's my test harness...
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
var destination = new int?[source.Length];
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000;i++)
{
Array.Copy(source, 1, destination, 0, source.Length - 1);
}
s.Stop();
Console.WriteLine(s.Elapsed);
Here are the performance results for 1 million iterations of each solution (8 Core Intel Xeon E5450 # 3.00GHz)
100 elements 10000 elements
For Loop 0.390s 31.839s
Array.Copy() 0.177s 12.496s
Aaron 1 3.789s 84.082s
Array.ConstrainedCopy() 0.197s 17.658s
Make the choice for yourself :)
The quickest way to do this is to use Array.Copy, which in the final implementation uses a bulk memory transfer operation (similar to memcpy):
var oldArray = new int?[] { 1, 2, 3, 4, 5, 6 };
var newArray = new int?[oldArray.Length];
Array.Copy(oldArray, 1, newArray, 0, oldArray.Length - 1);
// newArray is now { 2, 3, 4, 5, 6, null }
Edited: according to the documentation:
If sourceArray and destinationArray overlap, this method behaves as if the original values of sourceArray were preserved in a temporary location before destinationArray is overwritten.
So if you don't want to allocate a new array, you can pass in the original array for both source and destination--although I imagine the tradeoff will be a somewhat slower performance since the values go through a temporary holding position.
I suppose, as in any investigation of this kind, you should do some quick benchmarking.
Here is my solution, similar to Task's in that it is a simple Array wrapper and that it takes O(1) time to shift the array to the left.
public class ShiftyArray<T>
{
private readonly T[] array;
private int front;
public ShiftyArray(T[] array)
{
this.array = array;
front = 0;
}
public void ShiftLeft()
{
array[front++] = default(T);
if(front > array.Length - 1)
{
front = 0;
}
}
public void ShiftLeft(int count)
{
for(int i = 0; i < count; i++)
{
ShiftLeft();
}
}
public T this[int index]
{
get
{
if(index > array.Length - 1)
{
throw new IndexOutOfRangeException();
}
return array[(front + index) % array.Length];
}
}
public int Length { get { return array.Length; } }
}
Running it through Jason Punyon's test code...
int?[] intData = Enumerable.Range(1, 100).Cast<int?>().ToArray();
ShiftyArray<int?> array = new ShiftyArray<int?>(intData);
Stopwatch watch = new Stopwatch();
watch.Start();
for(int i = 0; i < 1000000; i++)
{
array.ShiftLeft();
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
Takes ~29ms, regardless of the array size.
Use the Array.Copy() method as in
int?[] myArray = new int?[]{0,1,2,3,4};
Array.Copy(myArray, 1, myArray, 0, myArray.Length - 1);
myArray[myArray.Length - 1] = null
The Array.Copy is probably the way, Microsoft wanted us to copy array elements...
Couldn't you use a System.Collections.Generic.Queue instead of an array ?
I feel like you need to perform actions on your value the discard it, thus using a queue seems to be more appropriate :
// dummy initialization
System.Collections.Generic.Queue<int> queue = new Queue<int>();
for (int i = 0; i < 7; ++i ) { queue.Enqueue(i); }// add each element at the end of the container
// working thread
if (queue.Count > 0)
doSomething(queue.Dequeue());// removes the last element of the container and calls doSomething on it
For any pour soul finding this thread and about to implement one of the highly rated answers. All of them are trash, I'm not sure why that is. Maybe Dested asked for a new array implementation at first or something that has now been removed from the question. Well if you simply want to shift the array and don't need a new one, see an answer like tdaines's answer. And read up on things like the Circular Buffer / Ring Buffer : http://en.wikipedia.org/wiki/Circular_buffer. No moving of the actual data is necessary. The performance of shifting an array should not be tied to the size of the array.
If it absolutely has to be in an array, then I would recommend the most obvious code possible.
for (int index = startIndex; index + 1 < values.Length; index++)
values[index] = values[index + 1];
values[values.Length - 1] = null;
This gives the optimizer the most opportunities to find the best way on whatever target platform the program is installed on.
EDIT:
I just borrowed Jason Punyon's test code, and I'm afraid he's right. Array.Copy wins!
var source = Enumerable.Range(1, 100).Cast<int?>().ToArray();
int indexToRemove = 4;
var s = new Stopwatch();
s.Start();
for (int i = 0; i < 1000000; i++)
{
Array.Copy(source, indexToRemove + 1, source, indexToRemove, source.Length - indexToRemove - 1);
//for (int index = indexToRemove; index + 1 < source.Length; index++)
// source[index] = source[index + 1];
}
s.Stop();
Console.WriteLine(s.Elapsed);
Array.Copy takes between 103 and 150 ms on my machine.
for loop takes between 269 and 338 ms on my machine.
Can't you
allocate the array with an extra 1000 elements
have an integer variable int base = 0
instead of accessing a[i] access a[base+i]
to do your shift, just say base++
Then after you've done this 1000 times, copy it down and start over.
That way, you only do the copy once per 1000 shifts.
Old joke:
Q: How many IBM 360s does it take to shift a register by 1 bit?
A: 33. 32 to hold the bits in place, and 1 to move the register. (or some such...)
You can use the same array as source and destination for fast in-place copy:
static void Main(string[] args)
{
int[] array = {0, 1, 2, 3, 4, 5, 6, 7};
Array.ConstrainedCopy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = 0;
}
You might do it like this:
var items = new int?[] { 0, 1, 2, 3, 4, 5, 6 }; // Your array
var itemList = new List<int?>(items); // Put the items in a List<>
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
items = itemList.ToArray(); // Turn the list back into an array
Of course, it would be more efficient to get rid of the array entirely and just use a List<>. You could then forget the first line and last line and do it like this:
var itemList = new List<int?> { 0, 1, 2, 3, 4, 5, 6 };
itemList.RemoveAt(1); // Remove the item at index 1
itemList.Add(null); // Add a null to the end of the list
The best and most efficient method I believe is using Buffer.BlockCopy function.
You will set both source and destination to your array, the offset of the source is 1. Depending on your array type (I assume it is int), 1 int = 4 bytes, so you must pass in 4 as the second parameter of this function. Note that the offset is byte offset.
So it looks like this:
int bytes2copy = yourArray.length - 4;
Buffer.BlockCopy(yourArray, 4, yourArray, 0, bytes2copy);
yourArray[yourArray.length-1] = null;
Try this! using Linq. No need of second Array.
var i_array = new int?[] {0, 1, 2, 3, 4, 5, 6 };
i_array = i_array.Select((v, k) => new { v = v, k = k }).
Where(i => i.k > 0).Select(i => i.v).ToArray();
Array.Resize(ref i_array, i_array.Length + 1);
Output:
[0,1,2,3,4,5,6] would become [1,2,3,4,5,6,null]
If you own the memory you could consider using Unsafe Code and good old fashioned pointers.
Make yourself a memory stream and lock it down or use Marshal.AllocHGlobal
Construct all your arrays in it with a little bit of padding at the beginning and end.
increment or decrement all of the array pointers at once. You'll still need to loop back and set your nulls.
If you need to selectively increment or decrement the arrays you would have to add padding between them.
Arrays are incredibly low level data structures, if you treat them in a low level way you can get huge performance out of them.
A baytrail doing this could outperform Jason's with all its copying 8 Core Intel Xeon E5450 # 3.00GHz
Not tested this code, but it should shifts all the values to right by one. Note that the last three lines of code is all you require to efficiently shift the array.
public class Shift : MonoBehaviour {
//Initialize Array
public int[] queue;
void Start () {
//Create Array Rows
queue = new int[5];
//Set Values to 1,2,3,4,5
for (int i=0; i<5;i++)
{
queue[i] = i + 1;
}
//Get the integer at the first index
int prev = queue[0];
//Copy the array to the new array.
System.Array.Copy(queue, 1, queue, 0, queue.Length - 1);
//Set the last shifted value to the previously first value.
queue[queue.Length - 1] = prev;
Implementation with Extension methods passing shifting direction as Enum.
"for" statements and indexers only (don't use Array.Copy method).
using System;
namespace ShiftArrayElements
{
public static class EnumShifter
{
public static int[] Shift(int[] source, Direction[] directions)
{
for (var i = 0; i < directions.Length; i++)
{
var direction = directions[i];
if (direction == Direction.Left)
{
source.LeftShift();
}
else if (direction == Direction.Right)
{
source.RightShift();
}
else
{
throw new InvalidOperationException("Direction is invalid");
}
}
return source;
}
public static void LeftShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[0];
for (int j = 0; j + 1 < source.Length; j++)
{
source[j] = source[j + 1];
}
source[lastIndex] = temp;
}
public static void RightShift(this int[] source)
{
var lastIndex = source?.Length - 1 ?? 0;
var temp = source[lastIndex];
for (int j = lastIndex; j > 0; j--)
{
source[j] = source[j - 1];
}
source[0] = temp;
}
}
}
Array copying is an O(n) operation and creates a new array.
While array copying can certainly be done quickly and efficiently, the problem you've stated can actually be solved in an entirely different way without (as you've requested) creating a new array/data structure and only creating one small wrapping object instance per array:
using System;
using System.Text;
public class ArrayReindexer
{
private Array reindexed;
private int location, offset;
public ArrayReindexer( Array source )
{
reindexed = source;
}
public object this[int index]
{
get
{
if (offset > 0 && index >= location)
{
int adjustedIndex = index + offset;
return adjustedIndex >= reindexed.Length ? "null" : reindexed.GetValue( adjustedIndex );
}
return reindexed.GetValue( index );
}
}
public void Reindex( int position, int shiftAmount )
{
location = position;
offset = shiftAmount;
}
public override string ToString()
{
StringBuilder output = new StringBuilder( "[ " );
for (int i = 0; i < reindexed.Length; ++i)
{
output.Append( this[i] );
if (i == reindexed.Length - 1)
{
output.Append( " ]" );
}
else
{
output.Append( ", " );
}
}
return output.ToString();
}
}
By wrapping and controlling access to the array in this manner, we can now demonstrate how the problem was solved with an O(1) method call...
ArrayReindexer original = new ArrayReindexer( SourceArray );
Console.WriteLine( " Base array: {0}", original.ToString() );
ArrayReindexer reindexed = new ArrayReindexer( SourceArray );
reindexed.Reindex( 1, 1 );
Console.WriteLine( "Shifted array: {0}", reindexed.ToString() );
Will produce the output:
Base array: [ 0, 1, 2, 3, 4, 5, 6 ]
Shifted array: [ 0, 2, 3, 4, 5, 6, null ]
I'm willing to bet that there will be a reason that such a solution won't work for you, but I believe this does match your initial stated requirements. 8 )
It's often helpful to think about all the different kinds of solutions to a problem before implementing a specific one, and perhaps that might be the most important thing that this example can demonstrate.
Hope this helps!
Incorrect and slightly amusing answer (thanks, i'll be here all night !)
int?[] test = new int?[] {0,1,2,3,4,5,6 };
int?[] t = new int?[test.Length];
t = test.Skip(1).ToArray();
t[t.Length - 1] = null;
In the spirit of still using Skip (dont ask me, i know worst usage of LINQ extension methods ever), the only way I thought of rewriting it would be
int?[] test = new int?[] { 0, 1, 2, 3, 4, 5, 6 };
int?[] t = new int?[test.Length];
Array.Copy(test.Skip(1).ToArray(), t, t.Length - 1);
But it's in NO WAY faster than the other options.
I know this is an old question but coming from Google there was no simple example so thanks to this is the easiest way to reorder a list, and you don't have to supply the type it will work it out at runtime,
private static List<T> reorderList<T>(List<T> list){
List<T> newList = new List<T>();
list.ForEach(delegate(T item)
{
newList.Add(item);
});
return newList;
}
using System;
using System.Threading;
namespace ShiftMatrix
{
class Program
{
static void Main(string[] args)
{
MatrixOperation objMatrixOperation = new MatrixOperation();
//Create a matrix
int[,] mat = new int[,]
{
{1, 2},
{3,4 },
{5, 6},
{7,8},
{8,9},
};
int type = 2;
int counter = 0;
if (type == 1)
{
counter = mat.GetLength(0);
}
else
{
counter = mat.GetLength(1);
}
while (true)
{
for (int i = 0; i < counter; i++)
{
ShowMatrix(objMatrixOperation.ShiftMatrix(mat, i, type));
Thread.Sleep(TimeSpan.FromSeconds(2));
}
}
}
public static void ShowMatrix(int[,] matrix)
{
int rows = matrix.GetLength(0);
int columns = matrix.GetLength(1);
for (int k = 0; k < rows; k++)
{
for (int l = 0; l < columns; l++)
{
Console.Write(matrix[k, l] + " ");
}
Console.WriteLine();
}
}
}
class MatrixOperation
{
public int[,] ShiftMatrix(int[,] origanalMatrix, int shift, int type)
{
int rows = origanalMatrix.GetLength(0);
int cols = origanalMatrix.GetLength(1);
int[,] _tmpMatrix = new int[rows, cols];
if (type == 2)
{
for (int x1 = 0; x1 < rows; x1++)
{
int y2 = 0;
for (int y1 = shift; y2 < cols - shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
y2--;
for (int y1 = 0; y1 < shift; y1++, y2++)
{
_tmpMatrix[x1, y2] = origanalMatrix[x1, y1];
}
}
}
else
{
int x2 = 0;
for (int x1 = shift; x2 < rows - shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
x2--;
for (int x1 = 0; x1 < shift; x1++, x2++)
{
for (int y1 = 0; y1 < cols; y1++)
{
_tmpMatrix[x2, y1] = origanalMatrix[x1, y1];
}
}
}
return _tmpMatrix;
}
}
}
See C# code below to remove space from string. That shift character in array. Performance is O(n). No other array is used. So no extra memory either.
static void Main(string[] args)
{
string strIn = System.Console.ReadLine();
char[] chraryIn = strIn.ToCharArray();
int iShift = 0;
char chrTemp;
for (int i = 0; i < chraryIn.Length; ++i)
{
if (i > 0)
{
chrTemp = chraryIn[i];
chraryIn[i - iShift] = chrTemp;
chraryIn[i] = chraryIn[i - iShift];
}
if (chraryIn[i] == ' ') iShift++;
if (i >= chraryIn.Length - 1 - iShift) chraryIn[i] = ' ';
}
System.Console.WriteLine(new string(chraryIn));
System.Console.Read();
}
a is array of ints & d is number of times array has to shift left.
static int[] rotLeft(int[] a, int d)
{
var innerLoop = a.Length - 1;
for(var loop=0; loop < d; loop++)
{
var res = a[innerLoop];
for (var i= innerLoop; i>=0; i--)
{
var tempI = i-1;
if (tempI < 0)
{
tempI = innerLoop;
}
var yolo = a[tempI];
a[tempI] = res;
res = yolo;
}
}
return a;
}
Simple way to do it when you need to resize the same array.
var nLength = args.Length - 1;
Array.Copy(args, 1, args, 0, nLength);
Array.Resize(ref args, nLength);