Number of nested loops at runtime - c#

I am trying to output all the possible unique integer combinations from 1 to max for a set number of integers. So for 3 integers and a max of 4 I would get:
123
124
134
234
I am doing this with nested for loops but I want to allow the user to input the number of integers at runtime. right now I have
if(numInts >6);
for(int x = 1; x < max; x++);
if(numInts >5);
for(int y = 1; y < max; y++);
...
Is there a way to clean this up so I don't have to write out each possible integer for loop.
PS: I know the code above will not output the requested output. This is for a programing competition so I am not asking for code solutions just the idea that would make this possible.

One word: Recursion.

Looking at your comments on the original post, you want an iterative solution. A recursive solution will be just as fast as an iterative solution when you have a language that supports tail call optimization. But if you're working with Java/C#, again, this isn't available, so here's another way to look at the problem.
You are generating combinations. A combination is just a subset with a certain number of elements. Subsets with small-ish sets can be expressed with bitmasks.
If I have the set [1, 2, 3, 4] and I want to describe the subset [1, 3, 4], I can do so by going through each element and asking "True or False: is this element in the subset?" So, for [1, 3, 4], the result is [True, False, True, True]. If I am working with a set less than 32 (or 64) bytes, I can encode this as an integer: 1011b = 11. This is very compact in memory and computers tend to have very fast bitmath operators.
So what is a combination then, in terms of these binary numbers? If I want all subsets with N members, I can translate that as "I want all numbers with N bits set."
Take [1, 2, 3, 4] as we have been. We want all subsets with 3 elements. How many 4-bit numbers are there with exactly 3 bits set? Answer: 1110b, 1101b, 1011b, and 0111b. If we turn these integers into subsets, we get your solutions: [1, 2, 3], [1, 2, 4], [1, 3, 4], and [2, 3, 4].
You can start thinking in terms of the bits only. You start off with the lowest number with N bits set. That corresponds to a solution. You then start flipping bits one-for-one. In a systematic way such that each iteration always results in the next highest number.

Use recursion, and numInts becomes the depth of your call tree.

