Need an algorithm to calculate all variations (Combination Calculation) [duplicate] - c#

This question already has answers here:
Algorithm to return all combinations of k elements from n
(77 answers)
Closed 8 years ago.
I have a list which has always even item count.
I need an algorithm to find all two member combinations.
For instance if item count is 4, output will be;
Items:
{1, 2, 3, 4 }
ResulSet:
{12}, {34}
{13}, {24}
{14}, {23}
Order makes no difference, {12} covers {21}.
For item count 6, output will be;
Items:
{1, 2, 3, 4, 5, 6}
ResulSet:
12 34 56
12 35 46
12 36 45
13 24 56
13 25 46
13 26 45
14 23 56
14 25 36
14 26 35
15 23 46
15 24 36
15 26 34
16 23 45
16 24 35
16 25 34
Could you show me a way please?
Thank you.
Edit:
Question is really short to read, and if you take 1 minute to read question you can see it is not duplicate like most of people think (probably they are semi-illiterate)
Combination of {1, 2, 3, 4, 5, 6} is
123456 and as you see at top, this is not what I'm looking for. Read question if you want to help or just get off.
Have a nice day.

Since you always have two members in your combination, a simple nested for loop should work:
for (int i = 0; i < data.Length - 1; i++)
for (int j = i + 1; j < data.Length; j++
Console.WriteLine({0}{1}, i, j);
We iterate over each item in the list, up to the next to last one (since we can't have 1 number combos). In each of these iterations, we iterate from the outer iteration variable plus 1 (no duplicating elements) up to the end of the list.
This will generate all unique combinations. To do more than two or three member outputs though, you'll want to look into recursion. I'll leave formatting the output to match your question as an exercise to the reader :).
For 6 element combinations, we will have to delve into the wild world of recursion. Recursion can really mess with your head, so please ask if you don't understand something. The general principle of recursion is: "Do something with the first element, call yourself and pass the rest". In this situation, the code would look something like:
public List<List<int>> GetAllCombos (int[] values)
{
//Kick it off with the 0 index
return GetCombos(values, 0);
}
private List<List<int>> GetCombos(int[] values, int myIndex)
{
//A holder for combinations from this index onward
List<List<int>> combos = new List<List<int>>();
for (int i = myIndex; i < values.Length; i++)
{
if (myIndex + 1 < values.Length)
{
foreach (List<int> combo in GetCombos(values, myIndex + 1))
{
combo.Add(values[myIndex][i]);
combos.Add(combo);
}
}
else
{
List<int> newCombination = new List<int>() { values[myIndex][i] };
combos.Add(newCombination);
}
}
return combos;
}
Again, please make sure you ask if you don't understand something. Recursion can be a really tough concept to understand!

Have you done your research? 5 minutes (not even that) with google and I get:
Algorithms for Generating Permutations and
Combinations
Algorithms for Permutations and Combinations
Tree-Based Algorithms for Computing k-Combinations and k-Compositions
Combinatorial Algorithms
All of which would show you how to do this.
Searching SO, you pretty immediately find this question, Algorithm to return all combinations of k elements from n, with even more resources (not to mention actual solutions).
And if you're a member of IEEE or the ACM, a few seconds searching their online libraries will get you pretty much everything you need.

Related

set a sequence on a list of items

I need to set up a recursive function in C# to set the sequence number of a list of items. More specifically a bom. For each bom level, I need to start the sequence at 10, and increment of 10. How do I keep track of what level i'm at, and what counter to increment. This is driving me nuts.
Short example of data below, the real boms have thousands of lines and up to 12-15 levels.
Order
Level
Sequence
1
1
10
2
2
10
3
3
10
4
3
20
5
2
20
6
3
10
7
4
10
8
3
20
9
4
10
10
4
20
11
2
30
12
3
10
13
1
20
14
1
30
I indented the levels, to make the structure a bit more clear. And pasted the results of your answer to this. As you can see, the new levels are not sequenced properly.
I think i this case we can use the new language feature local function, and see if a recursive function is really necessary, as they are generally some of the hardest code to debug and maintain, only to be used sparingly, if at all this year, for any given year :)
[Fact]
public void SequencingRecursiveTest()
{
// BOM like byte order mark in utf 8 text encoding? odd problem :D
// Anyway we have a long list of values and want to emit the value with a sequence number, starting from 10 with increment 10
// Like in most cases when contemplating recursion, first off what about not using recursion to keep code maintainable and clean,
// As it turns out, we can:
//However super sneakily we have to reset all 'bom' sequence counts below the highest when an element in the sequence breaks the chain of same or greater
var keyValues = new Dictionary<int, int>();
var firstValue = 10;
var increment = 10;
int lastBom = 0;
int greatesBom = 0;
KeyValuePair<int, int> GetValueWithSequenceResetIfLowerThanLast(int bom)
{
bool reset = bom < lastBom;
greatesBom = bom > greatesBom ? bom : greatesBom;
if (reset)
{
foreach (int keyBom in keyValues.Keys)
{
if (keyBom < greatesBom)
keyValues[keyBom] = firstValue;
}
}
else if (keyValues.ContainsKey(bom))
{
keyValues[bom] = keyValues[bom] + increment;
}
else
{
keyValues.Add(bom, firstValue);
}
lastBom = bom;
return new KeyValuePair<int, int>(bom, keyValues[bom]);
}
var valueList = new List<int> { 1, 2, 3, 3, 2, 3, 4, 3, 4, 4, 2, 3, 1, 1 };
var valueSequenceList = valueList.Aggregate(
new List<KeyValuePair<int, int>>(),
(source, item) =>
{
source.Add(GetValueWithSequenceResetIfLowerThanLast(item));
return source;
}
);
foreach (var element in valueSequenceList)
System.Diagnostics.Debug.WriteLine($"{element.Key}: {element.Value}");
}

