Why do something in one line of code when you can do it in a whole page?
This is what I was talking about in the comments. First I create a function that, when given a line of text, returns an array of integers:
public static bool TryGetLineOfNumbers (string line, out int[] numbers){
numbers = null; //out parameters must always be set, cover the failure case
var individualStrings = line.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
numbers = new int[individualStrings.Length];
// convert the strings into numbers, failing on a conversion error
for(var i = 0; i< individualStrings.Length; ++i){
if (!int.TryParse(individualStrings[i], out numbers[i])){
return false;
}
}
return true;
}
I'm way too lazy to type nine lines of numbers into a console, so I just created a hard-coded array of strings in my main function:
var testNumbers = new string[]{
"6 8",
"9 9 9 9 9 9 9 9",
"5 5 5 5 5 5 5 5",
"8 4 6 6 6 6 6 6",
"7 5 7 6 6 6 6 5",
"6 6 6 5 5 5 5 6",
"8 6 8 7 7 7 7 6",
"8 6 6 6 6 6 6 6",
"8 6 6 6 6 6 6 1",
};
My intention was to have a function that read the console and returned an IEnumerable<string> (so that I could use the hard-coded array or the function in my testing), but I couldn't get DotNet Fiddle to handle yield return properly (it also didn't like interpolated strings). That function (which didn't work) looked like:
public static IEnumerable<string> GetStringsFromConsole(){
var str = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(str)){
yield return str;
}
}
So, now my Main routine looks like:
public static void Main()
{
var testNumbers = new string[]{
"6 8",
"9 9 9 9 9 9 9 9",
"5 5 5 5 5 5 5 5",
"8 4 6 6 6 6 6 6",
"7 5 7 6 6 6 6 5",
"6 6 6 5 5 5 5 6",
"8 6 8 7 7 7 7 6",
"8 6 6 6 6 6 6 6",
"8 6 6 6 6 6 6 1",
};
//need to initialize these to keep the compiler happy
var lineNumber = 0;
int [,] numbers = null;
int[] dimensions = null;
foreach (var line in testNumbers)
{
++lineNumber; //i.e., it starts with one
if (lineNumber == 1) {
var firstLineValid = TryGetLineOfNumbers(line, out dimensions);
if (!firstLineValid || dimensions.Length != 2) {
throw new Exception ("The first line of text must have exactly two numbers");
}
numbers = new int[dimensions[0], dimensions[1]];
} else if (lineNumber < 4){
int[] ignoredNumbers;
var line23Valid = TryGetLineOfNumbers(line, out ignoredNumbers);
if (!line23Valid || ignoredNumbers.Length != dimensions[1]){
throw new Exception ("The second or third line is in the incorrect format");
}
} else {
int[] oneLine;
var normalLineValid = TryGetLineOfNumbers(line, out oneLine);
if (!normalLineValid || oneLine.Length != dimensions[1]){
throw new Exception ("Line " + lineNumber.ToString() + " is incorrectly formatted");
}
for(var i = 0; i < dimensions[1]; ++i){
numbers[lineNumber-4, i] = oneLine[i];
}
}
}
if (lineNumber != dimensions[0] + 3){
throw new Exception("Not enough inputted data");
}
//ok, got all the numbers, let's see them on the console:
for(var i = 0; i < dimensions[0]; ++i){
for(var j = 0; j < dimensions[1]; ++j){
Console.Write(numbers[i,j].ToString() + " ");
}
Console.WriteLine();
}
}
Yeah, it's a lot of code, but it's pretty self-explanatory. It also pays attention and validates the inputs. It's lightly tested
Reading the code over, it's probably worth refactoring the format and length test code (repeated three times) into a separate function, but that would be for another day.