Fisher–Yates shuffle in C# - c#

I have this method Shuffle that supposes to return a set of random numbers which was displayed in the above method but the numbers need to be displayed in a mixed format.
The first method works well since the number are being displayed correctly in the set of range but this method Shuffle is not returning them in a mixed format.
Example:
The first method returned: 1, 2, 3, 4, 5
This method needs to return 2, 1, 4, 5, 3
public int[] Shuffle(int[] Sequence)
{
int[] Array = new int[Sequence.Length];
for(int s=0; s < Array.Length-1; s++){
int GenObj = GenerateAnotherNum (0, Array.Length + 1);
Array[s] = Sequence[GenObj];
Sequence[GenObj] = Array[s];
}
return Sequence;
}

You have several problems here: all zeroes array, range and swap procedure
Algorithm:
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Code:
// probably "static" should be added (depends on GenerateAnotherNum routine)
public int[] Shuffle(int[] Sequence)
{
// public method's arguments validation
if (null == Sequence)
throw new ArgumentNullException(nameof(Sequence));
// No need in Array if you want to modify Sequence
for(int s = 0; s < Sequence.Length - 1; s++)
{
int GenObj = GenerateAnotherNum(s, Sequence.Length); // pleace, note the range
// swap procedure: note, var h to store initial Sequence[s] value
var h = Sequence[s];
Sequence[s] = Sequence[GenObj];
Sequence[GenObj] = h;
}
return Sequence;
}
Demo:
// Random(0) - we want to reproduce the results in the demo
private static Random random = new Random(0);
// Let unknown GenerateAnotherNum be a random
private static int GenerateAnotherNum(int from, int to) => random.Next(from, to);
...
int[] array = new int[] { 1, 2, 3, 4, 5 };
string result = string.Join(", ", Shuffle(array));
Console.Write(result);
Outcome:
4, 5, 2, 3, 1

public static class Shuffler<T>
{
private static Random r = new Random();
public static T[] Shuffle(T[] items)
{
for(int i = 0; i < items.Length - 1; i++)
{
int pos = r.Next(i, items.Length);
T temp = items[i];
items[i] = items[pos];
items[pos] = temp;
}
return items;
}
public static IList<T> Shuffle(IList<T> items)
{
for(int i = 0; i < items.Count - 1; i++)
{
int pos = r.Next(i, items.Count);
T temp = items[i];
items[i] = items[pos];
items[pos] = temp;
}
return items;
}
}

Related

Pass an array to a function, reverse it without using the Array.Reverse() method and return the reversed array