C# Code to print out prime numbers from 5 to N

Prime Number Generator Code
Do know that this question should be quite basic but i have spent hours trying to figure out why my code is stuck in the loop as below. Have added a Console.WriteLine($"{counttemp} , {count1} "); in the if loop to check the 2 numbers and seems like it is not breaking out of the if condition when the condition is true
this is the console output for the writeline in the if loop
5 , 5
6 , 2
7 , 7
8 , 2
9 , 3
10 , 2
11 , 11
12 , 2
13 , 13
14 , 2
15 , 3
16 , 2
17 , 17
18 , 2
19 , 19
Problematic Loop??
for (count1 = 2; count1 <= counttemp ; ++count1)
{
if(counttemp % count1 == 0)
{
Console.WriteLine($"{counttemp} , {count1} ");
Console.ReadKey();
primetest1 = 0;
break;
}
}
full code sequence
static void Main(string[] args)
{
int prime1 = 10000, count1, primetest1, counttemp;
for (counttemp = 5; counttemp <= prime1; counttemp++)
{
primetest1 = 1;
for (count1 = 2; count1 <= counttemp ; ++count1)
{
if(counttemp % count1 == 0)
{
Console.WriteLine($"{counttemp} , {count1} ");
Console.ReadKey();
primetest1 = 0;
break;
}
}
if (primetest1 == 1)
{
Console.Write($"{counttemp}");
}
}
}
You're almost there. The problem is that you're checking if your candidate number is a prime by getting the remainder when divided by each number up to and including the number itself.
I think you'll find that N is a factor of N for all values of N. To fix this, you should only be checking up to but excluding the number.
And, as an aside, you don't really need to check all the way up to N - 1. You only need to go to the square root of N, adjusted up to the nearest integer. That's because, if it has a factor above the square root, you would already have found a factor below it.
Consider 24 as an example. It has 6, 8, and 12 as factors above the square root, but the matching values below the square root are 4, 3, and 2 respectively.
And there's a another trick you can use by realising that if a number is a multiple of a non-prime, it's also a multiple of every prime factor of that non-prime. In other words, every multiple of 12 is also a multiple of 2 and 3.
So you only need to check prime numbers up to the square root, to see if there's a factor. And prime numbers, other than two or three, are guaranteed to be of the form 6x-1 or 6x+1, so it's quite easy to filter out a large chunk of candidates very quickly, by checking only for those values.
In other words, check two and three as special cases. Then start at 5 and alternately add 2 and 4: 5, 7, 11, 13, 17, 19, .... Not every number in that set is prime (e.g, 25) every prime is guaranteed to be in that set.
You can check out an earlier answer of mine for more detail on why this is so, and how to do this sequence efficiently.

Using Recursion to get combinations of Numbers in C# that equal the same sum

