Find smallest number in given range in an array - c#

Hi i have an array of size N. The array values will always have either 1, 2, 3 integer values only. Now i need to find the lowest number between a given range of array indices. So for e.g. array = 2 1 3 1 2 3 1 3 3 2. the lowest value for ranges like [2-4] = 1, [4-5] = 2, [7-8] = 3, etc.
Below is my code :
static void Main(String[] args) {
string[] width_temp = Console.ReadLine().Split(' ');
int[] width = Array.ConvertAll(width_temp,Int32.Parse); // Main Array
string[] tokens_i = Console.ReadLine().Split(' ');
int i = Convert.ToInt32(tokens_i[0]);
int j = Convert.ToInt32(tokens_i[1]);
int vehicle = width[i];
for (int beg = i+1; beg <= j; beg++) {
if (vehicle > width[beg]) {
vehicle = width[beg];
}
}
Console.WriteLine("{0}", vehicle);
}
The above code works fine. But my concern is about efficiency. In above I am just taking one set of array range, but in actual there will be n number of ranges and I would have to return the lowest for each range. Now the problem is if there is a range like [0-N], N is array size, then I would end up comparing all the items for lowest. So I was wondering if there is a way around to optimize the code for efficiency???

I think it is a RMQ (Range Minimum Query) and there is several implementation which may fit your scenario.
Here is a nice TopCoder Tutorial cover a lot of them, I recommend two of them:
Using the notation in the tutorial, define <P, T> as <Preprocess Complexity, Query Complexity>, there is two famous and common implementation / data structure which can handle RMQ: Square Rooting Array & Segment Tree.
Segment Tree is famous yet hard to implement, it can solve RMQ in <O(n), O(lg n)> though, which has better complexity than Square Rooting Array (<O(n), O(sqrt(n))>)
Square Rooting Array (<O(n), O(sqrt(n))>)
Note That It is not a official name of the technique nor any data structure, indeed I do not know if there is any official naming of this technique since I learnt it...but here we go
For query time, it is definitely not the best you can got to solve RMQ, but it has an advantage: Easy Implementation! (Compared to Segment Tree...)
Here is the high level concept of how it works:
Let N be the length of the array, we split the array into sqrt(N) groups, each contain sqrt(N) elements.
Now we use O(N) time to find the minimum value of each groups, store them into another array call M
So using the above array, M[0] = min(A[0..2]), M[1] = min(A[3..5]), M[2] = min(A[6..8]), M[3] = min(A[9..9])
(The image from TopCoder Tutorial is storing the index of the minimum element)
Now let's see how to query:
For any range [p..q], we can always split this range into 3 parts at most.
Two parts for the left boundaries which is some left over elements that cannot be form a whole group.
One part is the elements in between, which forms some groups.
Using the same example, RMQ(2,7) can be split into 3 parts:
Left Boundary (left over elements): A[2]
Right Boundary (left over elements): A[6], A[7]
In between elements (elements across whole group): A[3],A[4],A[5]
Notice that for those in between elements, we have already preprocessed their minimum using M, so we do not need to look at each element, we can look and compare M instead, there is at most O(sqrt(N)) of them (it is the length of M afterall)
For boundary parts, as they cannot form a whole group by definition, means there is at most O(sqrt(N)) of them (it is the length of one whole group afterall)
So combining two boundary parts, with one part of in between elements, we only need to compare O(3*sqrt(N)) = O(sqrt(N)) elements
You can refer to the tutorial for more details (even for some pseudo codes).

You could do this using Linq extension methods.
List<int> numbers = new List<int> {2, 1, 3, 1, 2, 3, 1, 3, 3, 2};
int minindex =1, maxindex =3, minimum=-1;
if(minindex <= maxindex && maxindex>=0 && maxindex >=0 && maxindex < numbers.Count())
{
minimum = Enumerable.Range(minindex, maxindex-minindex+1) // max inclusive, remove +1 if you want to exclude
.Select(x=> numbers[x]) // Get the elements between given indices
.Min(); // Get the minimum among.
}
Check this Demo

This seems a fun little problem. My first point would be that scanning a fixed array tends to be pretty fast (millions per second), so you'd need a vast amount of data to warrant a more complex solution.
The obvious first thing, is to break from the loop when you have found a 1, as you've found your lowest value then.
If you want something more advanced.
Create a new array of int. Create a pre load function that populates each item of this array with the next index where it gets lower.
Create a loop that uses the new array to skip.
Here is what I mean. Take the following arrays.
int[] intialArray = new int[] { 3, 3, 3, 3, 2, 2, 2, 1 };
int[] searchArray = new int[] { 4, 4, 4, 4, 7, 7, 7, 7 };
So the idea is to find the lowest between positions 0-7.
Start at initialArray[0] and get value 3.
Read searchArray[0] and get the value 4. The 4 is the next index where the number is lower.
Read initialArray[4] and get the value 2.
etc.
So basically you'd need to put some effort to build the searcharray, but onces it's complete you would scan each range much faster.