I want to pass an array to a function, reverse it without using the Array.Reverse() method and return the reversed array. I am actually trying to do it without using the temp variable in this case.
Below is my code snippet. Please correct me where I am getting it wrong.
class Program
{
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int[] reverse = new int[5];
reverse = ReverseArray(array, reverse);
foreach (int item in reverse)
{
Console.WriteLine(reverse);
}
}
public static int[] ReverseArray(int[] arr, int[] rev)
{
int x = arr.Length - 1;
for (int i = 0; i <= x; i++)
{
rev[i] = arr[x];
x--;
}
return rev;
}
}
I am actually trying to do it without using the temp variable in this case.
Let's ignore this bit first, and use a temp variable where it makes sense. We can come back to it.
There are a few different ways in which we can deal with the general problem of "reverse an array". We can reverse the array itself in-place, we can create a new array that is the reverse of the array we were given, or we can fill in another array we are given to be the reverse of the first array we were given. Your solution has a mixture of the three, and hence manages to do none of them properly.
To fill in a second array we are given we do not need a temp, as we aren't swapping, and we do not want to stop at a middle point:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int[] reverse = new int[5];
ReverseArray(array, reverse);
foreach (int item in reverse)
{
Console.WriteLine(item);
}
}
public static void ReverseArray(int[] arr, int[] rev)
{
int x = arr.Length - 1;
for (int i = 0; i < arr.Length; i++, x--)
{
rev[i] = arr[x];
}
}
We've gone through every single element in arr and put it in the relevant position in rev.
To return a new array we do much the same thing, but creating the new array within the method itself:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
int[] reverse = ReverseArray(array);
foreach (int item in reverse)
{
Console.WriteLine(item);
}
}
public static int[] ReverseArray(int[] arr)
{
int[] rev = new int[arr.Length];
int x = arr.Length - 1;
for (int i = 0; i < arr.Length; i++, x--)
{
rev[i] = arr[x];
}
return rev;
}
A variant of this doesn't create a new array at all, but just iterates through it, producing an IEnumerable<int>. This is faster to return the first result and doesn't use as much memory with large arrays, but re-does the reversing every time it's used, so it varies in how useful it is accordingly:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
IEnumerable<int> reverse = ReverseArray(array);
foreach (int item in reverse)
{
Console.WriteLine(item);
}
}
public static IEnumerable<int> ReverseArray(int[] arr)
{
for (int i = arr.Length - 1; i >= 0; i--)
{
yield return arr[i];
}
}
To reverse an array in-place we want to work our way from the outside to the middle swapping elements:
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
ReverseArray(array);
foreach (int item in array)
{
Console.WriteLine(item);
}
}
public static void ReverseArray(int[] arr)
{
int x = arr.Length - 1;
for (int i = 0; i < x; i++, x--)
{
int temp = arr[x];
arr[x] = arr[i];
arr[i] = temp;
}
}
This breaks your arbitrary no-temp-variable rule. We can get around this with a little trick of bit-twiddling, though there's no real value in doing that.
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 4, 5 };
ReverseArray(array);
foreach (int item in array)
{
Console.WriteLine(item);
}
}
public static void ReverseArray(int[] arr)
{
int x = arr.Length - 1;
for (int i = 0; i < x; i++, x--)
{
arr[x] ^= arr[i];
arr[i] ^= arr[x];
arr[x] ^= arr[i];
}
}
There's really no value in not using a 4-byte temporary variable though.
The x might not need to decrement, you can use arr.Length - 1 - i instead of x for array index otherwise, you will only revered half array.
public static int[] ReverseArray(int[] arr, int[] rev)
{
int x = arr.Length - 1;
for (int i = 0; i <= x; i++)
{
rev[i] = arr[arr.Length - 1 - i];
}
return rev;
}
and I would only pass one array be for method and you can declare the reverse array in the method.
public static int[] ReverseArray(int[] arr)
{
int[] reverse = new int[arr.Length];
int x = arr.Length - 1;
for (int i = 0; i <= x; i++)
{
reverse[i] = arr[arr.Length - 1 - i];
}
return reverse;
}
c# online
Result
5
4
3
2
1

Permutations with constant prefix numbers