UPDATE: Okay I've revamped this question due to some negative people that merely want to complain rather than attempt to provide some sort of constructive help.
I know variations of this question have been asked, but I'm fairly certain mine is different.
I'm trying to do something similar to the tic tac toe Magic Box, but with a variation.
Traditionally, the Magic TicTacToe box refers to the numbers 1-9 and you're asked to arrange them in the tictactoe box in such a way that every iteration of the sets of 3 equal the same. In that sense, each run of 3 numbers would have to equal 15. With every possible direction, there's 8 sequences to test. The important part of the calculation is that the total sum of 1-9 is 45 and that divided by 3 is what tells you each run of 3 should equal 15.
Now, as I understand it, there's a form of recursion that would have to take place to run through the combinations of numbers, but I'm not quite sure how to do that. I'd like to be able to put a number (divisible by 3 and 9) in for an input and have it not only determine the unique (non-recurring) numbers it takes to get to that total, but how those numbers should be used.
Example:
I know I can simply divide a number by 9 to determine the median, which in this case already gives me one letter, which would be E in this case. I know I can simply run a couple for loops to get the remaining numbers. What I'm not sure how to do is figure out the recursion process to determine the correct assignment of each number.
Here's the example of the letter assignment:
G | F | A
H | E | B
I | D | C
You'd need the following combinations:
A+B+C
F+E+D
G+H+I
A+E+I
G+E+C
G+F+A
H+E+B
I+D+C
Now, what I'm not sure of, and the effect it could have, is the frequency in which each number is used. I know each of the above sequences would need to equal the number input divided by 3 would in this case would be 30, but I'm not sure what important facts can be used to create the proper nested for loops and/or if statements that sort through the list or array of numbers created and properly assign them based on their relevance.
Considering E is used 4 times (which is why it's the center), A,C,I, and G are used 3 times, and H,B,D, and F are used 2 times.
So, for clarification, I would like all of this to output what A,B,C, etc. should be equal to given the restrictions.
Thanks for any help.
As an additional request, although not required, but extremely appreciated - if you do provide an answer, explaining some of the important portions of the recursions, functions used and how it achieves my desired outcome would be great.
I think I've made my question clear at this point. In regards to someone's comment, yes I'm asking for the code, because I one am not proficient enough to figure out the complex use of recursion it would take to constantly check the needed constraints required, and two, no other questions really get into the kind of detail I feel I'm trying to go to. Most just what a normal statistical use of Combinations and Permutations, but it doesn't seem there's as many restrictions on the results, and/or their end goal is different.
For the sake of making some things clear, here's another edit:
Below is what I have to first generate the list of all the numbers that will be used.
int A, B, C, D, E, F, G, H, I;
Console.WriteLine("Choose a number that's all 9 spots added together.");
Console.WriteLine("Make sure the number is divisble by 3 and 9.");
int myNumber = int.Parse(Console.ReadLine());
int sums = myNumber / 3;
E = myNumber / 9;
if (E%1 != 0)
{
Console.WriteLine("You did not enter a value divisible by 3 and 9");
Console.WriteLine("Try again.");
Console.ReadLine();
}
else
{
List<int> list = new List<int>();
int lowest = E - 4;
for (int x = lowest;x < E; x++)
{
list.Add(x);
}
int highest = E + 4;
for (int y=E;y<highest;y++)
{
list.Add(y+1);
}
//Testing output
foreach (int i in list)
{
Console.WriteLine(i);
}
I made this to first see if I could establish the numbers that would be used, then go into finding all the variations of the numbers that would make all the lines equal the same. For example: if they entered 45, all directions would have to equal 15; if they entered 90, all directions would have to equal 30, etc.
Here you go. Knock yourself out.
Func<IEnumerable<int>, IEnumerable<int[]>> permutate = null;
permutate = ns =>
{
if (!ns.Skip(1).Any())
{
return new [] { ns.ToArray() };
}
else
{
return
from n in ns
from ns2 in permutate(ns.Except(new [] { n }))
select new [] { n }.Concat(ns2).ToArray();
}
};
var results =
permutate(Enumerable.Range(1, 9))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[n * 3] + ns[n * 3 + 1] + ns[n * 3 + 2] == 15))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[n] + ns[3 + n] + ns[6 + n] == 15))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[0] + ns[4] + ns[8] == 15))
.Where(ns => Enumerable.Range(0, 3).All(n => ns[2] + ns[4] + ns[6] == 15));
This gives:
2, 7, 6
9, 5, 1
4, 3, 8
2, 9, 4
7, 5, 3
6, 1, 8
4, 3, 8
9, 5, 1
2, 7, 6
4, 9, 2
3, 5, 7
8, 1, 6
6, 1, 8
7, 5, 3
2, 9, 4
6, 7, 2
1, 5, 9
8, 3, 4
8, 1, 6
3, 5, 7
4, 9, 2
8, 3, 4
1, 5, 9
6, 7, 2
I understand what #tekGiant is asking but I do not know how to answer it yet...
G | F | A
H | E | B
I | D | C
You'd need the following combinations:
A+B+C=X
F+E+D=X
G+H+I=X
A+E+I=X
G+E+C=X
G+F+A=X
H+E+B=X
I+D+C=X
Where X is the initial number that you designate to be the one that each of the different combinations add up to.

