Related
I have some code that wasn't written by myself and I'm trying to use it to build a Poker ICM calculator program. This program takes an array of stack sizes and prize payouts and calculates each players prize equity.
The code works for 3 prizes but when I add a 4th prize I get an index out of bounds error because I'm trying to get permutation[3] when the object only contains indexes 0 to 2. The problem is I can't understand how the size of permuation gets set so I can't figure out how to adjust the code to work for higher numbers of prizes. I'd appreciate some help.
Below is a minimum working example with working and non-working code in the main method and a comment to indicate where the error occurs.
ICMCalculator.cs
class ICMCalculator
{
public double[] CalcEV(int[] structure, int[] chips)
{
//the probability of a players position
double[,] probabilitys = new double[structure.Length, chips.Length];
//the expected value of the player
double[] EVs = new double[chips.Length];
int[] players = new int[chips.Length];
for (int i = 0; i < players.Length; ++i)
players[i] = i;
IEnumerable<int[]> permutations;
for (int i = 0; i < structure.Length; ++i)
{
permutations = (new Permutation()).Enumerate(players, i + 2);
foreach (int[] permutation in permutations)
{
// OUT OF BOUNDS ERROR OCCURS HERE
probabilitys[i, permutation[i]] += CalcPermutationProbability(permutation, chips);
}
}
for (int i = 0; i < structure.Length; ++i)
{
for (int j = 0; j < chips.Length; ++j)
EVs[j] += probabilitys[i, j] * structure[i];
}
return EVs;
}
private double CalcPermutationProbability(int[] permutations, int[] chips)
{
double probability = 1.0F;
int chips_sum = chips.Sum();
for (int i = 0; i < permutations.Length; ++i)
{
probability *= System.Convert.ToDouble(chips[permutations[i]]) / System.Convert.ToDouble(chips_sum);
chips_sum -= chips[permutations[i]];
}
return probability;
}
}
Permutation.cs
class Permutation
{
public IEnumerable<T[]> Enumerate<T>(IEnumerable<T> nums, int length)
{
var perms = _GetPermutations<T>(new List<T>(), nums.ToList(), length);
return perms;
}
private IEnumerable<T[]> _GetPermutations<T>(IEnumerable<T> perm, IEnumerable<T> nums, int length)
{
if (length - perm.Count() <= 0)
{
yield return perm.ToArray();
}
else
{
foreach (var n in nums)
{
var result = _GetPermutations<T>(perm.Concat(new T[] { n }),
nums.Where(x => x.Equals(n) == false), length - perm.Count());
foreach (var xs in result)
yield return xs.ToArray();
}
}
}
}
Utils.cs
class Utils
{
public static string DoubleArrayToString(double[] doubles)
{
StringBuilder sb = new StringBuilder();
foreach (double dub in doubles)
{
sb.AppendLine(Utils.Format2DP(dub));
}
return sb.ToString().Trim();
}
}
Program.cs
static class Program
{
static void Main()
{
// THIS WORKS
ICMCalculator ev = new ICMCalculator();
int[] stacks = new int[] { 4500, 2700, 1800, 1000, 500 };
int[] prizes = new int[] { 84,36,18 };
int prizePool = prizes.Sum();
double[] equity = ev.CalcEV(prizes, stacks);
Console.WriteLine(Utils.DoubleArrayToString(equity));
// THIS THROWS INDEX ERROR
ev = new ICMCalculator();
stacks = new int[] { 4500, 2700, 1800, 1000, 500 };
prizes = new int[] { 84,36,18,9 };
prizePool = prizes.Sum();
equity = ev.CalcEV(prizes, stacks);
Console.WriteLine(Utils.DoubleArrayToString(equity));
}
}
To be clear, I believe that each 'permutation' should be the length of structure.Length. I don't want to avoid the out of bounds error by reducing the max value of i. I think I need to increase the size of each permuation to match structure.Length but I'm unable to figure out how to do this.
If resolved correctly, the code that currently fails should output the values: 50.82, 37.85, 29.16, 19.01, 10.15
I think the problem is in this line:
var result = _GetPermutations<T>(perm.Concat(new T[] { n }),
nums.Where(x => x.Equals(n) == false), length - perm.Count());
Instead, I think it should be
var result = _GetPermutations<T>(perm.Concat(new T[] { n }),
nums.Where(x => x.Equals(n) == false), length);
The problem here is that we are double-counting the length of the permutation found so far when we determine whether to stop further recursion.
The condition length - perm.Count() <= 0 (which can be simplified to perm.Count() >= length) is used to stop further calls to _GetPermutations if the permutation perm generated so far is long enough to be returned. This relies on the parameter length being the required length of the resulting permutations. However, by passing length - perm.Count() in the recursive call to _GetPermutations(), then we are reducing the value of length that inner calls to _GetPermutations() receive, causing them to stop the recursion early with permutations that are too short.
Lists say I have a list List<int> {1,2,3,4,5}
Rotate means:
=> {2,3,4,5,1} => {3,4,5,1,2} => {4,5,1,2,3}
Maybe rotate is not the best word for this, but hope you understand what I means
My question, whats the easiest way (in short code, c# 4 Linq ready), and will not be hit by performance (reasonable performance)
Thanks.
List<T>
The simplest way (for a List<T>) is to use:
int first = list[0];
list.RemoveAt(0);
list.Add(first);
Performance is nasty though - O(n).
Array
This is basically equivalent to the List<T> version, but more manual:
int first = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = first;
LinkedList<T>
If you could use a LinkedList<T> instead, that would be much simpler:
int first = linkedList.First;
linkedList.RemoveFirst();
linkedList.AddLast(first);
This is O(1) as each operation is constant time.
Queue<T>
cadrell0's solution of using a queue is a single statement, as Dequeue removes the element and returns it:
queue.Enqueue(queue.Dequeue());
While I can't find any documentation of the performance characteristic of this, I'd expect Queue<T> to be implemented using an array and an index as the "virtual starting point" - in which case this is another O(1) solution.
Note that in all of these cases you'd want to check for the list being empty first. (You could deem that to be an error, or a no-op.)
You could implement it as a queue. Dequeue and Enqueue the same value.
**I wasn't sure about performance in converting a List to a Queue, but people upvoted my comment, so I'm posting this as an answer.
I use this one:
public static List<T> Rotate<T>(this List<T> list, int offset)
{
return list.Skip(offset).Concat(list.Take(offset)).ToList();
}
It seems like some answerers have treated this as a chance to explore data structures. While those answers are informative and useful, they are not very Linq'ish.
The Linq'ish approach is: You get an extension method which returns a lazy IEnumerable that knows how to build what you want. This method doesn't modify the source and should only allocate a copy of the source if necessary.
public static IEnumerable<IEnumerable<T>> Rotate<T>(this List<T> source)
{
for(int i = 0; i < source.Count; i++)
{
yield return source.TakeFrom(i).Concat(source.TakeUntil(i));
}
}
//similar to list.Skip(i-1), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeFrom<T>(this List<T> source, int index)
{
for(int i = index; i < source.Count; i++)
{
yield return source[i];
}
}
//similar to list.Take(i), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeUntil<T>(this List<T> source, int index)
{
for(int i = 0; i < index; i++)
{
yield return source[i];
}
}
Used as:
List<int> myList = new List<int>(){1, 2, 3, 4, 5};
foreach(IEnumerable<int> rotation in myList.Rotate())
{
//do something with that rotation
}
How about this:
var output = input.Skip(rot)
.Take(input.Count - rot)
.Concat(input.Take(rot))
.ToList();
Where rot is the number of spots to rotate - which must be less than the number of elements in the input list.
As #cadrell0 answer shows if this is all you do with your list, you should use a queue instead of a list.
My solution maybe too basic (I wouldn't like to say it's lame...) and not LINQ'ish.
However, it has a pretty good performance.
int max = 5; //the fixed size of your array.
int[] inArray = new int[5] {0,0,0,0,0}; //initial values only.
void putValueToArray(int thisData)
{
//let's do the magic here...
Array.Copy(inArray, 1, inArray, 0, max-1);
inArray[max-1] = thisData;
}
Try
List<int> nums = new List<int> {1,2,3,4,5};
var newNums = nums.Skip(1).Take(nums.Count() - 1).ToList();
newNums.Add(nums[0]);
Although, I like Jon Skeet's answer better.
My solution for Arrays:
public static void ArrayRotate(Array data, int index)
{
if (index > data.Length)
throw new ArgumentException("Invalid index");
else if (index == data.Length || index == 0)
return;
var copy = (Array)data.Clone();
int part1Length = data.Length - index;
//Part1
Array.Copy(copy, 0, data, index, part1Length);
//Part2
Array.Copy(copy, part1Length, data, 0, index);
}
I've used the following extensions for this:
static class Extensions
{
public static IEnumerable<T> RotateLeft<T>(this IEnumerable<T> e, int n) =>
n >= 0 ? e.Skip(n).Concat(e.Take(n)) : e.RotateRight(-n);
public static IEnumerable<T> RotateRight<T>(this IEnumerable<T> e, int n) =>
e.Reverse().RotateLeft(n).Reverse();
}
They're certainly easy (OP title request), and they've got reasonable performance (OP write-up request). Here's a little demo I ran in LINQPad 5 on an above-average-powered laptop:
void Main()
{
const int n = 1000000;
const int r = n / 10;
var a = Enumerable.Range(0, n);
var t = Stopwatch.StartNew();
Console.WriteLine(a.RotateLeft(r).ToArray().First());
Console.WriteLine(a.RotateLeft(-r).ToArray().First());
Console.WriteLine(a.RotateRight(r).ToArray().First());
Console.WriteLine(a.RotateRight(-r).ToArray().First());
Console.WriteLine(t.ElapsedMilliseconds); // e.g. 236
}
You can use below code for left Rotation.
List<int> backUpArray = array.ToList();
for (int i = 0; i < array.Length; i++)
{
int newLocation = (i + (array.Length - rotationNumber)) % n;
array[newLocation] = backUpArray[i];
}
You can play nice in .net framework.
I understand that what you want to do is more up to be an iteration behavior than a new collection type; so I would suggest you to try this extension method based on IEnumerable, which will work with Collections, Lists and so on...
class Program
{
static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> circularNumbers = numbers.AsCircular();
IEnumerable<int> firstFourNumbers = circularNumbers
.Take(4); // 1 2 3 4
IEnumerable<int> nextSevenNumbersfromfourth = circularNumbers
.Skip(4).Take(7); // 4 5 6 7 1 2 3
}
}
public static class CircularEnumerable
{
public static IEnumerable<T> AsCircular<T>(this IEnumerable<T> source)
{
if (source == null)
yield break; // be a gentleman
IEnumerator<T> enumerator = source.GetEnumerator();
iterateAllAndBackToStart:
while (enumerator.MoveNext())
yield return enumerator.Current;
enumerator.Reset();
if(!enumerator.MoveNext())
yield break;
else
yield return enumerator.Current;
goto iterateAllAndBackToStart;
}
}
Reasonable performance
Flexible
If you want go further, make a CircularList and hold the same enumerator to skip the Skip() when rotating like in your sample.
below is my approach. Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
public static int[] RightShiftRotation(int[] a, int times) {
int[] demo = new int[a.Length];
int d = times,i=0;
while(d>0) {
demo[d-1] = a[a.Length - 1 - i]; d = d - 1; i = i + 1;
}
for(int j=a.Length-1-times;j>=0;j--) { demo[j + times] = a[j]; }
return demo;
}
Using Linq,
List<int> temp = new List<int>();
public int[] solution(int[] array, int range)
{
int tempLength = array.Length - range;
temp = array.Skip(tempLength).ToList();
temp.AddRange(array.Take(array.Length - range).ToList());
return temp.ToArray();
}
If you're working with a string you can do this quite efficiently using ReadOnlySpans:
ReadOnlySpan<char> apiKeySchema = "12345";
const int apiKeyLength = 5;
for (int i = 0; i < apiKeyLength; i++)
{
ReadOnlySpan<char> left = apiKeySchema.Slice(start: i, length: apiKeyLength - i);
ReadOnlySpan<char> right = apiKeySchema.Slice(start: 0, length: i);
Console.WriteLine(string.Concat(left, right));
}
Output:
12345
23451
34512
45123
51234
I was asked to reverse a character array with minimal memory usage.
char[] charArray = new char[]{'C','o','w','b','o','y'};
Method:
static void Reverse(ref char[] s)
{
for (int i=0; i < (s.Length-i); i++)
{
char leftMost = s[i];
char rightMost = s[s.Length - i - 1];
s[i] = rightMost;
s[s.Length - i - 1] = leftMost;
}
}
How about using modular arithmetic :
public void UsingModularArithmetic()
{
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
int[] a = new int[n];
for(int i = 0; i < n; i++)
{
int newLocation = (i + (n - k)) % n;
a[newLocation] = Convert.ToInt32(Console.ReadLine());
}
foreach (int i in a)
Console.Write("{0} ", i);
}
So basically adding the values to the array when I am reading from console.
I have a large sequence of integers (1M+).
Whenever a user queries my API, I need to pick one of these integers in a non-sequential, not random and non-repeating way. I cannot store the history of all integers previously returned.
I came up with a "shaking" algorithm which simply moves values around within a very large array:
static int[] Shake(
int[] values,
Func<int, bool> predicate,
Func<int, int> moveBy)
{
static int Adjust(int index, int size)
{
while (index > size - 1) index -= size;
while (index < 0) index += size;
return index;
}
var count = values.Length;
for (var oldIndex = 0; oldIndex < count - 1; oldIndex++)
{
if (!predicate(oldIndex)) continue;
var newIndex = Adjust(oldIndex + moveBy(oldIndex), count);
var value = values[oldIndex];
values[oldIndex] = values[newIndex];
values[newIndex] = value;
}
return values;
}
var indexes = Enumerable.Range(0, size).ToArray();
indexes = Shake(indexes, idx => idx % 3 == 0, idx => idx + 50);
indexes = Shake(indexes, idx => idx % 2 == 0, idx => 12);
return indexes;
This algorithm works and but is not really efficient:
I need to create and loop through large collections of items
May consume lots of memory / CPU
This is a fairly slow algorithm
Instead of creating large arrays of data, I was wondering if there is another way to return a number in a
non-sequential, not random and non-repeating way (maybe a formula / mathematical series but my math sucks).
Thx for your help
Here you have an efficient and simple solution, you just need a prime number and remember n, the next time you need to increment n.
class Program
{
const long prime = 15_485_863;
static void Main(string[] args)
{
const int arrayLenght = 1_000_0000;
var numbers = new int[arrayLenght];
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = i;
}
var hashSet = new HashSet<int>();
for (int i = 0; i < numbers.Length; i++)
{
var number = GetNonSequentialNotRandomNonRepeatingNumber(numbers, i);
if (hashSet.Add(number) == false)
{
Console.WriteLine($"Something went wrong. {number} is duplicated");
}
}
}
static int GetNonSequentialNotRandomNonRepeatingNumber(int[] numbers, int n)
{
int pos = (int) ((prime * (long) n) % numbers.Length);
return numbers[pos];
}
}
So I have an unsorted numeric array int[] anArray = { 1, 5, 2, 7 }; and I need to get both the value and the index of the largest value in the array which would be 7 and 3, how would I do this?
This is not the most glamorous way but works.
(must have using System.Linq;)
int maxValue = anArray.Max();
int maxIndex = anArray.ToList().IndexOf(maxValue);
int[] anArray = { 1, 5, 2, 7 };
// Finding max
int m = anArray.Max();
// Positioning max
int p = Array.IndexOf(anArray, m);
If the index is not sorted, you have to iterate through the array at least once to find the highest value. I'd use a simple for loop:
int? maxVal = null; //nullable so this works even if you have all super-low negatives
int index = -1;
for (int i = 0; i < anArray.Length; i++)
{
int thisNum = anArray[i];
if (!maxVal.HasValue || thisNum > maxVal.Value)
{
maxVal = thisNum;
index = i;
}
}
This is more verbose than something using LINQ or other one-line solutions, but it's probably a little faster. There's really no way to make this faster than O(N).
A succinct one-liner:
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Test case:
var anArray = new int[] { 1, 5, 7, 4, 2 };
var (number, index) = anArray.Select((n, i) => (n, i)).Max();
Console.WriteLine($"Maximum number = {number}, on index {index}.");
// Maximum number = 7, on index 2.
Features:
Uses Linq (not as optimized as vanilla, but the trade-off is less code).
Does not need to sort.
Computational complexity: O(n).
Space complexity: O(n).
Remarks:
Make sure the number (and not the index) is the first element in the tuple because tuple sorting is done by comparing tuple items from left to right.
The obligatory LINQ one[1]-liner:
var max = anArray.Select((value, index) => new {value, index})
.OrderByDescending(vi => vi.value)
.First();
(The sorting is probably a performance hit over the other solutions.)
[1]: For given values of "one".
Here are two approaches. You may want to add handling for when the array is empty.
public static void FindMax()
{
// Advantages:
// * Functional approach
// * Compact code
// Cons:
// * We are indexing into the array twice at each step
// * The Range and IEnumerable add a bit of overhead
// * Many people will find this code harder to understand
int[] array = { 1, 5, 2, 7 };
int maxIndex = Enumerable.Range(0, array.Length).Aggregate((max, i) => array[max] > array[i] ? max : i);
int maxInt = array[maxIndex];
Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");
}
public static void FindMax2()
{
// Advantages:
// * Near-optimal performance
int[] array = { 1, 5, 2, 7 };
int maxIndex = -1;
int maxInt = Int32.MinValue;
// Modern C# compilers optimize the case where we put array.Length in the condition
for (int i = 0; i < array.Length; i++)
{
int value = array[i];
if (value > maxInt)
{
maxInt = value;
maxIndex = i;
}
}
Console.WriteLine($"Maximum int {maxInt} is found at index {maxIndex}");
}
int[] numbers = new int[7]{45,67,23,45,19,85,64};
int smallest = numbers[0];
for (int index = 0; index < numbers.Length; index++)
{
if (numbers[index] < smallest) smallest = numbers[index];
}
Console.WriteLine(smallest);
public static class ArrayExtensions
{
public static int MaxIndexOf<T>(this T[] input)
{
var max = input.Max();
int index = Array.IndexOf(input, max);
return index;
}
}
This works for all variable types...
var array = new int[]{1, 2, 4, 10, 0, 2};
var index = array.MaxIndexOf();
var array = new double[]{1.0, 2.0, 4.0, 10.0, 0.0, 2.0};
var index = array.MaxIndexOf();
this works like a charm, no need for linq or other extensions
int[] anArray = { 1, 5, 2, 7 };
int i, mx;
int j = 0;
mx = anArray[0];
for (i = 1; i < anArray.Length; i++)
{
if (anArray[i] > mx)
{
mx = anArray[i];
j = i;
}
}
Console.Write("The largest value is: {0}, of index: {1}", mx, j);
anArray.Select((n, i) => new { Value = n, Index = i })
.Where(s => s.Value == anArray.Max());
Output for bellow code:
00:00:00.3279270 - max1
00:00:00.2615935 - max2
00:00:00.6010360 - max3 (arr.Max())
With 100000000 ints in array not very big difference but still...
class Program
{
static void Main(string[] args)
{
int[] arr = new int[100000000];
Random randNum = new Random();
for (int i = 0; i < arr.Length; i++)
{
arr[i] = randNum.Next(-100000000, 100000000);
}
Stopwatch stopwatch1 = new Stopwatch();
Stopwatch stopwatch2 = new Stopwatch();
Stopwatch stopwatch3 = new Stopwatch();
stopwatch1.Start();
var max = GetMaxFullIterate(arr);
Debug.WriteLine( stopwatch1.Elapsed.ToString());
stopwatch2.Start();
var max2 = GetMaxPartialIterate(arr);
Debug.WriteLine( stopwatch2.Elapsed.ToString());
stopwatch3.Start();
var max3 = arr.Max();
Debug.WriteLine(stopwatch3.Elapsed.ToString());
}
private static int GetMaxPartialIterate(int[] arr)
{
var max = arr[0];
var idx = 0;
for (int i = arr.Length / 2; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
if (arr[idx] > max)
{
max = arr[idx];
}
idx++;
}
return max;
}
private static int GetMaxFullIterate(int[] arr)
{
var max = arr[0];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
}
public static void Main()
{
int a,b=0;
int []arr={1, 2, 2, 3, 3, 4, 5, 6, 5, 7, 7, 7, 100, 8, 1};
for(int i=arr.Length-1 ; i>-1 ; i--)
{
a = arr[i];
if(a > b)
{
b=a;
}
}
Console.WriteLine(b);
}
Old post, but this is super easy with Lists:
For Maximum:
List<int> lst = new List<int>(YourArray);
int Max = lst.OrderByDescending(x => x).First();
For Minimum:
List<int> lst = new List<int>(YourArray);
int Max = lst.OrderBy(x => x).First();
Of course you can substitute "int" data type with any numeric variable type (float, decimal, etc).
This is very high performance BTW and beats any other method (IMHO)
int[] Data= { 1, 212, 333,2,12,3311,122,23 };
int large = Data.Max();
Console.WriteLine(large);
Here is a LINQ solution which is O(n) with decent constant factors:
int[] anArray = { 1, 5, 2, 7, 1 };
int index = 0;
int maxIndex = 0;
var max = anArray.Aggregate(
(oldMax, element) => {
++index;
if (element <= oldMax)
return oldMax;
maxIndex = index;
return element;
}
);
Console.WriteLine("max = {0}, maxIndex = {1}", max, maxIndex);
But you should really write an explicit for lop if you care about performance.
Just another perspective using DataTable. Declare a DataTable with 2 columns called index and val. Add an AutoIncrement option and both AutoIncrementSeed and AutoIncrementStep values 1 to the index column. Then use a foreach loop and insert each array item into the datatable as a row. Then by using Select method, select the row having the maximum value.
Code
int[] anArray = { 1, 5, 2, 7 };
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("index"), new DataColumn("val")});
dt.Columns["index"].AutoIncrement = true;
dt.Columns["index"].AutoIncrementSeed = 1;
dt.Columns["index"].AutoIncrementStep = 1;
foreach(int i in anArray)
dt.Rows.Add(null, i);
DataRow[] dr = dt.Select("[val] = MAX([val])");
Console.WriteLine("Max Value = {0}, Index = {1}", dr[0][1], dr[0][0]);
Output
Max Value = 7, Index = 4
Find a demo here
If you know max index accessing the max value is immediate. So all you need is max index.
int max=0;
for(int i = 1; i < arr.Length; i++)
if (arr[i] > arr[max]) max = i;
This is a C# Version. It's based on the idea of sort the array.
public int solution(int[] A)
{
// write your code in C# 6.0 with .NET 4.5 (Mono)
Array.Sort(A);
var max = A.Max();
if(max < 0)
return 1;
else
for (int i = 1; i < max; i++)
{
if(!A.Contains(i)) {
return i;
}
}
return max + 1;
}
Consider following:
/// <summary>
/// Returns max value
/// </summary>
/// <param name="arr">array to search in</param>
/// <param name="index">index of the max value</param>
/// <returns>max value</returns>
public static int MaxAt(int[] arr, out int index)
{
index = -1;
int max = Int32.MinValue;
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] > max)
{
max = arr[i];
index = i;
}
}
return max;
}
Usage:
int m, at;
m = MaxAt(new int[]{1,2,7,3,4,5,6}, out at);
Console.WriteLine("Max: {0}, found at: {1}", m, at);
This can be done with a bodiless for loop, if we're heading towards golf ;)
//a is the array
int mi = a.Length - 1;
for (int i=-1; ++i<a.Length-1; mi=a[mi]<a[i]?i:mi) ;
The check of ++i<a.Length-1 omits checking the last index. We don't mind this if we set it up as if the max index is the last index to start with.. When the loop runs for the other elements it will finish and one or the other thing is true:
we found a new max value and hence a new max index mi
the last index was the max value all along, so we didn't find a new mi, and we stuck with the initial mi
The real work is done by the post-loop modifiers:
is the max value (a[mi] i.e. array indexed by mi) we found so far, less than the current item?
yes, then store a new mi by remembering i,
no then store the existing mi (no-op)
At the end of the operation you have the index at which the max is to be found. Logically then the max value is a[mi]
I couldn't quite see how the "find max and index of max" really needed to track the max value too, given that if you have an array, and you know the index of the max value, the actual value of the max value is a trivial case of using the index to index the array..
Another answer in this long list, but I think it's worth it, because it provides some benefits that most (or all?) other answers don't:
The method below loops only once through the collection, therefore the order is O(N).
The method finds ALL indices of the maximum values.
The method can be used to find the indices of any comparison: min, max, equals, not equals, etc.
The method can look into objects via a LINQ selector.
Method:
///-------------------------------------------------------------------
/// <summary>
/// Get the indices of all values that meet the condition that is defined by the comparer.
/// </summary>
/// <typeparam name="TSource">The type of the values in the source collection.</typeparam>
/// <typeparam name="TCompare">The type of the values that are compared.</typeparam>
/// <param name="i_collection">The collection of values that is analysed.</param>
/// <param name="i_selector">The selector to retrieve the compare-values from the source-values.</param>
/// <param name="i_comparer">The comparer that is used to compare the values of the collection.</param>
/// <returns>The indices of all values that meet the condition that is defined by the comparer.</returns>
/// Create <see cref="IComparer{T}"/> from comparison function:
/// Comparer{T}.Create ( comparison )
/// Comparison examples:
/// - max: (a, b) => a.CompareTo (b)
/// - min: (a, b) => -(a.CompareTo (b))
/// - == x: (a, b) => a == 4 ? 0 : -1
/// - != x: (a, b) => a != 4 ? 0 : -1
///-------------------------------------------------------------------
public static IEnumerable<int> GetIndices<TSource, TCompare> (this IEnumerable<TSource> i_collection,
Func<TSource, TCompare> i_selector,
IComparer<TCompare> i_comparer)
{
if (i_collection == null)
throw new ArgumentNullException (nameof (i_collection));
if (!i_collection.Any ())
return new int[0];
int index = 0;
var indices = new List<int> ();
TCompare reference = i_selector (i_collection.First ());
foreach (var value in i_collection)
{
var compare = i_selector (value);
int result = i_comparer.Compare (compare, reference);
if (result > 0)
{
reference = compare;
indices.Clear ();
indices.Add (index);
}
else if (result == 0)
indices.Add (index);
index++;
}
return indices;
}
If you don't need the selector, then change the method to
public static IEnumerable<int> GetIndices<TCompare> (this IEnumerable<TCompare> i_collection,
IComparer<TCompare> i_comparer)
and remove all occurences of i_selector.
Proof of concept:
//########## test #1: int array ##########
int[] test = { 1, 5, 4, 9, 2, 7, 4, 6, 5, 9, 4 };
// get indices of maximum:
var indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a.CompareTo (b)));
// indices: { 3, 9 }
// get indices of all '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 4 ? 0 : -1));
// indices: { 2, 6, 10 }
// get indices of all except '4':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a != 4 ? 0 : -1));
// indices: { 0, 1, 3, 4, 5, 7, 8, 9 }
// get indices of all '15':
indices = test.GetIndices (t => t, Comparer<int>.Create ((a, b) => a == 15 ? 0 : -1));
// indices: { }
//########## test #2: named tuple array ##########
var datas = new (object anything, double score)[]
{
(999, 0.1),
(new object (), 0.42),
("hello", 0.3),
(new Exception (), 0.16),
("abcde", 0.42)
};
// get indices of highest score:
indices = datas.GetIndices (data => data.score, Comparer<double>.Create ((a, b) => a.CompareTo (b)));
// indices: { 1, 4 }
Enjoy! :-)
Finds the biggest and the smallest number in the array:
int[] arr = new int[] {35,28,20,89,63,45,12};
int big = 0;
int little = 0;
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
if (arr[i] > arr[0])
{
big = arr[i];
}
else
{
little = arr[i];
}
}
Console.WriteLine("most big number inside of array is " + big);
Console.WriteLine("most little number inside of array is " + little);
Lists say I have a list List<int> {1,2,3,4,5}
Rotate means:
=> {2,3,4,5,1} => {3,4,5,1,2} => {4,5,1,2,3}
Maybe rotate is not the best word for this, but hope you understand what I means
My question, whats the easiest way (in short code, c# 4 Linq ready), and will not be hit by performance (reasonable performance)
Thanks.
List<T>
The simplest way (for a List<T>) is to use:
int first = list[0];
list.RemoveAt(0);
list.Add(first);
Performance is nasty though - O(n).
Array
This is basically equivalent to the List<T> version, but more manual:
int first = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = first;
LinkedList<T>
If you could use a LinkedList<T> instead, that would be much simpler:
int first = linkedList.First;
linkedList.RemoveFirst();
linkedList.AddLast(first);
This is O(1) as each operation is constant time.
Queue<T>
cadrell0's solution of using a queue is a single statement, as Dequeue removes the element and returns it:
queue.Enqueue(queue.Dequeue());
While I can't find any documentation of the performance characteristic of this, I'd expect Queue<T> to be implemented using an array and an index as the "virtual starting point" - in which case this is another O(1) solution.
Note that in all of these cases you'd want to check for the list being empty first. (You could deem that to be an error, or a no-op.)
You could implement it as a queue. Dequeue and Enqueue the same value.
**I wasn't sure about performance in converting a List to a Queue, but people upvoted my comment, so I'm posting this as an answer.
I use this one:
public static List<T> Rotate<T>(this List<T> list, int offset)
{
return list.Skip(offset).Concat(list.Take(offset)).ToList();
}
It seems like some answerers have treated this as a chance to explore data structures. While those answers are informative and useful, they are not very Linq'ish.
The Linq'ish approach is: You get an extension method which returns a lazy IEnumerable that knows how to build what you want. This method doesn't modify the source and should only allocate a copy of the source if necessary.
public static IEnumerable<IEnumerable<T>> Rotate<T>(this List<T> source)
{
for(int i = 0; i < source.Count; i++)
{
yield return source.TakeFrom(i).Concat(source.TakeUntil(i));
}
}
//similar to list.Skip(i-1), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeFrom<T>(this List<T> source, int index)
{
for(int i = index; i < source.Count; i++)
{
yield return source[i];
}
}
//similar to list.Take(i), but using list's indexer access to reduce iterations
public static IEnumerable<T> TakeUntil<T>(this List<T> source, int index)
{
for(int i = 0; i < index; i++)
{
yield return source[i];
}
}
Used as:
List<int> myList = new List<int>(){1, 2, 3, 4, 5};
foreach(IEnumerable<int> rotation in myList.Rotate())
{
//do something with that rotation
}
How about this:
var output = input.Skip(rot)
.Take(input.Count - rot)
.Concat(input.Take(rot))
.ToList();
Where rot is the number of spots to rotate - which must be less than the number of elements in the input list.
As #cadrell0 answer shows if this is all you do with your list, you should use a queue instead of a list.
My solution maybe too basic (I wouldn't like to say it's lame...) and not LINQ'ish.
However, it has a pretty good performance.
int max = 5; //the fixed size of your array.
int[] inArray = new int[5] {0,0,0,0,0}; //initial values only.
void putValueToArray(int thisData)
{
//let's do the magic here...
Array.Copy(inArray, 1, inArray, 0, max-1);
inArray[max-1] = thisData;
}
Try
List<int> nums = new List<int> {1,2,3,4,5};
var newNums = nums.Skip(1).Take(nums.Count() - 1).ToList();
newNums.Add(nums[0]);
Although, I like Jon Skeet's answer better.
My solution for Arrays:
public static void ArrayRotate(Array data, int index)
{
if (index > data.Length)
throw new ArgumentException("Invalid index");
else if (index == data.Length || index == 0)
return;
var copy = (Array)data.Clone();
int part1Length = data.Length - index;
//Part1
Array.Copy(copy, 0, data, index, part1Length);
//Part2
Array.Copy(copy, part1Length, data, 0, index);
}
I've used the following extensions for this:
static class Extensions
{
public static IEnumerable<T> RotateLeft<T>(this IEnumerable<T> e, int n) =>
n >= 0 ? e.Skip(n).Concat(e.Take(n)) : e.RotateRight(-n);
public static IEnumerable<T> RotateRight<T>(this IEnumerable<T> e, int n) =>
e.Reverse().RotateLeft(n).Reverse();
}
They're certainly easy (OP title request), and they've got reasonable performance (OP write-up request). Here's a little demo I ran in LINQPad 5 on an above-average-powered laptop:
void Main()
{
const int n = 1000000;
const int r = n / 10;
var a = Enumerable.Range(0, n);
var t = Stopwatch.StartNew();
Console.WriteLine(a.RotateLeft(r).ToArray().First());
Console.WriteLine(a.RotateLeft(-r).ToArray().First());
Console.WriteLine(a.RotateRight(r).ToArray().First());
Console.WriteLine(a.RotateRight(-r).ToArray().First());
Console.WriteLine(t.ElapsedMilliseconds); // e.g. 236
}
You can use below code for left Rotation.
List<int> backUpArray = array.ToList();
for (int i = 0; i < array.Length; i++)
{
int newLocation = (i + (array.Length - rotationNumber)) % n;
array[newLocation] = backUpArray[i];
}
You can play nice in .net framework.
I understand that what you want to do is more up to be an iteration behavior than a new collection type; so I would suggest you to try this extension method based on IEnumerable, which will work with Collections, Lists and so on...
class Program
{
static void Main(string[] args)
{
int[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
IEnumerable<int> circularNumbers = numbers.AsCircular();
IEnumerable<int> firstFourNumbers = circularNumbers
.Take(4); // 1 2 3 4
IEnumerable<int> nextSevenNumbersfromfourth = circularNumbers
.Skip(4).Take(7); // 4 5 6 7 1 2 3
}
}
public static class CircularEnumerable
{
public static IEnumerable<T> AsCircular<T>(this IEnumerable<T> source)
{
if (source == null)
yield break; // be a gentleman
IEnumerator<T> enumerator = source.GetEnumerator();
iterateAllAndBackToStart:
while (enumerator.MoveNext())
yield return enumerator.Current;
enumerator.Reset();
if(!enumerator.MoveNext())
yield break;
else
yield return enumerator.Current;
goto iterateAllAndBackToStart;
}
}
Reasonable performance
Flexible
If you want go further, make a CircularList and hold the same enumerator to skip the Skip() when rotating like in your sample.
below is my approach. Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
public static int[] RightShiftRotation(int[] a, int times) {
int[] demo = new int[a.Length];
int d = times,i=0;
while(d>0) {
demo[d-1] = a[a.Length - 1 - i]; d = d - 1; i = i + 1;
}
for(int j=a.Length-1-times;j>=0;j--) { demo[j + times] = a[j]; }
return demo;
}
Using Linq,
List<int> temp = new List<int>();
public int[] solution(int[] array, int range)
{
int tempLength = array.Length - range;
temp = array.Skip(tempLength).ToList();
temp.AddRange(array.Take(array.Length - range).ToList());
return temp.ToArray();
}
If you're working with a string you can do this quite efficiently using ReadOnlySpans:
ReadOnlySpan<char> apiKeySchema = "12345";
const int apiKeyLength = 5;
for (int i = 0; i < apiKeyLength; i++)
{
ReadOnlySpan<char> left = apiKeySchema.Slice(start: i, length: apiKeyLength - i);
ReadOnlySpan<char> right = apiKeySchema.Slice(start: 0, length: i);
Console.WriteLine(string.Concat(left, right));
}
Output:
12345
23451
34512
45123
51234
I was asked to reverse a character array with minimal memory usage.
char[] charArray = new char[]{'C','o','w','b','o','y'};
Method:
static void Reverse(ref char[] s)
{
for (int i=0; i < (s.Length-i); i++)
{
char leftMost = s[i];
char rightMost = s[s.Length - i - 1];
s[i] = rightMost;
s[s.Length - i - 1] = leftMost;
}
}
How about using modular arithmetic :
public void UsingModularArithmetic()
{
string[] tokens_n = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(tokens_n[0]);
int k = Convert.ToInt32(tokens_n[1]);
int[] a = new int[n];
for(int i = 0; i < n; i++)
{
int newLocation = (i + (n - k)) % n;
a[newLocation] = Convert.ToInt32(Console.ReadLine());
}
foreach (int i in a)
Console.Write("{0} ", i);
}
So basically adding the values to the array when I am reading from console.