Form your looping like the following:
int[] inputArray = { 2, 1, 3, 1, 2, 3, 1, 3, 3, 2 };
int minIndex = 2;
int maxIndex = 5;
int minVal = 3;
for (int i = minIndex; i <= maxIndex; i++)
{
if (inputArray[i] <= minVal)
minVal = inputArray[i];
}
Console.WriteLine("Minimum value in the Given range is ={0}", minVal);

Related

How do you compute for the moving average of a given dataset in C#?

So I use a randomly generated dataset and I need to find the moving average of the sample size the user inputted. For example, the dataset is a list with {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} and the sample size the user inputted is 2. The program must calculate first the mean of:
1 and 2 = 1.5, 2 and 3 = 2.5, 3 and 4 = 3.5,
and so on. How do I do this? Thanks! 😊
You can keep track of the sum and queue up all the values so you know what to subtract from the sum once you get to the sample size.
public static IEnumerable<decimal> MovingAverages(IEnumerable<decimal> values, int sample)
{
var queue = new Queue<decimal>(sample);
decimal sum = 0;
foreach(var x in values)
{
sum += x;
queue.Enqueue(x);
if(queue.Count == sample)
{
yield return sum / sample;
sum -= queue.Dequeue();
}
}
}
Basically this will queue up the first n values (equal to sample) and the sum. Once it gets the desired number of values to average it yields the sum divided by the sample size and then removes the oldest value from the queue and subtracts it from the sum. Note that if the sample size is larger than the number of values this will return an empty enumerable.
This can be done with a simple loop.
for (int i = 0; i <= array.Length - samplesize; i++)
Console.WriteLine(array.Skip(i).Take(samplesize).Average());
The Skip(i).Take(samplesize) portion selects only the elements you are interested in at the moment.

Divide List<string> into sublists of equal size N

I'm trying to slice a List of strings (size N) and return a range based on the list being sliced into equal parts (X).
So for instance, if I have a list of say 10 elements, and my number of tiers is 5.
Elements 0 and 1 are tier 1. Elements 2 and 3 are tier 2. At the end of the method I return the tier specified in the params.
What I'm struggling with is if the list count isn't divisible by the number of tiers. For instance, 23 / 5 = 4.6. So that means they'll be 5 sets of 4, and then 3 left over. I'd like the result to be 5 tiers of 5, 5, 5, 5, 3 (with the final tier just the remaining number of elements).
I've included my code so far, but I'm really stuck on how to ensure the list sizes are as equal as possible and how to handle remainders.
// Gets a list and returns a range by the tier specified
public List<string> GetRangeByTierIndex(List<string> listToDivide, int numOfTiers, int tierIndexToGet)
{
int numOfElementsPerList = listToDivide.Count / numOfTiers;
int index = (tierToGet - 1) * numOfElementsPerList;
return listToDivide.GetRange(index, numOfElementsPerList);
}
Note: Forgot to mention, I can't use LINQ for this either (AOT and iOS problems).
The idea is to use modulo which is remainder of division of listToDivide.Count by numOfTiers. If that remainder is greater than zero all tiers which index is less or equal to that remainder will have one more element. Because of that, start index of every tier must be corrected also. Note that I haven't wrote any checks (like if number of elements in main list is zero, numOfTiers < tierIndexToGet, etc... but you can add those checks if you need). Also, this will, for your example, give lists with 5, 5, 5, 4, 4 elements instead of 5, 5, 5, 5, 3 but I think this is even better. Anyway I hope it will be good for your needs. Code should look something like:
public List<string> GetRangeByTierIndex(List<string> listToDivide, int numOfTiers, int tierIndexToGet)
{
int remaining = listToDivide.Count % numOfTiers;
int numOfElementsPerList = listToDivide.Count / numOfTiers;
int index = (tierIndexToGet - 1) * numOfElementsPerList;
if (remaining > 0)
{
// most increase position of index because of numOfElementsPerList correction bellow
index += tierIndexToGet > remaining ? remaining : tierIndexToGet - 1;
// first 'remaining-th' tiers will have +1 element
numOfElementsPerList += tierIndexToGet <= remaining ? 1 : 0;
}
return listToDivide.GetRange(index, numOfElementsPerList);
}
Example: 23 and 5.
23/5 = 4 // 4 tiers of 5 - use integer division
23%5 = 3 // 1 tier of 3

Are there any algorithms to categorize an array among certain patterns?