Express an integer as the sum of some other fixed integers

I have a fixed list of weights:
int[] weights = new int[] { 10, 15, 20 };
and a target:
int target = 28;
I am looking for an algorithm to express target as the sum of elements from weights (with repeats allowed) such that target is either matched or exceeded, the closest possible match to target is achieved, and within that, the number of weights used is minimised.
So with the above input I would like either 10 20 or 15 15 to be returned, since 30 is as close as we can get, and of the options for making 30, these two are better than 10 10 10.
With a target of 39, the output should be 20 20 rather than, say, 15 15 10 or 10 10 10 10.
With a target of 14, the output should be 15.
Is there a good approach here other than regular foreach loops? I was thinking of retreiving the largest value available in the array and check if the target is negative, if not then let's go for the next value.
This is not homework :)
This is known as the knapsack problem. The only difference is that you're looking for the nearest match, instead of the nearest lower match. Also fortunately none of the weights have a different value. The difficulty lies in that you cannot simply use one of the weights that comes closest and recurse using the remaining value (a combination of smaller values would sometimes make a better match).
In your example the weights all have 5 "units" in between, if this is always the case, the problem will become alot easier to solve.
I've managed to find a solution thanks to everyone here making it a bit more clear what I actually needed. It's not the prettiest code I've written but this is MVP development anyway!
private static List<int> WeightsJuggle(List<int> packages, IOrderedEnumerable<int> weights, int weight)
{
if (weight == 0)
return packages;
foreach (int i in weights.Where(i => i >= weight))
{
packages.Add(i);
return packages;
}
packages.Add(weights.Max());
return WeightsJuggle(packages, weights, weight - weights.Max());
}
I call it like this
IOrderedEnumerable<int> weights = new int[] { 10, 15, 20 }.OrderBy(x => x);
int weight = 65;
List<int> packages = new List<int>();
Test with weight 65
Test with weight 123

Different Sorting Orders - divide and conquer?

