-1

I need to create a List<string> with strings of 50 length; like this results:

...0000000000
...0000000001
...000000000z
...0000000010
...000000001z
...00000000zz
...0000000100
...00000001zz
...zzzzzzzzzz

My code is

ConcurrentBag<string> bags = new ConcurrentBag<string>();

string schar = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

for (int a1 = 0; a1 < schar.length; a1++)
{
    ...
    // 48 nested for loops here 
    ...
    for (int a50 = 0 ; a50 < schar.length ; a50++)
    {
        bags.add($"{schar[a1]}{schar[a2]}{schar[a3]}......to a50");
    }
}

In this case, I can use 50 nested for loops to create this list, but the code is very unreadable. Is there any method to create this? Thanks.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
kotodev
  • 57
  • 6

1 Answers1

1

You can implement a simple generator:

private static IEnumerable<string> MyGenerator(
  int length, 
  string alphabeth = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") {

  char[] item = Enumerable
    .Repeat(alphabeth[0], length)
    .ToArray();

  do {
    yield return new string(item);

    for (int i = item.Length - 1; i >= 0; --i) {
      int index = alphabeth.IndexOf(item[i]);

      if (index < alphabeth.Length - 1) {
        item[i] = alphabeth[index + 1];

        break;
      }

      item[i] = alphabeth[0];
    }
  }
  while (!item.All(c => c == alphabeth[0]));
}

Demo:

  var result = MyGenerator(3)
    .Take(100);

  string report = string.Join(Environment.NewLine, result);

  Console.Write(report);

Outcome:

000
001
002
003
004
005
006
007
008
009
00A
00B
00C
00D
00E
00F
...
01Z
01a
01b

In your case it can be something like this:

  var list = MyGenerator(50) // 50 characters in each item
    .Take(1000)              // take 1000 top items
    .ToList();               // materialize as a list

Please, note Take: the entire list (if not restricted) will be of

 62**50 == 4.16e89

items, which is a huge number.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • thanks for `yield return`, this will not blow your RAM with 1.8938896e+79 terrabytes of strings – vasily.sib Oct 02 '18 at 08:32
  • @vasily.sib, at N e+79 e+12 byte, N=1 or 4 is not that big of a deal. There is 1.18e+57 atoms of hydrogen in the sun. Still 34 order of magnetude from that. It's so huge human brain min can easly be tricked by it. – Drag and Drop Oct 02 '18 at 09:00
  • @DragandDrop, I not sure what are you talking about:) all I mean is that as @kotodev is asking about getting all combinations of 50 symbol strings (`var list = MyGenerator(50).ToList();`) he must be prepared for a list of `62**50 (4.16e+89)` strings each of which is 50 bytes in length, so this is something about 1.89e+79 Tb of data. That's why `yield return` is extremly useful in this sample and that's why I upvote this answer. – vasily.sib Oct 02 '18 at 09:18
  • @vasily.sib, you corrected your math about Ram. My point was even if the original math was a bit wrong. It's so huge that it doesn't matter. e+79 Tb >>> to the number of atom of hydrogen in the sun. Thats how crazy the size is. If you consider that Tb is e+12byte. My aim was to to correct the math but to underline that you could have wrote 9,999, it would have hold the same value. It's an unrealistic amount of data. – Drag and Drop Oct 02 '18 at 09:29