I have an array of integers where each value will have distinct meanings.The first value means the length of permutation, the second value represent the length of initial prefix and rest of integers are single integer that make up prefix of all permutations.
For e.g. if the array has elements {5,2,1,4}
where 5 is the number of elements in the permutation array.
and 2 is the length of the integer that will makeup the first 2 elements prefix in the array permutation. 1,4 are the prefix integers i.e. length 2 in 5 element permutation combination so missing elements are 2,3,5 where 1&4 being common prefix across all permutations as below
[14235][14253][14325][14352][14523][14532] where input array is {5,2,1,4}
How to achieve this?
I have below code to get the permutation of one missing elements 2,3 & 5 but I am not getting how to program the entire the solution
static void Main(string[] args)
{
int output;
int ip1;
ip1 = Convert.ToInt32(Console.ReadLine());
int ip2_size = 0;
ip2_size = Convert.ToInt32(Console.ReadLine());
int[] ip2 = new int[ip2_size];
int ip2_item;
for (int ip2_i = 0; ip2_i < ip2_size; ip2_i++)
{
ip2_item = Convert.ToInt32(Console.ReadLine());
ip2[ip2_i] = ip2_item;
}
output = correctResult(ip1, ip2);
Console.WriteLine(output);
}
static int correctResult(int n, int[] arr)
{
int permLength = 0;
int prefLength = 0;
int result = 0;
permLength = n;
prefLength = arr.Length;
int[] permArray = new int[permLength];
int len = 0;
var missingNum = Enumerable.Range(1,
permLength).Except(arr).ToArray<int>();
if (permLength < (missingNum.Length + len))
{
result = -1;
}
else
{
for (int i = 0; i < missingNum.Length; i++)
{
permArray[prefLength + i] = missingNum[i];
}
result = permute(missingNum, 0, missingNum.Length - 1);
}
return result;
}
static int permute(int[] arry, int i, int n)
{
int j;
if (i == n)
{
int s1, s2;
s1 = s2 = 0;
for (int a = 0; a < n - 1; a++)
{
for (int b = a + 1; b < n; b++)
{
if (arry[a] > arry[b])
{
s1++;
}
}
s2 = s2 + Math.Max(0, a + 1 - arry[a]);
}
int count = 0;
if (s1 == s2)
count++;
return count;
}
else
{
int count = 0;
for (j = i; j <= n; j++)
{
swap(ref arry[i], ref arry[j]);
count += permute(arry, i + 1, n);
swap(ref arry[i], ref arry[j]);
}
return count;
}
}
static void swap(ref int a, ref int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
Try solving this with immutable types, its easier to reason about them. If, after solving the problem, you have a performance goal you haven't met then you can start trying to optimize the code.
Consider the following approach with an immutable stack that keeps track of the current permutation:
static IEnumerable<IEnumerable<int>> GetPermutations(IList<int> input)
{
if (input == null)
throw new ArgumentNullException(nameof(input));
if (input.Count < 2)
throw new ArgumentException("Input does not have a valid format.");
var setSize = input[0];
var prefixSize = input[1];
if (prefixSize != input.Count - 2)
throw new ArgumentException("Input does not have a valid format.");
if (input.Skip(2).Any(i => i > setSize)) //we are assuming, per example, that valid range starts at 1.
throw new ArgumentException("Input does not have a valid format.");
//Ok, we've got a valid input, interesting stuff starts here.
var prefix = input.Skip(2).ToArray();
var initialSet = Enumerable.Range(1, setSize)
.Except(prefix)
.ToArray();
foreach (var p in getPermutations(ImmutableStack<int>.Empty, initialSet))
{
yield return prefix.Concat(p);
}
IEnumerable<IEnumerable<int>> getPermutations(ImmutableStack<int> permutation, IEnumerable<int> set)
{
if (permutation.Count == setSize - prefixSize)
{
yield return permutation;
}
else
{
foreach (var i in set)
{
foreach (var p in getPermutations(permutation.Push(i), set.Except(new[] { i })))
{
yield return p;
}
}
}
}
}
And that is it, solving your problem was about 10-12 lines of real code (not considering input validation). Note that I am using some c#7 features here, but its easily translatable to previous versions of the language. Also I'd like to underline the argument validation we are doing upfront; make sure you have a valid input before trying out anything.
For ImmutableStack<T> you can use the one in System.Collections.Immutable (you have to download the NuGet package) or implement your own, its simple:
private class ImmutableStack<T>: IEnumerable<T>
{
public static readonly ImmutableStack<T> Empty = new ImmutableStack<T>();
private readonly T head;
private readonly ImmutableStack<T> tail;
private ImmutableStack() { }
private ImmutableStack(T head, ImmutableStack<T> tail)
{
Debug.Assert(tail != null);
this.head = head;
this.tail = tail;
Count = tail.Count + 1;
}
public int Count { get; }
public T Peek() =>
this != Empty ? head : throw new InvalidOperationException("Empty stack.");
public ImmutableStack<T> Pop() =>
this != Empty ? tail : throw new InvalidOperationException("Empty stack.");
public ImmutableStack<T> Push(T item) => new ImmutableStack<T>(item, this);
public IEnumerator<T> GetEnumerator()
{
var current = this;
while (current != Empty)
{
yield return current.head;
current = current.tail;
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
If you use the collections in System.Collections.Immutable, then you'll probably want to use some kind of immutable set for initalSet and set.
You can rewrite your permute method (based on this answer):
private static IEnumerable<IEnumerable<T>> Permute<T>(List<T> prefix, List<T> suffix)
{
for (var i = 0; i < suffix.Count; ++i)
{
var newPrefix = new List<T>(prefix) {suffix[i]};
var newSuffix = new List<T>(suffix.Take(i).Concat(suffix.Skip(i + 1)));
if (newSuffix.Count == 0)
{
yield return newPrefix;
continue;
}
foreach (var permutation in Permute(newPrefix, newSuffix))
yield return permutation;
}
}
And use it like this:
public static void PrintAllPermutations()
{
var input = new[] {5, 2, 1, 4};
var prefix = input.Skip(2).Take(input[1]).ToList();
var suffx = Enumerable.Range(1, input[0]).Except(prefix).ToList();
foreach (var permutation in Permute(prefix, suffx))
Console.WriteLine(string.Join(", ", permutation));
}
Reult would be:
1, 4, 2, 3, 5
1, 4, 2, 5, 3
1, 4, 3, 2, 5
1, 4, 3, 5, 2
1, 4, 5, 2, 3
1, 4, 5, 3, 2

Get an index of array and remove everything left of that index

I have an array of ints
int[] RowOfints = 1,2,3,4,5,6,7,8,9;
if i enter for example value 4 i want to remove 1,2,3 from array and return what's left.
How to do that?
If you don't want to use LINQ:
int[] newRowOfInts = new int[RowOfInts.Length - index];
Array.Copy(RowOfInts, index, newRowOfInts, 0, newRowOfInts.Length);
Using Skip extension in LINQ.
int[] newArray = RowOfInts.Skip(value).ToArray();
I'm interpreting your question that you want to find the index for the value 4 and then take everything starting from that index position.
var result = RowOfInts.SkipWhile(item => item != 4); // optionally, .ToArray()
result will be an IEnumerable<int> consisting of 4 .. 9. If you want a concrete array, you can use the optional ToArray() extension method as well. If no elements in the array match the given criteria, you will get a zero-length sequence.
OK, now that I understand the question better, I will post my version of the actual requirements (again perversely emphasising effeciency over readability):
private static int[] RemoveBeforeValue(int[] source, int value)
{
if (source == null)
return null;
int valueIndex = 0;
while (valueIndex < source.Length && source[valueIndex] != value)
valueIndex++;
if (valueIndex == 0)
return source;
int[] result = new int[source.Length - valueIndex];
Array.Copy(source, valueIndex, result, 0, result.Length);
return result;
}
OLD ANSWER
If you want to do it the hard (but efficient!) way, then you can do this (assuming you want to remove values less than the supplied value):
private static int[] RemoveValuesLessThan(int[] source, int newMinimum)
{
if (source == null)
return null;
int lessThanCount = 0;
for (int index = 0; index < source.Length; index++)
if (source[index] < newMinimum)
lessThanCount++;
if (lessThanCount == 0)
return source;
int[] result = new int[source.Length - lessThanCount];
int targetIndex = 0;
for (int index = 0; index < source.Length; index++)
if (source[index] >= newMinimum)
result[targetIndex++] = source[index];
return result;
}
For a sequential array of ints
public static void RemoveIntsBefore(int i)
{
int[] RowOfints = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int k = 0; k < RowOfints.Length; k++)
{
if (RowOfints.ElementAt(k) < i)
{
RowOfints[k] = i;
}
}
RowOfints = RowOfints.Distinct().ToArray();
//this part is to write it on console
//foreach (var item in RowOfints)
//{
// Console.WriteLine(item);
//}
//Console.ReadLine();
}
with this one your array does not have to be sequential
public static void RemoveIntsBefore(int i)
{
int[] RowOfints = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1,2 };
Console.WriteLine("OUTPUT");
foreach (var item in Enumerable.Range(i-1, RowOfints.Length + 1 - i).ToArray())
{
Console.WriteLine(RowOfints[item]);
}
Console.ReadLine();
}
using System.Linq;
....
int[] RowOfints = {1,2,3,4,5,6,7,8,9};
int[] Answer = RowOfints.Where(x => x != 1 && x != 2 && x != 3).ToArray()

Check for missing number in sequence

I have an List<int> which contains 1,2,4,7,9 for example.
I have a range from 0 to 10.
Is there a way to determine what numbers are missing in that sequence?
I thought LINQ might provide an option but I can't see one
In the real world my List could contain 100,000 items so performance is key
var list = new List<int>(new[] { 1, 2, 4, 7, 9 });
var result = Enumerable.Range(0, 10).Except(list);
Turn the range you want to check into a HashSet:
public IEnumerable<int> FindMissing(IEnumerable<int> values)
{
HashSet<int> myRange = new HashSet<int>(Enumerable.Range(0,10));
myRange.ExceptWith(values);
return myRange;
}
Will return the values that aren't in values.
Using Unity i have tested two solutions on set of million integers. Looks like using Dictionary and two "for" loops gives better result than Enumerable.Except
FindMissing1 Total time: 0.1420 (Enumerable.Except)
FindMissing2 Total time: 0.0621 (Dictionary and two for loops)
public static class ArrayExtension
{
public static T[] FindMissing1<T>(T[] range, T[] values)
{
List<T> result = Enumerable.Except<T>(range, values).ToList<T>();
return result.ToArray<T>();
}
public static T[] FindMissing2<T>(T[] range, T[] values)
{
List<T> result = new List<T>();
Dictionary<T, T> hash = new Dictionary<T, T>(values.Length);
for (int i = 0; i < values.Length; i++)
hash.Add(values[i], values[i]);
for (int i = 0; i < range.Length; i++)
{
if (!hash.ContainsKey(range[i]))
result.Add(range[i]);
}
return result.ToArray<T>();
}
}
public class ArrayManipulationTest : MonoBehaviour
{
void Start()
{
int rangeLength = 1000000;
int[] range = Enumerable.Range(0, rangeLength).ToArray();
int[] values = new int[rangeLength / 5];
int[] missing;
float start;
float duration;
for (int i = 0; i < rangeLength / 5; i ++)
values[i] = i * 5;
start = Time.realtimeSinceStartup;
missing = ArrayExtension.FindMissing1<int>(range, values);
duration = Time.realtimeSinceStartup - start;
Debug.Log($"FindMissing1 Total time: {duration:0.0000}");
start = Time.realtimeSinceStartup;
missing = ArrayExtension.FindMissing2<int>(range, values);
duration = Time.realtimeSinceStartup - start;
Debug.Log($"FindMissing2 Total time: {duration:0.0000}");
}
}
List<int> selectedNumbers = new List<int>(){8, 5, 3, 12, 2};
int firstNumber = selectedNumbers.OrderBy(i => i).First();
int lastNumber = selectedNumbers.OrderBy(i => i).Last();
List<int> allNumbers = Enumerable.Range(firstNumber, lastNumber - firstNumber + 1).ToList();
List<int> missingNumbers = allNumbers.Except(selectedNumbers).ToList();
foreach (int i in missingNumbers)
{
Response.Write(i);
}
LINQ's Except method would be the most readable. Whether it performs adequately for you or not would be a matter for testing.
E.g.
range.Except(listOfValues);
Edit
Here's the program I used for my mini-benchmark, for others to plug away with:
static void Main()
{
var a = Enumerable.Range(0, 1000000);
var b = new List<int>();
for (int i = 0; i < 1000000; i += 10)
{
b.Add(i);
}
Stopwatch sw = new Stopwatch();
sw.Start();
var c = a.Except(b).ToList();
sw.Stop();
Console.WriteLine("Milliseconds {0}", sw.ElapsedMilliseconds );
sw.Reset();
Console.ReadLine();
}
An alternative method which works in general for any two IEnunumerable<T> where T :IComparable. If the IEnumerables are both sorted, this works in O(1) memory (i.e. there is no creating another ICollection and subtracting, etc.) and in O(n) time.
The use of IEnumerable<IComparable> and GetEnumerator makes this a little less readable, but far more general.
Implementation
/// <summary>
/// <para>For two sorted IEnumerable<T> (superset and subset),</para>
/// <para>returns the values in superset which are not in subset.</para>
/// </summary>
public static IEnumerable<T> CompareSortedEnumerables<T>(IEnumerable<T> superset, IEnumerable<T> subset)
where T : IComparable
{
IEnumerator<T> supersetEnumerator = superset.GetEnumerator();
IEnumerator<T> subsetEnumerator = subset.GetEnumerator();
bool itemsRemainingInSubset = subsetEnumerator.MoveNext();
// handle the case when the first item in subset is less than the first item in superset
T firstInSuperset = superset.First();
while ( itemsRemainingInSubset && supersetEnumerator.Current.CompareTo(subsetEnumerator.Current) >= 0 )
itemsRemainingInSubset = subsetEnumerator.MoveNext();
while ( supersetEnumerator.MoveNext() )
{
int comparison = supersetEnumerator.Current.CompareTo(subsetEnumerator.Current);
if ( !itemsRemainingInSubset || comparison < 0 )
{
yield return supersetEnumerator.Current;
}
else if ( comparison >= 0 )
{
while ( itemsRemainingInSubset && supersetEnumerator.Current.CompareTo(subsetEnumerator.Current) >= 0 )
itemsRemainingInSubset = subsetEnumerator.MoveNext();
}
}
}
Usage
var values = Enumerable.Range(0, 11);
var list = new List<int> { 1, 2, 4, 7, 9 };
var notIncluded = CompareSortedEnumerables(values, list);
If the range is predictable I suggest the following solution:
public static void Main()
{
//set up the expected range
var expectedRange = Enumerable.Range(0, 10);
//set up the current list
var currentList = new List<int> {1, 2, 4, 7, 9};
//get the missing items
var missingItems = expectedRange.Except(currentList);
//print the missing items
foreach (int missingItem in missingItems)
{
Console.WriteLine(missingItem);
}
Console.ReadLine();
}
Regards,
y00daa
This does not use LINQ but it works in linear time.
I assume that input list is sorted.
This takes O(list.Count).
private static IEnumerable<int> get_miss(List<int> list,int length)
{
var miss = new List<int>();
int i =0;
for ( i = 0; i < list.Count - 1; i++)
{
foreach (var item in
Enumerable.Range(list[i] + 1, list[i + 1] - list[i] - 1))
{
yield return item;
}
}
foreach (var item in Enumerable.Range(list[i]+1,length-list[i]))
{
yield return item;
}
}
This should take O(n) where n is length of full range.
static void Main()
{
List<int> identifiers = new List<int>() { 1, 2, 4, 7, 9 };
Stopwatch sw = new Stopwatch();
sw.Start();
List<int> miss = GetMiss(identifiers,150000);
sw.Stop();
Console.WriteLine("{0}",sw.ElapsedMilliseconds);
}
private static List<int> GetMiss(List<int> identifiers,int length)
{
List<int> miss = new List<int>();
int j = 0;
for (int i = 0; i < length; i++)
{
if (i < identifiers[j])
miss.Add(i);
else if (i == identifiers[j])
j++;
if (j == identifiers.Count)
{
miss.AddRange(Enumerable.Range(i + 1, length - i));
break;
}
}
return miss;
}
Ok, really, create a new list which parallels the initial list and run the method Except over it...
I have created a fully linq answer using the Aggregate method instead to find the missings:
var list = new List<int>(new[] { 1, 2, 4, 7, 9 }); // Assumes list is ordered at this point
list.Insert(0, 0); // No error checking, just put in the lowest and highest possibles.
list.Add(10); // For real world processing, put in check and if not represented then add it/them.
var missing = new List<int>(); // Hold any missing values found.
list.Aggregate ((seed, aggr) => // Seed is the previous #, aggr is the current number.
{
var diff = (aggr - seed) -1; // A difference between them indicates missing.
if (diff > 0) // Missing found...put in the missing range.
missing.AddRange(Enumerable.Range((aggr - diff), diff));
return aggr;
});
The missing list has this after the above code has been executed:
3, 5, 6, 8
for a List L a general solution (works in all programming languages) would be simply
L.Count()*(L.Count()+1)/2 - L.Sum();
which returns the expected sum of series minus the actual series.
for a List of size n the missing number is:
n(n+1)/2 - (sum of list numbers)
this method here returns the number of missing elements ,sort the set , add all elements from range 0 to range max , then remove the original elements , then you will have the missing set
int makeArrayConsecutive(int[] statues)
{
Array.Sort(statues);
HashSet<int> set = new HashSet<int>();
for(int i = statues[0]; i< statues[statues.Length -1]; i++)
{
set.Add(i);
}
for (int i = 0; i < statues.Length; i++)
{
set.Remove(statues[i]);
}
var x = set.Count;
return x;
// return set ; // use this if you need the actual elements + change the method return type
}
Create an array of num items
const int numItems = 1000;
bool found[numItems] = new bool[numItems];
List<int> list;
PopulateList(list);
list.ForEach( i => found[i] = true );
// now iterate found for the numbers found
for(int count = 0; i < numItems; ++numItems){
Console.WriteList("Item {0} is {1}", count, found[count] ? "there" : "not there");
}
This method does not use LINQ and works in general for any two IEnunumerable<T> where T :IComparable
public static IEnumerable<T> FindMissing<T>(IEnumerable<T> superset, IEnumerable<T> subset) where T : IComparable
{
bool include = true;
foreach (var i in superset)
{
foreach (var j in subset)
{
include = i.CompareTo(j) == 0;
if (include)
break;
}
if (!include)
yield return i;
}
}
int sum = 0,missingNumber;
int[] arr = { 1,2,3,4,5,6,7,8,9};
for (int i = 0; i < arr.Length; i++)
{
sum += arr[i];
}
Console.WriteLine("The sum from 1 to 10 is 55");
Console.WriteLine("Sum is :" +sum);
missingNumber = 55 - sum;
Console.WriteLine("Missing Number is :-"+missingNumber);
Console.ReadLine();

How to shift the start of an array in C#?

I'm trying to reorganize an array based on the first occurrence of a value (thus simulating similar functionality to a circular array.)
For example, in the following array I wish the first occurrence of the value 6 to become the new first element, and prior elements to become the latter:
So:
int[] myArray = {2, 3, 6, 1, 7, 6};
Becomes:
myArray = {6, 1, 7, 6, 2, 3};
What is the "best" way to achieve this?
int[] myArray = { 2, 3, 6, 1, 7, 6 };
myArray = myArray
.SkipWhile(i => i != 6)
.Concat(myArray.TakeWhile(i => i != 6))
.ToArray();
Should do the trick!
You will need a using System.Linq;
Thorsten's solution creates a new array; here's an in place version which only creates a temporary array as large as the amount your rotation size:
public static void RotateLeft<T>(T[] array, int places)
{
T[] temp = new T[places];
Array.Copy(array, 0, temp, 0, places);
Array.Copy(array, places, array, 0, array.Length - places);
Array.Copy(temp, 0, array, array.Length - places, places);
}
I'm sure it could be done with just a single temporary buffer item, but it would be more complicated :)
As an efficiency measure, here's a "rotate left one place" shortcut:
public static void RotateLeft<T>(T[] array)
{
T temp = array[0];
Array.Copy(array, 0, array, 1, array.Length - 1);
array[array.Length-1] = temp;
}
You could do the following:
Create new array of same size as original
Determine your "Start index"
Use Array.Copy() to copy everything from start index to end of source array to destination array
Use Array.Copy() to copy everything from 0 to start index of source array to the end of the destination array
That way you get a copy of your source array that looks as you expected.
You'll have to play with various overloads of Array.Copy(), however, because I don't know the exact parameter values right now.
To begin with, do a linear search to find the first occurrence of the value that you want to make the first element:
// value contains the value to find.
int skip;
for (int i = 0; i < array.Length; i++)
{
if (array[i] == value)
{
skip = i;
break;
}
}
// skip contains the index of the element to put at the front.
// Equivalently, it is the number of items to skip.
// (I chose this name for it because it makes the subtractions
// in the Array.Copy implementation more intuitive.)
Do you want to change the actual array? Then do what Thorsten Dittmar suggests:
int[] array = new int[] { 2, 3, 6, 1, 7, 6 };
int[] result = new int[array.Length];
int skip = 2; // So that array[skip] will be result[0] at the end
Array.Copy(array, skip, result, 0, array.Length - skip);
Array.Copy(array, 0, result, array.Length - skip, skip);
Do you want to just view the array in the new order, without doing anything else? Then index it like so:
array[(i + skip) % array.Length] // Instead of array[i]
Edit: Just for laughs, an implementation of Jon Skeet's suggestion to implement the copy while using only a single buffer value (sourceValue):
// GCD gives the greatest common divisor
int gcd = GCD(array.Length, skip);
// period is the length of the permutation cycles in our rotation.
int period = array.Length / gcd;
int max = array.Length / period;
for (int i = 0; i < max; i++)
{
int sourceIndex = i;
int sourceValue = array[sourceIndex];
for (int n = 1; n <= period; n++)
{
int destinationIndex = (sourceIndex + array.Length - skip) % array.Length;
int temp = array[destinationIndex];
array[destinationIndex] = sourceValue;
sourceValue = temp;
sourceIndex = destinationIndex;
}
}
As an alternative to creating a new array, you can wrap it with a class:
class CircularList<T> : IList<T>
{
static IEnumerable<T> ToEnumerator(CircularList<T> list)
{
for (int i = 0; i < list.Count; i++)
{
yield return list[i];
}
}
IList<T> arr;
public int Shift { get; private set; }
public CircularList(IList<T> arr, int shift)
{
this.arr = arr;
this.Shift = shift;
}
int shiftIndex(int baseIndex)
{
return (baseIndex + Shift) % arr.Count;
}
#region IList<T> Members
public int IndexOf(T item) { throw new NotImplementedException(); }
public void Insert(int index, T item) { throw new NotImplementedException(); }
public void RemoveAt(int index) { throw new NotImplementedException(); }
public T this[int index]
{
get { return arr[shiftIndex(index)]; }
set { arr[shiftIndex(index)] = value; }
}
#endregion
#region ICollection<T> Members
public void Add(T item) { throw new NotImplementedException(); }
public void Clear() { throw new NotImplementedException(); }
public bool Contains(T item) { throw new NotImplementedException(); }
public void CopyTo(T[] array, int arrayIndex) { throw new NotImplementedException(); }
public int Count { get { return arr.Count; } }
public bool IsReadOnly { get { throw new NotImplementedException(); } }
public bool Remove(T item) { throw new NotImplementedException(); }
#endregion
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return ToEnumerator(this).GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ToEnumerator(this).GetEnumerator();
}
#endregion
}
This program:
class Program
{
static void Main(string[] args)
{
int[] myArray = { 2, 3, 6, 1, 7, 6 };
CircularList<int> circularList =
new CircularList<int>(myArray, Array.IndexOf<int>(myArray, 6));
foreach (int i in circularList)
{
Console.WriteLine(i);
}
}
}
Prints the following:
6
1
7
6
2
3
var ar = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ar = ar.SkipWhile(a => a != 6).ToArray<int>();
C# answer:
input : { 1, 2, 3, 5, 6, 7, 8 };
Output : { 8, 7 1, 2, 3, 5, 6};
{
static void Main(string[] args)
{
int[] array = { 1, 2, 3, 5, 6, 7, 8 };
int index = 2;
int[] tempArray = new int[array.Length];
array.CopyTo(tempArray, 0);
for (int i = 0; i < array.Length - index; i++)
{
array[index + i] = tempArray[i];
}
for (int i = 0; i < index; i++)
{
array[i] = tempArray[array.Length -1 - i];
}
}
}
New approach that will only work with .NET 4.5 (from 2012) or later:
const int value = 6;
int[] myArray = { 2, 3, 6, 1, 7, 6, };
var index = Array.IndexOf(myArray, value);
if (index == -1)
throw new InvalidOperationException();
var rotatedArray = (new ArraySegment<int>(myArray, index, myArray.Length - index))
.Concat(new ArraySegment<int>(myArray, 0, index))
.ToArray();
In earlier .NET versions, an ArraySegment<> value could not be used as an IEnumerable<> like that.
Not clear to me if it was a requirement that the original array instance be mutated, but if you need that, simply append:
rotatedArray.CopyTo(myArray, 0);
to my code.

Categories