I'm trying to re-arrange a list of objects in different ways. Here I'll use integers but could be anything in this list.
The example code below sorts 1,2,3,4,5,6,7,8 into the following order:
1,8,2,7,3,6,4,5
So first. last. second. Second to last etc. It may be a bit clunky but it works.
Now what I'm trying to do now is to output the list in another order, so that it keeps dividing in two. I think this may be called Divide and Conquer but after trying / looking at some recursive sorting code etc. I'm not too clear on how to implement that here.
I hope to get the numbers ordered like this.
1,8,4,2,6,3,5,7
First, last, halfway, 1st half halfway, 2nd half halfway etc.
So in other words what I'm trying to do is to split the set of numbers in half... Then for each half in turn split those in half. And so on:
1 2 3 4 5 6 7 8
1 (first item)
8 (last item)
4 (mid item)
2 (mid of first half)
6 (mid of second half)
3 (mid of 1st chunk)
5 (mid of 2nd chunk)
7 (mid of 3rd chunk)
If anyone could anyone show me how to do this, with this simple example, that'd be really great.
static void Main(string[] args)
{
List<int> numberlist = new List<int>();
numberlist.Add(1);
numberlist.Add(2);
numberlist.Add(3);
numberlist.Add(4);
numberlist.Add(5);
numberlist.Add(6);
numberlist.Add(7);
numberlist.Add(8);
int rev = numberlist.Count-1;
int fwd = 0;
// order 1,8,2,7,3,6,4,5
for (int re = 0; re < numberlist.Count; re++)
{
if (re % 2 == 0)
{
Console.WriteLine(numberlist[fwd]);
fwd++;
}
else
{
Console.WriteLine(numberlist[rev]);
rev--;
}
}
Console.ReadLine();
}
Some more sample ranges and output, to be read left-to-right, top-to-bottom:
1 2 3 4 5 6 7
1 7
4
2 5
3 6
1 2 3 4 5 6 7 8 9 10 11 12
1 12
6
3 9
2 4 7 10
5 8 11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 16
8
4 12
2 6 10 14
3 5 7 9 11 13 15
Let me see if I understand the problem. Let's work an example with more items:
This is the order you want?
ABCDEFGHIJKLMNOPQ
A Q
I
E M
C G K O
B D F H J L N P
That seems straightforward. Create a data structure called "Interval" that has two fields: the Greatest Lower Bound and the Least Upper Bound. That is, what are the elements that are the biggest thing that is below the interval and the smallest thing that is above the interval. The algorithm goes like this:
Input: the size of the array.
Yield the first item -- if there is one
Yield the last item -- if it is different from the first item.
Make a queue of intervals.
Enqueue the interval (0, array.Length - 1)
While the queue is not empty:
Dequeue the queue to obtain the current item.
Is the interval empty? If so, skip this interval
Otherwise, the interval has a GLB, a LUB, and a value in the middle.
Yield the middle of the interval
Enqueue the interval (bottom, middle)
Enqueue the interval (middle, top)
Let's work the example above. We have the array ABCDEFGHIJKLMNOPQ.
Yield A
Yield Q
Enqueue A-Q. The queue is now A-Q
Is the queue empty? No.
Dequeue the queue. It is now empty.
current is A-Q
Is the current interval empty? no.
The middle is I.
Yield I.
Enqueue A-I. The queue is now A-I.
Enqueue I-Q. The queue is now A-I, I-Q.
Is the queue empty? No.
Dequeue the queue. It is now I-Q.
current is A-I.
Is the current interval empty? No.
The middle is E.
Yield E.
Enqueue A-E. The queue is now I-Q, A-E.
Enqueue E-I. The queue is now I-Q, A-E, E-I
Is the queue empty? No.
Dequeue. The queue is now A-E, E-I
current is I-Q
The middle is M
Yield M.
Enqueue I-M
Enqueue M-Q. The queue is now A-E, E-I, I-M, M-Q
OK, let's start skipping some steps here. The state of the queue and the yields are:
Yield C
E-I, I-M, M-Q, A-C, C-E
Yield G
I-M, M-Q, A-C, C-E, E-G, G-I
Yield K
M-Q, A-C, C-E, E-G, G-I, I-K, K-M
yield O
A-C, C-E, E-G, G-I, I-K, K-M, M-O, O-Q
yield B
C-E, E-G, G-I, I-K, K-M, M-O, O-Q, A-B, B-C
OK, skip more steps...
Yield D, F, H, J, L, N, P
Queue is now A-B, B-C, C-D, D-E, ... P-Q
Every interval is now empty, so we skip all of htem and we are done.
Make sense?
The trick here is to notice that the order you want is a breadth-first visit of a tree. You just have to be able to "see through" the array to the tree structure that you want to traverse.
Incidentally, the ordering seems a bit weird. The ordering for the most part seems to be "divide the range into two parts and yield the middle of each range first". Why then are the two extremes yielded first, instead of last? I would find the ordering:
ABCDEFGHIJKLMNOPQ
I
E M
C G K O
B D F H J L N P
A Q
more intuitively obvious; if the things "in the middle" always get priority over things "at the extremes" then the extremes should go last, not first.
I can demonstrate a similar selection; it results in a slightly different order to yours.
Take the numbers 0 to 7, and express them in binary: 000 001 010 011 100 101 110 111.
Now, reverse them: 000 100 010 110 001 101 011 111.
In decimal, this gives 0 4 2 6 1 3 5 7. So you start with the first element, then halfway through the rest of the elements, then a quarter and three quarters, and then finally all the odd-numbered elements.
Obviously this procedure only works for exact powers of two.

Categories