-2

I have a dictionary like this.

Dictionary<int, string> Diccionario = new Dictionary<int, string>(){
        {1,"124"}  ,  {4,"1457"}  ,  {7,"478"},
        {2,"1235"} ,  {5,"24568"} ,  {8,"05789"},
        {3,"236"}  ,  {6,"3569"}  ,  {9,"698"},
        {0,"08"}   
};

And I'd like to get all combinations for n integer. For example.

for n = 11 - 11, 12, 14, 21, 22, 24, 41, 42, 44.

for n = 24- 11, 14, 15, 17, 21, 24, 25, 27, 31, 34, 35, 37, 51, 54, 55, 57.

for n = 339 - 236, 256, 259...

And so on... But I don't have ANY IDEA how I could iterate through all of those numbers, since the lenght of every number isn't always the same. (1 has three possible combinations, 2 has four; and so on)

Thanks!

Since you guys asked me where does the data come from... It comes from here.

enter image description here

Imagine the PIN is 1273, then it's necessary to create all possible combinations based on the adjacent digit (horizontally and vertically) for example (1 has 2, 3 and the number itself), to make it easier I made the dictionary that can be seen earlier, giving each key its possible value.

Since the answer was closed, I'm not sure what kind of info more I could add, because I can't say too much about the problem. It's like if I had a dictionary of colors, for example:

Dictionary<int, string> Diccionario = new Dictionary<int, string[]>(){
        {1,{"red"}, {"blue"}, {"green"}} , 
        {2,{{"green"}, {"orange"} },
        {3, {{"dark"}}

};

So if I got the number 32 combinations would be: Dark Green or Dark Orange

Not sure If I'm ilustring my point.

Omar
  • 374
  • 1
  • 14
  • 2
    How does `n=11` have results from 11 to 44? And the other ones starting result below the n? Where does that minimum come from, if it is not realted to the value of n? – Christopher Feb 29 '20 at 15:16
  • 2
    I guess as soon as you provide some meaningful input for your data and the rules that create that output, you can solve this issue yourself. Currently I have no idea how those numbers are derived. There´s no 11, 31 or 24 or all those others. – MakePeaceGreatAgain Feb 29 '20 at 15:18
  • Sorry for the delay, I updated the post, so you can see where the data comes from... – Omar Feb 29 '20 at 15:34
  • 1
    "surrounding numbers (horizontally and vertically) for example (1 has 2, 3 and the number itself)" Nope. 1 has 2 and **4** as adjacent numbers. But beyond that, it is slowly beginning to make sense. My answer was on point: You need a `Dicitonary` – Christopher Feb 29 '20 at 15:36
  • When you get teh input of 11, what you want is just the results for 1. 1 is Duplicated, but onlöy the first one seems to mater. Similar with 339, wich is jsut 3+9. – Christopher Feb 29 '20 at 15:40
  • Sorry, I meant only adjacent digit (horizontally or vertically) – Omar Feb 29 '20 at 15:40
  • 3
    There more I understand the problem, the more this design is inherehntly wrong. Diccionario should be a `Dictionary`. Never turn perfectly good integers into string. String are terrible to work with. At best a nessesary evil for I/O | And n should also be a `int[]`. "1,1", "2,4" and "3,3,9" respectively. You should not turn two totally seperate and unrelated integers into a single one. – Christopher Feb 29 '20 at 15:48
  • I got this point, and you're right, I used string because I thought I should have to itereate through every value[it], not sure if you're understanding me. (And sorry for my english) but yeah, you're right, I didn't even think about int, int[]... Also, I updated the post since it was closed, trying to be more clearly, but not sure if I was. – Omar Feb 29 '20 at 15:52

2 Answers2

1

After some comments, I think I figured out your problems (there are more then one).

  • Diccionario should be a Dictionary<int, int[]>. String is a terrible type to work with. And as you do not seem to use the * and # keys, I see no call for char either.
  • Even a dictionary might go overboard. A simple indexed collection could also do it. You should normally only use it if the indexes are non-contiguoius. But for readability this dictionary can work here.
  • The input n is also not a single number, but an array of int[]

For input {3, 3, 9} you want all combinations of {2, 3, 6}, {2, 3, 6} and { 6, 8, 9}. It would be possible doing that with 4+ layers of nested loops, but you propably want to look into recursion. This is a inherently recursive operation.

I am at a big loss for naming the arguments and variables, however. That makes writing example code pretty hard.

Christopher
  • 9,634
  • 2
  • 17
  • 31
  • 1
    And how does this answer that completely unclear question? It´s just a list of merely related points to understand some concepts. – MakePeaceGreatAgain Feb 29 '20 at 15:32
  • @HimBromBeere I specifically quoted the QUesiton I asnwered. It *seems* to be a basic "nested itteration" question. – Christopher Feb 29 '20 at 15:35
  • @HimBromBeere I was 50% there. Now I am 100% there. – Christopher Feb 29 '20 at 15:57
  • @Christopher Wo, now I think I got it, at least I have some idea how could I make it works. Even thought I'm not sure how could I transform a nested itteration for(for(for))) into a recursive function. Thanks! – Omar Feb 29 '20 at 16:04
  • @Omar Conversion between loops and recursion is usually easy. However there is the rare case of a *inherently recursive* problems, that can not be tranformed effectively into a loop. This sounds like that rare case: https://youtu.be/HXNhEYqFo0o – Christopher Mar 10 '20 at 07:02
1

You are trying to do Cartesian product. This is solved here: Generating all Possible Combinations (all credits to Eric Lippert)

Using that function, the task is really easy:

private static readonly int[][] adjacent = new int[][]
    {
        new int[]{0,8},//0
        new int[]{1,2,4},//1  
        new int[]{1,2,3,5},//2
        new int[]{2,3,6},//3
        new int[]{1,4,5,7},//4  
        new int[]{2,4,5,6,8},//5
        new int[]{3,5,6,9},//6
        new int[]{4,7,8},//7
        new int[]{0,5,7,8,9},//8
        new int[]{6,9,8}//9                
    };

public static IEnumerable<IEnumerable<int>> GetCombinations(int[] input)
{
    if (input.Length == 0) { return new int[0][]; }

    return CartesianProduct(input.Select(n => adjacent[n]));
}

You replace every number in input with the array of adjacent numbers and do a Cartesian product. There is a special case for empty input, the CartesianProduct function returns one empty sequence, which is not the correct result I guess. It should return empty sequence of sequences.

Antonín Lejsek
  • 6,003
  • 2
  • 16
  • 18