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.
Related
This question already has answers here:
Find two sum function in c#
(15 answers)
Closed 1 year ago.
I'm trying to modify this algorithm which is of complexity O(n2) to something quicker.
the algorithm is supposed to do the following
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
Any help is appreciated.
using System.Collections.Generic;
public class Solution
{
public int[] TwoSum(int[] nums, int target)
{
int[] output = new int[2];
for (int i = 0; i < nums.Length; i++)
{
for (int n = 0; n < nums.Length; n++)
{
if ((nums[i] + nums[n]) == target)
{
output[0] = n;
output[1] = i;
}
}
}
return output;
}
}
In order to code an O(n) solution, you should loop the elements(numbers) of the array only one time. So, you need to store them in a dictionary. Keys will be numbers, Values will be their indexes. Then will check that is there any key whose value is equal to target - number in the dictionary. Dictionary<TKey, TValue> is a good choice for this problem.
public class Solution {
public int[] TwoSum(int[] nums, int target)
{
//Declare key-value dictionary to store numbers
var set = new Dictionary<int, int>();
//Loop each number in the array until find the complementary number.
for (var i = 0; i < nums.Length; i++)
{
//Assign the element of the array to a integer variable to have an elegant code.
var number = nums[i];
//If the dictionary contains the complementary number then return it.
if (set.ContainsKey(target - number))
{
return new[] {set[target - number], i};
}
//If the current number is not a complementary number then add it to the dictionary.
if (!set.ContainsKey(number))
{
set.Add(number, i);
}
}
//throw the right exception if there is no valid solution.
throw new ArgumentException();
}
}
Assuming that you have good hash function, you can have O(n) complexity. For each p within num you should check if q = k - p exists within num. You can do each each check with O(1) if you use hash based collection (here Dictionary<int, int[]>). The only little problem is p = q = k/2; here we should check if two equal items k/2 are in num.
using System.Linq;
...
public static int[] TwoSum(int[] nums, int k) {
if (nums == null)
throw new ArgumentNullException(nameof(nums));
var dict = nums
.Select((value, index) => new { value = (long)value, index })
.GroupBy(pair => pair.value, pair => pair.index)
.ToDictionary(group => group.Key, group => group.ToArray());
for (int i = 0; i < nums.Length; ++i) {
long p = nums[i];
long q = k - p;
if (dict.TryGetValue(q, out var array))
if (p != q)
return new int[] { i, array[0] };
else if (array.Length >= 2)
return new int[] { array[0], array[1] };
}
return new int[] { -1, -1 };
}
Here I've used long for dictionary key, p and q in order to cope with integer overflow
While everyone debates the fastest algorithm, the following code is quicker than O(n^2) it runs on average O(n log n) and in N space.
using System.Collections.Generic;
public class Solution
{
public int[] TwoSum(int[] nums, int target)
{
int[] output = new int[2];
for (int i = 0; i < nums.Length; i++)
{
for (int n = 1; n < nums.Length; n++)
{
if ((nums[i] + nums[n]) == target)
{
output[0] = n;
output[1] = i;
return output; //early exit giving O(n log n) vs (n^2)
}
}
}
return output; // degenerate case no solution exists
}
}
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've recently started learning C# (having learnt other languages) and I'm trying to create a function that generates the fibonacci sequence to the 'nth' term using a while loop and then returns the value of the 'nth' term.
My current code is this:
void fibonacci(int n)
{
int[] terms = { 0, 1 };
int i = 2;
while (i<=n)
{
terms.Concat( terms[i-1] + terms[i-2] );
i += 1;
}
return terms[n];
}
My understanding of C# is very poor as visual studio is telling me that I can't use 'Concat' with int[] - I'm trying to append the array with the new values. Any help would be great.
Arrays in C# are fixed length.
If you want to use a variable length collection, use a strongly typed List<T> instead, which has an Add method:
int fibonacci(int n)
{
var terms = new List<int>{ 0, 1 };
int i = 2;
while (i<=n)
{
terms.Add( terms[i-1] + terms[i-2] );
i += 1;
}
return terms[n];
}
You can't append to an array. In .Net, arrays have constant size and you can't resize them after creation.
Instead, you should use List<int> and its Add() method.
You can for example use list and change your code to:
int fibonacci(int n)
{
List<int> terms = new List<int> { 0, 1 };
int i = 2;
while (i<=n)
{
terms.Add(terms[i-1] + terms[i-2]);
i += 1;
}
return terms[n];
}
You can't add items to an array as it has fixed length. Use List<int> instead of array
I'm surprised nobody mentioned fixing the array size.
Well, maybe I'm missing something, but you could do:
int[] FibonacciArray(int n)
{
int[] F = new int[n+1];
F[0] = 0;
F[1] = 1;
for (int i = 2; i <= n; ++i)
{
F[i] = F[i - 1] + F[i - 2];
}
return F;
}
It's in average 2.5x faster than the version using a list.
But as often there is no free-lunch: the drawback is that your memory consumption is not smoothed: you pay upfront for all the memory you'll need.
Don't append values to an array. arrays have static size and you can't resize them after creation.
use
List<int> and its Add() method instead of array.
here is your solution for fibonacci series.
int fibonacci(int n)
{
var terms = new List<int>{ 0, 1 };
int i = 2;
while (i<=n)
{
terms.Add( terms[i-1] + terms[i-2] );
i += 1;
}
return terms[n];
}
also can be done like this :
class FibonacciSeries
{
static void Main(string[] args)
{
Console.WriteLine("Enter a num till which you want fibonacci series : ");
int val = Convert.ToInt32(Console.ReadLine());
int num1, num2;
num1 = num2 = 1;
Console.WriteLine(num1);
if (val > num2)
{
while (num2 < val)
{
Console.WriteLine(num2);
num2 += num1;
num1 = num2 - num1;
}
}
Console.ReadLine();
}
}
in your array format here is the solution
public int[] FibonacciSeriesArray(int num)
{
int[] arr = new int[num+1];
arr[0] = 0;
arr[1] = 1;
for (int startnum = 2; startnum <= num; startnum++)
{
arr[startnum] = arr[startnum - 1] + arr[startnum - 2];
}
return arr;
}
I would do it as a recursion, and not as a loop.
private static int fibonacci(int fib)
{
if (fib == 2 || fib == 1)
{
return 1;
}
else
{
return fibonacci(fib - 1) + fibonacci(fib - 2);
}
}
Here's a much more efficient way of finding fibonnaci numbers.
public static IEnumerable<double> FibList(int n)
{
for (int i = 1; i <= n; i++)
{
yield return Math.Round(Fib(i));
}
}
public static double Fib(double n)
{
double golden = 1.61803398875;
return (n == 0 || n == 1) ? 1 : (Math.Pow(golden, n) - Math.Pow(-golden, -n))/Math.Sqrt(5);
}
The method should work like Math.Max(), but take 3 or more int parameters.
You could use Enumerable.Max:
new [] { 1, 2, 3 }.Max();
Well, you can just call it twice:
int max3 = Math.Max(x, Math.Max(y, z));
If you find yourself doing this a lot, you could always write your own helper method... I would be happy enough seeing this in my code base once, but not regularly.
(Note that this is likely to be more efficient than Andrew's LINQ-based answer - but obviously the more elements you have the more appealing the LINQ approach is.)
EDIT: A "best of both worlds" approach might be to have a custom set of methods either way:
public static class MoreMath
{
// This method only exists for consistency, so you can *always* call
// MoreMath.Max instead of alternating between MoreMath.Max and Math.Max
// depending on your argument count.
public static int Max(int x, int y)
{
return Math.Max(x, y);
}
public static int Max(int x, int y, int z)
{
// Or inline it as x < y ? (y < z ? z : y) : (x < z ? z : x);
// Time it before micro-optimizing though!
return Math.Max(x, Math.Max(y, z));
}
public static int Max(int w, int x, int y, int z)
{
return Math.Max(w, Math.Max(x, Math.Max(y, z)));
}
public static int Max(params int[] values)
{
return Enumerable.Max(values);
}
}
That way you can write MoreMath.Max(1, 2, 3) or MoreMath.Max(1, 2, 3, 4) without the overhead of array creation, but still write MoreMath.Max(1, 2, 3, 4, 5, 6) for nice readable and consistent code when you don't mind the overhead.
I personally find that more readable than the explicit array creation of the LINQ approach.
Linq has a Max function.
If you have an IEnumerable<int> you can call this directly, but if you require these in separate parameters you could create a function like this:
using System.Linq;
...
static int Max(params int[] numbers)
{
return numbers.Max();
}
Then you could call it like this: max(1, 6, 2), it allows for an arbitrary number of parameters.
As generic
public static T Min<T>(params T[] values) {
return values.Min();
}
public static T Max<T>(params T[] values) {
return values.Max();
}
off topic but here is the formula for middle value.. just in case someone is looking for it
Math.Min(Math.Min(Math.Max(x,y), Math.Max(y,z)), Math.Max(x,z));
Let's assume that You have a List<int> intList = new List<int>{1,2,3} if You want to get a max value You could do
int maxValue = intList.Max();
Maximum element value in priceValues[] is maxPriceValues :
double[] priceValues = new double[3];
priceValues [0] = 1;
priceValues [1] = 2;
priceValues [2] = 3;
double maxPriceValues = priceValues.Max();
If, for whatever reason (e.g. Space Engineers API), System.array has no definition for Max nor do you have access to Enumerable, a solution for Max of n values is:
public int Max(int[] values) {
if(values.Length < 1) {
return 0;
}
if(values.Length < 2) {
return values[0];
}
if(values.Length < 3) {
return Math.Max(values[0], values[1]);
}
int runningMax = values[0];
for(int i=1; i<values.Length - 1; i++) {
runningMax = Math.Max(runningMax, values[i]);
}
return runningMax;
}
You could try this code:
private float GetBrightestColor(float r, float g, float b) {
if (r > g && r > b) {
return r;
} else if (g > r && g > b) {
return g;
} else if (b > r && b > g) {
return b;
}
}
This function takes an array of integers. (I completely understand #Jon Skeet's complaint about sending arrays.)
It's probably a bit overkill.
public static int GetMax(int[] array) // must be a array of ints
{
int current_greatest_value = array[0]; // initializes it
for (int i = 1; i <= array.Length; i++)
{
// compare current number against next number
if (i+1 <= array.Length-1) // prevent "index outside bounds of array" error below with array[i+1]
{
// array[i+1] exists
if (array[i] < array[i+1] || array[i] <= current_greatest_value)
{
// current val is less than next, and less than the current greatest val, so go to next iteration
continue;
}
} else
{
// array[i+1] doesn't exist, we are at the last element
if (array[i] > current_greatest_value)
{
// current iteration val is greater than current_greatest_value
current_greatest_value = array[i];
}
break; // next for loop i index will be invalid
}
// if it gets here, current val is greater than next, so for now assign that value to greatest_value
current_greatest_value = array[i];
}
return current_greatest_value;
}
Then call the function :
int highest_val = GetMax (new[] { 1,6,2,72727275,2323});
// highest_val = 72727275
You can use if and else if method for three values but it would be much easier if you call call twice Math.Max method like this
Console.WriteLine("Largest of three: " + Math.Max(num1, Math.Max(num2, num3)));
Console.WriteLine("Lowest of three: " + Math.Min(num1, Math.Min(num2, num3)));
If you don't want to repeatedly calling the Max function, can do like this
new List<int>() { A, B, C, D, X, Y, Z }.Max()
in case you need sorting as well:
var side = new double[] {5,3,4}
Array.Sort(side);
//side[2] is a maximum
as an another variant:
T[] GetMax<T>(int number, List<T> source, T minVal)
{
T[] results = new T[number];
for (int i = 0; i < number; i++)
{
results[i] = minVal;
}
var curMin = minVal;
foreach (var e in source)
{
int resComp = Comparer.DefaultInvariant.Compare(curMin, e);
if (resComp < 0)
{
int minIndex = Array.IndexOf(results, curMin);
results[minIndex] = e;
curMin = results.Min();
}
}
return results;
}
var source = new int[] { 5, 5, 1, 2, 4, 3 }.ToList();
var result = GetMax(3, source, int.MinValue);
I need to randomly 'sort' a list of integers (0-1999) in the most efficient way possible. Any ideas?
Currently, I am doing something like this:
bool[] bIndexSet = new bool[iItemCount];
for (int iCurIndex = 0; iCurIndex < iItemCount; iCurIndex++)
{
int iSwapIndex = random.Next(iItemCount);
if (!bIndexSet[iSwapIndex] && iSwapIndex != iCurIndex)
{
int iTemp = values[iSwapIndex];
values[iSwapIndex] = values[iCurIndex];
values[iCurIndex] = values[iSwapIndex];
bIndexSet[iCurIndex] = true;
bIndexSet[iSwapIndex] = true;
}
}
A good linear-time shuffling algorithm is the Fisher-Yates shuffle.
One problem you'll find with your proposed algorithm is that as you near the end of the shuffle, your loop will spend a lot of time looking for randomly chosen elements that have not yet been swapped. This may take an indeterminate amount of time once it gets to the last element to swap.
Also, it looks like your algorithm will never terminate if there are an odd number of elements to sort.
static Random random = new Random();
public static IEnumerable<T> RandomPermutation<T>(IEnumerable<T> sequence)
{
T[] retArray = sequence.ToArray();
for (int i = 0; i < retArray.Length - 1; i += 1)
{
int swapIndex = random.Next(i, retArray.Length);
if (swapIndex != i) {
T temp = retArray[i];
retArray[i] = retArray[swapIndex];
retArray[swapIndex] = temp;
}
}
return retArray;
}
modified to handle lists or other objects implementing IEnumerable
We can make an extension method out of this to get a Random enumerator for any IList collection
class Program
{
static void Main(string[] args)
{
IList<int> l = new List<int>();
l.Add(7);
l.Add(11);
l.Add(13);
l.Add(17);
foreach (var i in l.AsRandom())
Console.WriteLine(i);
Console.ReadLine();
}
}
public static class MyExtensions
{
public static IEnumerable<T> AsRandom<T>(this IList<T> list)
{
int[] indexes = Enumerable.Range(0, list.Count).ToArray();
Random generator = new Random();
for (int i = 0; i < list.Count; ++i )
{
int position = generator.Next(i, list.Count);
yield return list[indexes[position]];
indexes[position] = indexes[i];
}
}
}
This uses a reverse Fisher-Yates shuffle on the indexes of the list we want to randomly enumerate through. Its a bit of a size hog (allocating 4*list.Count bytes), but runs in O(n).
As Greg pointed out the Fisher-Yates shuffle would be the best approach. Here is an implementation of the algorithm from Wikipedia:
public static void shuffle (int[] array)
{
Random rng = new Random(); // i.e., java.util.Random.
int n = array.length; // The number of items left to shuffle (loop invariant).
while (n > 1)
{
int k = rng.nextInt(n); // 0 <= k < n.
n--; // n is now the last pertinent index;
int temp = array[n]; // swap array[n] with array[k] (does nothing if k == n).
array[n] = array[k];
array[k] = temp;
}
}
The implementation above relies on
Random.nextInt(int) providing
sufficiently random and unbiased
results
I am not sure of the efficiency factor, but I have used something similar to the following, if you aren't opposed to using an ArrayList:
private ArrayList ShuffleArrayList(ArrayList source)
{
ArrayList sortedList = new ArrayList();
Random generator = new Random();
while (source.Count > 0)
{
int position = generator.Next(source.Count);
sortedList.Add(source[position]);
source.RemoveAt(position);
}
return sortedList;
}
Using this, you do not have to worry about the intermediate swapping.
To improve your efficiency you can keep a set of values/indices that have been swapped rather than a boolean for indicating they were swapped. Pick your randomized swap index from the remaining pool. When the pool is 0, or when you made it through the initial list then you are done. You don't have the potential to try to select a random swap index value.
When you do a swap, just remove them from the pool.
For the size of data you are looking at it is no big deal.
itemList.OrderBy(x=>Guid.NewGuid()).Take(amount).ToList()
ICR's answer is very fast, but the resulting arrays aren't distributed normally. If you want a normal distribution, here's the code:
public static IEnumerable<T> RandomPermutation<T>(this IEnumerable<T> sequence, int start,int end)
{
T[] array = sequence as T[] ?? sequence.ToArray();
var result = new T[array.Length];
for (int i = 0; i < start; i++)
{
result[i] = array[i];
}
for (int i = end; i < array.Length; i++)
{
result[i] = array[i];
}
var sortArray=new List<KeyValuePair<double,T>>(array.Length-start-(array.Length-end));
lock (random)
{
for (int i = start; i < end; i++)
{
sortArray.Add(new KeyValuePair<double, T>(random.NextDouble(), array[i]));
}
}
sortArray.Sort((i,j)=>i.Key.CompareTo(j.Key));
for (int i = start; i < end; i++)
{
result[i] = sortArray[i - start].Value;
}
return result;
}
Note that in my tests, this algorithm was 6 times slower than the one ICR provided, however this is the only way I could come up with to get a normal result distribution
Wouldn't something like this work?
var list = new[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
var random = new Random();
list.Sort((a,b)=>random.Next(-1,1));
what about :
System.Array.Sort(arrayinstance, RandomizerMethod);
...
//any evoluated random class could do it !
private static readonly System.Random Randomizer = new System.Random();
private static int RandomizerMethod<T>(T x, T y)
where T : IComparable<T>
{
if (x.CompareTo(y) == 0)
return 0;
return Randomizer.Next().CompareTo(Randomizer.Next());
}
voila!
Here is what I used.
This is surely not the fastest one, but it is probably good enough for most cases and most importantly, it is very simple.
IEnumerable<ListItem> list = ...;
Random random = new Random(); // important to not initialize a new random in the OrderBy() function
return list.OrderBy(i => random.Next());
You can use a NuGet package called ListShuffle (source code) to shuffle a list in a thread-safe way using the Fisher-Yates algorithm, with optional cryptographically-strong random.
var myList = new List<string>();
myList.Add("Item A");
myList.Add("Item B");
myList.Add("Item C");
myList.Shuffle();
or (less performant but cryptographically-strong)
var myList = new List<string>();
myList.Add("Item A");
myList.Add("Item B");
myList.Add("Item C");
myList.CryptoStrongShuffle();
I made a method using a temporary Hashtable, allowing the Hashtable's natural key sort to randomize. Simply add, read and discard.
int min = 1;
int max = 100;
Random random;
Hashtable hash = new Hashtable();
for (int x = min; x <= max; x++)
{
random = new Random(DateTime.Now.Millisecond + x);
hash.Add(random.Next(Int32.MinValue, Int32.MaxValue), x);
}
foreach (int key in hash.Keys)
{
HttpContext.Current.Response.Write("<br/>" + hash[key] + "::" + key);
}
hash.Clear(); // cleanup