For a simple problem of array length 5 to start with ( in practice the array length might be 20.. )
I have got a predefined set of patterns, like AAAAB, AAABA, BAABC, BCAAA, .... Each pattern is of the same length of the input array. I would need a function that takes any integer array as input, and returns all the patterns it matches. (an array may match a few patterns) as fast as possible.
"A" means that in the pattern all numbers at the positions of A are equal. E.g. AAAAA simply means all numbers are equal, {1, 1, 1, 1, 1} matches AAAAA.
"B" means the number at the positions B are not equal to the number at the position of A. (i.e. a wildcard for a number which is not A)Numbers represented by B don't have to be equal. E.g. ABBAA means the 1st, 4th, 5th numbers are equal to, say x, and 2nd, 3rd are not equal to x. {2, 3, 4, 2, 2} matches ABBAA.
"C" means this position can be any number (i.e. a wildcard for a number). {1, 2, 3, 5, 1} matches ACBBA, {1, 1, 3, 5, 1} also matches ACBBA
I am looking for an efficient ( in terms of comparisons number) algorithm. It doesn't have to be optimal, but shouldn't be too bad from optimal. I feel it is sort-of like the decision tree...
A very straightforward but inefficient way is like the following:
Try to match each pattern against the input. say AABCA against {a, b, c, d, e}. It checks if (a=b=e && a!=c).
If the number of patterns is n, the length of the pattern/array is m, then the complexity is about O(n*m)
Update:
Please feel free to suggest better wordings for the question, as I don't know how to make the question simple to understand without confusions.
An ideal algorithm would need some kind of preparation, like to transform the set of patterns into a decision tree. So that the complexities after preprocessing can be achieved to something like O(log n * log m) for some special pattern sets.(just a guess)
Some figures that maybe helpful: the predefined pattern sets is roughly of the size of 30. The number of input arrays to match with is about 10 millions.
Say, if AAAAA and AAAAC are both in the pre defined pattern set. Then if AAAAA matches, AAAAC matches as well. I am looking for an algorithm which could recognize that.
Update 2
#Gareth Rees 's answer gives a O(n) solution, but under assumption that there are not many "C"s. (otherwise the storage is huge and many unnecessary comparisons)
I would also welcome any ideas on how to deal with situations where there are many "C"s, say, for input array of length 20, there are at least 10 "C"s for each predefined patterns.
Here's an idea that trades O(2n) preparation and storage for O(n)-ish runtime. If your arrays are no longer than your machine's word size (you imply that 20 would be a typical size), or if there are not too many occurrences of C in the patterns, this idea might work for you. (If neither of these conditions is satisfied, avoid!)
(Preparatory step, done once.) Create a dictionary d mapping numbers to sets of patterns. For each pattern p, and each subset S of the occurrences of C in that pattern, let n be the number that has a set bit corresponding to each A in the pattern, and for each occurrence of C in S. Add p to the set of patterns d[n].
(Remaining steps are done each time a new array needs to be matched against the patterns.) Create a dictionary e mapping numbers to numbers.
Let j run over the indexes of the array, and for each j:
Let i be the j-th integer in the array.
If i is not in the dictionary e, set e[i] = 0.
Set e[i] = e[i] + 2ℓ − j − 1 where ℓ is the length of the array.
Now the keys of e are the distinct numbers i in the array, and the value e[i] has a set bit corresponding to each occurrence of i in the array. For each value e[i] that is found in the dictionary d, all the patterns in the set d[e[i]] match the array.
(Note: in practice you'd build the bitsets the other way round, and use 2j at step 3.3 instead of 2ℓ − j − 1, but I've described the algorithm this way for clarity of exposition.)
Here's an example. Suppose we have the patterns AABBA and ACBBA. In the preprocessing step AABBA turns into the number 25 (11001 in binary), and ACBBA turns into the numbers 25 (11001 in binary) and 17 (10001 in binary), for the two possible subsets of the occurrences of C in the pattern. So the dictionary d looks like this:
17 → {ACBBA}
25 → {AABBA, ACBBA}
After processing the array {1, 2, 3, 5, 1} we have e = {1 → 17, 2 → 8, 3 → 4, 5 → 2}. The value e[1] = 17 is found in d, so this input matches the pattern ACBBA.
After processing the array {1, 1, 2, 3, 1} we have e = {1 → 25, 2 → 4, 3 → 2}. The value e[1] = 25 is found in d, so this input matches the patterns AABBA and ACBBA.
Get the index of the first A in the pattern, get the value for that position, then loop through the positions.
To check if the array array matches the pattern in the string pattern, the result is in the boolean match:
int index = pattern.IndexOf('A');
int value = array[index];
bool match = true;
for (int i = 0; i < array.Length; i++) {
if (pattern[i] != 'C' && i != index) {
if ((pattern[i] == 'A') != (array[i] == value)) {
match = false;
break;
}
}
}

C#: Loop to find minima of function

