-1

I have a list of integers:

List <int> allPossibleValues;

The length of the password:

int passwordLength = 2;

I should generate all possible combinations of the password with the integers from the list:

List <int> allPossibleValues = new List<int>() { 1, 2, 4};
int passwordLength = 2;

Expected result:

List<string> { 
  "11", "22", "44", "12", "21", "14", "41", "24", "42" 
};

How can I create a logic to implement this?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
dimitri
  • 109
  • 6
  • 1
    See Amir's answer here: https://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer or pushpaj's answer here https://stackoverflow.com/questions/24349443/c-sharp-list-permutations-with-limited-length – Caius Jard Dec 26 '21 at 21:33
  • Specifically, I think you're actually looking for a *variation*, which is "some elements X from a larger set Y, where the order of the Xs matters" - https://www.codeproject.com/Articles/26050/Permutations-Combinations-and-Variations-using-C-G# is useful too. – Caius Jard Dec 26 '21 at 21:39
  • Does this answer your question? [All Possible Combinations of a list of Values](https://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values) – Mark Benningfield Dec 27 '21 at 02:54

2 Answers2

1

Well, you can put it like this:

Code:

using System.Linq;

...

// Let's do it a bit more general - <T> - and enumerate any items of alphabet 
private static IEnumerable<string> Passwords<T>(List<T> alphabet, int size) {
  int[] current = new int[size];

  do {
    yield return string.Concat(current.Select(i => alphabet[i]));

    for (int i = 0; i < current.Length; ++i)
      if ((current[i] = (current[i] + 1) % alphabet.Count) != 0)
        break;
  }
  while (!current.All(i => i == 0));
}

Demo:

List <int> allPossibleValues = new List<int>() { 1, 2, 4};
int passwordLength = 2;

string[] passwords = Passwords(allPossibleValues, passwordLength).ToArray();

var report = string.Join(", ", passwords);
      
Console.Write(report);

Outcome:

11, 21, 41, 12, 22, 42, 14, 24, 44
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • One major improvement you should do instead of `while (!current.All(i => i == 0));`, calculate the combo count by `var comboCount = (int)Math.Pow(n, k);` and then check whether you reached the combo count inside the while loop. – Charles Dec 26 '21 at 22:35
  • @Charles: if `alphabet` and `size` are *large*, say, `alphabet = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}` and `size = 1000` (`1e1000` possible passwords in total) will have at most `Math.Pow(n, k) == double.PositiveInfinity` and at least *integer overflow* for `comboCount` (we can even get *negative* `comboCount`) and thus either exception thrown or incorrect output. However, such *large* values *have sence*: we can well get, say, `100` passwords: `Passwords(allPossibleValues, passwordLength).Take(100).ToArray();` – Dmitry Bychenko Dec 26 '21 at 22:41
  • Ok, thank you for the explanation. I like this answer because its short. I still think we should not build on extreme edge cases, but i get your point and why it might be useful. I would not use this in my code, because i don't have a use case for Infinite Combinations. It's also a very weird way of OP to generate a "Password" – Charles Dec 27 '21 at 19:00
0

You could just use two for cycles to iterate through your Input list twice, combine the values and add the combined value to a new list.