0

How to generate numbers consists 2 digits with four digits number? Let's say the number is 1214.

It needs to create 12, 11, 14, 21, 24, 41, 42.

It skips consolidation 2 digits number. Digit position 3 with 1 will consolidation.

Cause, it already exists by position 1 with 3.

So far i just can generate 12, 21, 14. It still have other possibility.

class Program
{
    static void Main(string[] args)
    {
        char[] digits = { '1', '2', '1', '4' };

        List<string> numbers = new List<string>();

        for ( int i = 0; i < digits.Length; i++ )
        {
            ushort increment = 1;
            string number = String.Empty;

            if ( i != 3 )
            {
                number = digits[i].ToString() + digits[i + increment].ToString();
            }

            if ( i == 0)
            {
                numbers.Add(number);
            }
            else
            {
                // Compare to check element inside numbers already exists or not
                if ( numbers.Contains("number") == false)
                {
                    numbers.Add(number);
                }
            }
        }

        foreach ( string number in numbers)
        {
            Console.WriteLine(number);
        }        
    }
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
david stephen
  • 329
  • 4
  • 12
  • Does this answer your question? [Listing all permutations of a string/integer](https://stackoverflow.com/questions/756055/listing-all-permutations-of-a-string-integer) – LLSv2.0 Feb 20 '20 at 21:06
  • I am very confused by `if(numbers.Contains("number"))`. Did you mean `if (numbers.Contains(number))` ? Do you understand the large difference between those two code fragments? – Eric Lippert Feb 20 '20 at 22:50
  • 1
    A few things to improve in your code: (1) strings are indexible; you can just say `digits = "1214";` and the rest of the code will work the same. Strings are treated like read-only char arrays. (2) Don't say `if(x == false)`. Say `if(!x)`. It's better style. (3) You can avoid the containment check entirely by using `HashSet` instead of `List`. A hash set automatically discards duplicates for you. – Eric Lippert Feb 20 '20 at 22:53
  • 1
    (4) Do not use `ushort` in this manner. `ushort` exists for interoperability with legacy C/C++ code. Use an `int` to represent a small quantity. – Eric Lippert Feb 20 '20 at 22:54

2 Answers2

1

Here's the simplest way I could think of.

var number = 1214;
var text = number.ToString();

var query =
    from i in Enumerable.Range(0, text.Length)
    from j in Enumerable.Range(0, text.Length)
    where i != j
    select $"{text[i]}{text[j]}";

var results = query.Distinct().ToArray();

That gives me 12, 11, 14, 21, 24, 41, 42.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • You're probably going to want a `ToList()` after `Distinct()` to execute the query. – Eric Lippert Feb 20 '20 at 22:56
  • 1
    @EricLippert - Yes, agreed. I just did a `String.Join(", ", results).Dump();` in LINQPad to get the results to execute, but I left that out of the answer. I've updated the the answer to use `ToArray()` - I like the idea that I get back a list that I can't change - `List<>` is just too permissive, IMO. – Enigmativity Feb 20 '20 at 23:09
  • 1
    You can change an array; array elements are variables! – Eric Lippert Feb 20 '20 at 23:24
  • @EricLippert - Oh, yes, but I can't remove or add elements to an array without creating a new one. That's what I think is too permissive of `List<>`. Ideally I'd like to return a read-only array. – Enigmativity Feb 22 '20 at 06:43
  • @Enigmativity: If that's your concern, why not just return an `IENumerable` or a `ReadOnlyCollection` ? Mind you, my tendency is to avoid `ReadOnlyCollection` unless my goal is to be able to wrap an existing collection to avoid an allocation. – Brian Feb 24 '20 at 18:58
  • @Brian - Returning an `IEnumerable<>` means that I might have a lazy evaluation list - and that could be expensive. To return a `ReadOnlyCollection` I'd need to write my own extension method - and that would just clutter up my answers. Using `.ToArray()` is the compromise I choose. – Enigmativity Feb 24 '20 at 21:09
0

You can do like so:

    string str = "1214";
    string x;
    string y;
    int digitsCount = str.Count(c => char.IsDigit(c));
    if (digitsCount > 2) {    
        for (int i = 0; i < digitsCount; i++)
        {
            x = str.Substring(i, 1);
            for (int ii = i+ 1; ii < digitsCount ; ii++)
            {
               y = str.Substring(ii, 1);                      
               Console.WriteLine(x + " " + y);
            }
        }
    }

Remember to Add:

using System.Linq; 

.....I'm not sure I understand 41 and 42 though....

Heinrich
  • 36
  • 6