I currently have this function:
public double Max(double[] x, double[] y)
{
//Get min and max of x array as integer
int xMin = Convert.ToInt32(x.Min());
int xMax = Convert.ToInt32(x.Max());
// Generate a list of x values for input to Lagrange
double i = 2;
double xOld = Lagrange(xMin,x,y);
double xNew = xMax;
do
{
xOld = xNew;
xNew = Lagrange(i,x,y);
i = i + 0.01;
} while (xOld > xNew);
return i;
}
This will find the minimum value on a curve with decreasing slope...however, given this curve, I need to find three minima.
How can I find the three minima and output them as an array or individual variables? This curve is just an example--it could be inverted--regardless, I need to find multiple variables. So once the first min is found it needs to know how to get over the point of inflection and find the next... :/
*The Lagrange function can be found here.** For all practical purposes, the Lagrange function will give me f(x) when I input x...visually, it means the curve supplied by wolfram alpha.
*The math-side of this conundrum can be found here.**
Possible solution?
Generate an array of input, say x[1,1.1,1.2,1.3,1.4...], get an array back from the Lagrange function. Then find the three lowest values of this function? Then get the keys corresponding to the values? How would I do this?
It's been a while since I've taken a numerical methods class, so bear with me. In short there are a number of ways to search for the root(s) of a function, and depending on what your your function is (continuous? differentiable?), you need to choose one that is appropriate.
For your problem, I'd probably start by trying to use Newton's Method to find the roots of the second degree Lagrange polynomial for your function. I haven't tested out this library, but there is a C# based numerical methods package on CodePlex that implements Newton's Method that is open source. If you wanted to dig through the code you could.
The majority of root finding methods have cousins in the broader CS topic of 'search'. If you want a really quick and dirty approach, or you have a very large search space, consider something like Simulated Annealing. Finding all of your minima isn't guaranteed but it's fast and easy to code.
Assuming you're just trying to "brute force" calculate this to a certain level of prcision, you need your algorithm to basically find any value where both neighbors are greater than the current value of your loop.
To simplify this, let's just say you have an array of numbers, and you want to find the indices of the three local minima. Here's a simple algorithm to do it:
public void Test()
{
var ys = new[] { 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4 };
var indices = GetMinIndices(ys);
}
public List<int> GetMinIndices(int[] ys)
{
var minIndices = new List<int>();
for (var index = 1; index < ys.Length; index++)
{
var currentY = ys[index];
var previousY = ys[index - 1];
if (index < ys.Length - 1)
{
var neytY = ys[index + 1];
if (previousY > currentY && neytY > currentY) // neighbors are greater
minIndices.Add(index); // add the index to the list
}
else // we're at the last index
{
if (previousY > currentY) // previous is greater
minIndices.Add(index);
}
}
return minIndices;
}
So, basically, you pass in your array of function results (ys) that you calculated for an array of inputs (xs) (not shown). What you get back from this function is the minimum indices. So, in this example, you get back 8, 14, and 17.

C# Calculate items in List<int> values vertically

I have a list of int values some thing like below (upper bound and lower bounds are dynamic)
1, 2, 3
4, 6, 0
5, 7, 1
I want to calculate the column values in vertical wise like
1 + 4 + 5 = 10
2 + 6 + 7 = 15
3 + 0 + 1 = 4
Expected Result = 10,15,4
Any help would be appreciated
Thanks
Deepu
Here's the input data using array literals, but the subsequent code works exactly the same on arrays or lists.
var grid = new []
{
new [] {1, 2, 3},
new [] {4, 6, 0},
new [] {5, 7, 1},
};
Now produce a sequence with one item for each column (take the number of elements in the shortest row), in which the value of the item is the sum of the row[column] value:
var totals = Enumerable.Range(0, grid.Min(row => row.Count()))
.Select(column => grid.Sum(row => row[column]));
Print that:
foreach (var total in totals)
Console.WriteLine(total);
If you use a 2D array you can just sum the first, second,... column of each row.
If you use a 1D array you can simply use a modulo:
int[] results = new results[colCount];
for(int i=0, i<list.Count; list++)
{
results[i%colCount] += list[i];
}
Do you have to use a "List"-object? Elseway, I would use a twodimensional array.
Otherwise, you simply could try, how to reach rows and columns separatly, so you can add the numbers within a simply for-loop. It depends on the methods of the List-object.
Quite inflexible based on the question, but how about:
int ans = 0;
for(int i = 0; i < list.length; i+=3)
{
ans+= list[i];
}
You could either run the same thing 3 times with a different initial iterator value, or put the whole thing in another loop with startValue as an interator that runs 3 times.
Having said this, you may want to a) look at a different way of storing your data if, indeed they are in a single list b) look at more flexible ways to to this or wrap in to a function which allows you to take in to account different column numbers etc...
Cheers,
Adam

Categories