Check out combinations on Wikipedia. These are what you are trying to generate.
EDIT: At first, I thought the OP meant permuations. The following code doesn't work for combinations, but I'll keep it here in case someone wants to tweak it to get it to work.
As others have said, this is a problem for which recursion excels at. Let's call your function pick(num, list). Here is some pseudo code.
List pick(Int num, List list)
{
if (num == 1) // base case
{
return list
}
else // recurring case
{
var results = []
foreach (item in list)
{
alteredList = list.copy().remove(item)
results.add([item] + pick(num - 1, alteredList))
}
return results
}
}
Some notes on the above code. Note the two cases. Recursion almost always follows the base-case/recurring-case format. The actual recursion occurs in the line results.add([item] + pick(num - 1, alteredList)), and the key point is that you pass num-1. This means that in each call to pick, num gets smaller and smaller until it reaches 1 (when it reaches 1, it's done).
The variable named alteredList is created as a COPY of list with the current item removed. Most languages have a removed method, but it ALTERS the original list (this is not what you want!!) Recursion works best when variables are immutable (when they aren't altered ever).
Lastly, I want to clarify the line [item] + pick(num - 1, alteredList) a bit. I simply mean create a new list, whose first element is item and the rest of the elements are the list returned by the call pick(num - 1, alteredList). In Lisp, this operation of adding an element to the front of a list is called a cons. This cons operation is extremely powerful in functional languages, where recursion is heavily used, but it is awkward to express in imperative languages, such as Java/C#.

Problems where you would need nested for-loops usually shout for recursion.
Imagine a tree like
<root>
<1>
<1>
<1>
<2>
<3>
<4>
<2>
<1>
<2>
<3>
<4>
...
then walk through the tree (recursivly) and collect the 'valid paths'

internal class Program {
private static void Main(string[] args) {
foreach (var combination in AllCombinations(new[] { 1, 2, 3 })) {
Console.WriteLine(string.Join("", combination.Select(item => item.ToString()).ToArray()));
}
}
private static IEnumerable<IEnumerable<T>> AllCombinations<T>(IEnumerable<T> elements) {
if (elements.Count() == 1) yield return new[] { elements.First() };
else {
foreach (var element in elements) {
foreach (var combination in AllCombinations(elements.Except(new[] { element }))) {
yield return (new[] { element }).Concat<T>(combination);
}
}
}
}
}

Related

Slice array into sub-arrays of varying sizes (C#)

While doing a code Kata, I've run into a slight logical problem that I can't figure out a solution to. It isn't a hard-and-fast requirement of completing the task but it has me intrigued as to how it could be handled.
The Kata is simulating applying pricing discounts and a supermarket checkout (see full Kata here) through a collection of pricing rules. To play around with some inheritance and interface capabilities, I've added a "Buy X, get Y free" rule. It works fine when the Y in question is 1, but starts getting a little hazy after that...
For example, I experimented with the idea of "Buy 3, get 2 free". I tried doing this by grouping the items in groups of 5, and working out the discount of each group by subtracting the price of two of the items:
public override double CalculateDiscount(Item[] items)
{
//per the example described above
//_groupSize = 5, _buy = 3
//meaning 2 out of every group of 5 items should be free
var discountGroups = new List<IEnumerable<Item>>();
for (var i = 0; i < items.Length / _groupSize; i++)
{
discountGroups.Add(items.Skip(i * _groupSize).Take(_groupSize));
}
return discountGroups
.Sum(group => group
.Skip(_buy)
.Sum(item => item.Price)
);
}
What I found is that the above code works as expected (if each item has a Price property of 1.00, the above would return 2.00). An edge case that I am looking to solve is that it doesn't take affect until the fifth item is added (so the price as you ad each item would go 1.00, 2.00, 3.00, 4.00, 3.00).
What I would ideally like is that, once you have three items in your collection, the next two items are free, whether you choose to take just one or two of them shouldn't affect the price. I understand this isn't hugely realistic to the domain, but I was interested in trying to solve it as a technical problem.
I've had a few cracks at it but haven't successfully gotten any closer than the above code. I figure that what I need to do is group the array into the minimum number of bought items required, then a variable number of free items. I could probably hard-code something to solve the issue once, but this gets complicated if I were to simulate buying 3 items and getting 2 free, then buying 3 items but only taking one free one.
Any advice on how to go about this would be really appreciated!
Thanks,
Mark
Your discount-calculation has some bugs, for example you dont create groups if the item-count is less than groupSize. So change i < to i <=:
for (var i = 0; i <= items.Length / groupSize; i++)
{
discountGroups.Add(items.Skip(i * groupSize).Take(groupSize));
}
Maybe that's already all.
I would just like to add that the extension method .Chunk() was added to the System.Linq namespace in .NET 6, and it does exactly what you are doing to create discountGroups; it splits the source collection into an IEnumerable of chunks of the requested chunk size:
source: { 1, 2, 3, 4, 5, 6, 7, 8 }
var chunks = source.Chunk(3);
chunks: { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8 } }
If the item count in the source enumerable is not exactly divisible by the wanted chunk size, the last chunk will simply consist of the remaining items (i.e. the last chunk may be smaller in size than the other chunks).
By using .Chunk(), you could therefore replace this:
var discountGroups = new List<IEnumerable<Item>>();
for (...)
{
discountGroups.Add(items.Skip(i * _groupSize).Take(_groupSize));
}
with this:
var discountGroups = items.Chunk(_groupSize).ToList();

Find smallest number in given range in an array

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);

How do make binary Search in list of structures in C#?

I want to ask how can I implement binary search in a List where I have 50,000 structures.
I sort this list by word like this listSub.OrderBy(s => s.word);
public struct SubItem
{
public string word;
public int count;
public SubItem(string word, int count)
{
this.word = word;
this.count = count;
}
}
I dont know how binary search in List<SubItem>. Can you help me?
The key to a binary search is that all of the items to the left of the center item are less than the center item, and to the right are all greater. The other key is that any given section of the list behaves as a sorted list in its own right, and thus that property still applies. So you keep breaking the list in half until you have found your element. This is usually done with recursion, with an empty list as the base case that the element does not exist in the list.
Here is some pseudocode to get you started:
find (list, start, end, target) {
if (start > end) // this is called a base case, look into recursion
return -1
center = (end - start) / 2
if list[center] == target // this is also a base case
return center;
else if list[center] > target
return find(list, start, center-1, target)
else
return find(list, center+1, end, target)
}
And we would run it like so:
list = [ 1 , 3, 7, 9, 12, 15, 17, 21, 28 ]
// need to find the target in the list
find(list, 0, list.length - 1, 3);
this would first look at 12, which is bigger than our target, so then it would split the list in half, look at the middle of the lesser half which is 3 and find it, returning its index. It tends to be more beneficial on larger and larger lists.
I said it uses recursion, which means two things: it will call itself until it finds an answer, and that when it finds the answer, it stops calling itself. There are two main kinds of recursion which you might find out about later, but the most important parts are those two: the recursive step (calling itself) and the base case (when it stops calling itself). Without those two parts something is not recursive.
Use ArrayList. It has a method named as BinarySearch.

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;
}
}
}

