0

I want to start by saying I am very new (1 week) into learning C#, so I sincerely apologize if this question is obvious. I do understand the reason for the exception, diverse.Length has to be 0 or greater. However, I am required to have the formula in my code so as to get the numbered-positions of the last 2 characters of an ever changing string (diverse).

Below, are 3 sets of code....

Firstly my working method.

static void Main(string[] args)
{
        try
        {
            // Sample data - inputs 3 ints.
            Console.WriteLine(Solution1(6, 1, 1));
            Console.WriteLine(Solution1(1, 3, 1));
            Console.WriteLine(Solution1(0, 1, 8));
            Console.WriteLine(Solution1(5, 2, 4));
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

}

static string Solution1(int A, int B, int C)
{

            string a = "a"; // a/b/c are added to string diverse when needed.
            string b = "b";
            string c = "c";
            string diverse = "";
            int totalLength = A + B + C; // Length of all 3 arrays

            for(int i = 1; i <= totalLength; i++) 
            {
                if (A >= B && A >= C && A > 0) { diverse = diverse + a; A = A - 1; }
                if (B >= A && B >= C && B > 0) { diverse = diverse + b; B = B - 1; }
                if (C >= A && C >= B && C > 0) { diverse = diverse + c; C = C - 1; }
            }
            return diverse;
}

What I am trying to do is add an additional check to my code. This check will take the printed letters and check to see if 2 of the same letter has previously been printed. If so, it will not print a 3rd. To do this I made a solution that would find the last 2 characters of the string (as I mentioned above) and compare it to the conditional check in the if statement.

Below is the code with this additional check, that I need to get working...

static string Solution1(int A, int B, int C)
{
    string a = "a"; // a/b/c are added to string diverse when needed.
    string b = "b";
    string c = "c";
    string diverse = "";
    int totalLength = A + B + C; // Length of all 3 arrays

    for (int i = 1; i <= totalLength; i++)
    {
        // Finds the last 2 characters in the diverse string.
        int LastTwoChars = diverse.Length - 2;
        string twoCharCheck = diverse.Substring(LastTwoChars, 2);

        if (A > 0 && B < 2 && C < 2 && twoCharCheck != "aa")
        {
            diverse = diverse + a; A = A - 1;
        }
        if (B > 0 && A < 2 && C < 2 && twoCharCheck != "bb")
        {
            diverse = diverse + b; B = B - 1;
        }
        if (C > 0 && B < 2 && A < 2 && twoCharCheck != "cc")
        {
            diverse = diverse + c; C = C - 1;
        }

    }
    return diverse;
}
DonalC93
  • 83
  • 7
  • At the start, `diverse` is assigned to "" (empty string), so its length is `0`. The first time through the loop, `LastTwoChars` (why does that start with a capital letter?) is set to `diverse.Length - 2`, so it's assigned the value `-2`. Then you try using that variable as the first argument to `Substring()`. BLAM! You get an exception because the beginning of a string is at index `0`, not `-2`. You should really learn how to use the debugger. You can step through each line of your code and see the values of variables as they change. – itsme86 Nov 04 '19 at 23:44
  • Suggestion: you should need to put `else` between `if` ? –  Nov 04 '19 at 23:46
  • Before you `// Finds the last 2 characters in the diverse string.`, you need to make sure the string has at least two characters. – Rufus L Nov 04 '19 at 23:47

2 Answers2

4

You can have the string check only after you have at least 2 characters:

int LastTwoChars = diverse.Length - 2;
string twoCharCheck = LastTwoChars >= 0 ? diverse.Substring(LastTwoChars, 2) : string.Empty; // identical with if (LastTwoChars >= 0) twoCharCheck = diverse.Substring(LastTwoChars, 2); else twoCharCheck = string.Empty


if (A > 0 && B < 2 && C < 2 && (LastTwoChars  < 0 || twoCharCheck != "aa")) // check the end only if you have at least 2 chars;
{
...
}
....

As you can see the code gets ugly very fast, so I would propose using a helper method:

// returns the last two chars in a string format, or a default user string
private static string LastTwoCharsOrDefault(string input, string default)
{
   var lastTwoCharsIdx = input.Length - 2;
   if (lastTwoCharsIdx > 0 )
   {
     return input.Substring(lastTwoCharsIdx, 2);
   }
   // we don't have at least 2 chars, so lets just return the default
   return default;
}

Then you can change your code like this:


if (A > 0 && B < 2 && C < 2 && string.Equals("aa", LastTwoCharsOrDefault(diverse, "aa"), StringComparison.OrdinalIgnoreCase))
...

You can find more about string comparison here.

Claudiu Guiman
  • 837
  • 5
  • 18
1

If I read your code right, you initialize Diverse as: string diverse = "";

and then execute string twoCharCheck = diverse.Substring(LastTwoChars, 2);

LastTwoChars is going to be -2 the first time through the loop.
Jon
  • 116
  • 4