Bubble sort worst case example is O(n*n), how?

I am trying Bubble sort. There are 5 elements and array is unsorted. Worst case for bubble sort shuold be O(n^2).
As an exmaple I am using
A = {5, 4, 3, 2, 1}
In this case the comparison should be 5^2 = 25.
Using manual verification and code, I am getting comparison count to be 20.
Following is the bubble sort implemenation code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SortingAlgo
{
class Program
{
public static int[] bubbleSort(int[] A)
{
bool sorted = false;
int temp;
int count = 0;
int j = 0;
while (!sorted)
{
j++;
sorted = true;
for (int i = 0; i < (A.Length - 1); i++)
{
count++;
if(A[i] > A[i+1])
{
temp = A[i];
A[i] = A[i+1];
A[i+1] = temp;
sorted = false;
}
Console.Write(count + ". -> ");
for(int k=0; k< A.Length; k++)
{
Console.Write(A[k]);
}
Console.Write("\n");
}
}
return A;
}
static void Main(string[] args)
{
int[] A = {5, 4, 3, 2, 1};
int[] B = bubbleSort(A);
Console.ReadKey();
}
}
}
Output is following
-> 45321
-> 43521
-> 43251
-> 43215
-> 34215
-> 32415
-> 32145
-> 32145
-> 23145
-> 21345
-> 21345
-> 21345
-> 12345
-> 12345
-> 12345
-> 12345
-> 12345
-> 12345
-> 12345
-> 12345
Any idea why the maths its not coming out to be 25?
Big-O notation doesn't tell you anything about how many iterations (or how long) an algorithm will take. It is an indication of the growth rate of a function as the number of elements increases (usually towards infinity).
So, in your case, O(n2) simply means that the bubble sort's computational resources grows by the square as the number of elements. So, if you have twice as many elements, you can expect it to take (worst case) 4-times as long (as an upper bound). If you have 4-times as many elements, the complexity increases by a factor of 16. Etc.
For an algorithm with O(n2) complexity, five elements could take 25 iterations, or 25,000 iterations. There's no way to tell without analyzing the algorithm. In the same vein, a function with O(1) complexity (constant time) could take 0.000001 seconds to execute or two weeks to execute.
If an algorithm takes n^2 - n operations, that's still simplified to O(n^2). Big-O notation is only an approximation of how the algorithm scales, not an exact measurement of how many operations it will need for a specific input.
Consider: Your example, bubble-sorting 5 elements, takes 5x4 = 20 comparisons. That generalizes to bubble-sorting N elements takes N x (N-1) = N^2 - N comparisons, and N^2 very quickly gets a LOT bigger than N. That's where O(N^2) comes from. (For example, for 20 elements, you are looking at 380 comparisons.)
Bubble sort is a specific case, and its full complexity is (n*(n-1)) - which gives you the correct number: 5 elements leads to 5*(5-1) operations, which is 20, and is what you found in the worst case.
The simplified Big O notation, however, removes the constants and the least significantly growing terms, and just gives O(n^2). This makes it easy to compare it to other implementations and algorithms which may not have exactly (n*(n-1)), but when simplified show how the work increases with greater input.
It's much easier to compare the Big O notation, and for large datasets the constants and lesser terms are negligible.
Remember that O(N^2) is simplified from the actual expression of C * N(2); that is, there is a bounded constant. For bubble sort, for example, C would be roughly 1/2 (not exactly, but close).
Your comparison count is off too, I think, it should be 10 pairwise comparisons. But I guess you could consider swapping of elements to be another. Either way, all that does is change the constant, not the more important part.
for (int i=4; i>0; i--) {
for (int j=0; j<i;j++) {
if (A[j]>A[j+1]){
swapValues(A[j],A[j+1]);
................
Comparison count for 5 (0:4) elements should be 10.
i=4 - {(j[0] j[1]) (j[1] j[2]) (j[2] j[3]) (j[3] j[4])} - 4 comparisons
i=3 - {(j[0] j[1]) (j[1] j[2]) (j[2] j[3])} - 3 comparisons
i=2 - {(j[0] j[1]) (j[1] j[2])} - 2 comparisons
i=1 - {(j[0] j[1])} - 1 comparison

Categories