Print a List of ints as a matrix

Viewed 148

I have a List of 9 integers and I want to print all elements from the list as a matrix 3,3. And I have to avoid unnecessary white space on the end of every line. Is it possible to use String.Join ? Thanks.

Here's my code:

int[] input = Console.ReadLine().Split().Select(int.Parse).ToArray();

int[][] matrix = new int[input[0]][];

for (int i = 0; i < input[0]; i++)
{
    int[] line = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();

    matrix[i] = line;
}

List<int> arr = new List<int>(9);
List<int> arr1 = new List<int>(9);

arr = Enumerable.Repeat(0, 9).ToList();

//for (int i = 0; i < 9 ; i++) sum[i%3, i/3] = 0;

for (int row = 0; row < input[0] - 2; row++)
{
    for (int col = 0; col < input[1] - 2; col++)
    {
        arr1.Add(matrix[row][col]);
        arr1.Add(matrix[row][col + 1]);
        arr1.Add(matrix[row][col + 2]);
        arr1.Add(matrix[row + 1][col]);
        arr1.Add(matrix[row + 1][col + 1]);
        arr1.Add(matrix[row + 1][col + 2]);
        arr1.Add(matrix[row + 2][col]);
        arr1.Add(matrix[row + 2][col + 1]);
        arr1.Add(matrix[row + 2][col + 2]);

        if (arr1.Sum() > arr.Sum())
        {
            arr = arr1.Select(a => a).ToList();
        }
        arr1.Clear();
    }
}

Console.WriteLine($"Sum = {arr.Sum()} ");

// print the list as a matrix
4 Answers

This is how I would print it using String.Join:

List<int> asd = new List<int> {1,2,3,4,5,6,7,8,9};

for (int i = 0; i < asd.Count; i +=3)
{
    Console.WriteLine(string.Join(" ",asd.Skip(i).Take(3)));
}

Explanation: Walk in steps of 3. Skip the amount of numbers equal to the stepsize and take 3 to combine a row of the matrix.

Is that what you meant?

    string output = string.Empty;
    List<int> myList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    int counter = 0;
    foreach (int value in myList)
    {
        output += value.ToString();
        counter++;
        if (counter % 3 == 0)
        {
            Console.WriteLine(output);
            output = string.Empty;
        }
    }

Now You have your code pasted. Anyway, I created the sample to print the 3x3 matrix.

class Program
{
    static void Main(string[] args)
    {
        StringBuilder stringBuilder = new StringBuilder();
        List<int> numbers = new List<int>() {1,2,3,4,5,6,7,8,9 };


        for (int i = 0; i <3; i++)
        {
            int index = i * 3;
            stringBuilder.AppendFormat("{0}{1}{2}", numbers[index], numbers[index + 1], numbers[index + 2]);
            stringBuilder.AppendLine();
        }

        Console.Write(stringBuilder.ToString());
        Console.ReadLine();
    }
}

You should reconsider the accepted answer because the performance is poorly with many items.

It may be irrelevant for your current count of items but still hear my warning.

I ran the following code snippet:

var sb = new StringBuilder();
for (int i = 0; i < asd.Count; i +=3)
    sb.AppendLine(string.Join(" ", asd.Skip(i).Take(3)));
Console.WriteLine(sb.ToString());

used a StringBuilder to remove the time relevant Console.WriteLine(); for every item in the loop.

This approach takes 756,115ms to complete, with 1,000,000 items.

Created the asd list like this:

var asd = Enumerable.Range(0, 1000000).ToList();

Every other answer given so far will perform way better.

The reason why the accepted solution performs this poorly is because of the .Skip() that is getting called inside the loop, it doesn't actually skip and go directly to this Position instead it again and again loops the list till it reaches this point.

My solution would be:

Console.WriteLine(string.Concat(asd.Select((x, i) => (i + 1) % 3 != 0 ? x + " " : x + Environment.NewLine)));

Which executes the same task in 8,610ms

For completness:

  • Wojtek's solution takes: 7,932ms
  • Nirmal Subedi' solution takes: 8,088ms

Note:

Changed it so that it uses a StringBuilder to build the string and only output the string once to the console, instead of calling Console.WriteLine() in a loop

Here my complete test routine:

var asd = Enumerable.Range(0, 1000000).ToList();

var sw1 = new Stopwatch();
sw1.Start();
Console.WriteLine(string.Concat(asd.Select((x, i) => (i + 1) % 3 != 0 ? x + " " : x + Environment.NewLine)));
sw1.Stop();

var sw2 = new Stopwatch();
sw2.Start();

var sb1 = new StringBuilder();
for (int i = 0; i < asd.Count; i += 3)
    sb1.AppendLine(string.Join(" ", asd.Skip(i).Take(3)));
Console.WriteLine(sb1.ToString());

sw2.Stop();

var sw3 = new Stopwatch();
sw3.Start();

var sb2 = new StringBuilder();
int counter = 0;
string output = "";
foreach (int value in asd)
{
    counter++;
    if (counter % 3 == 0)
    {
        output += value;
        sb2.AppendLine(output);
        output = string.Empty;
    }
    else
        output += value + " ";
}
Console.WriteLine(sb2.ToString());
sw3.Stop();

var sw4 = new Stopwatch();
sw4.Start();

var sb3 = new StringBuilder();
for (int i = 0; i <asd.Count / 3; i++)
{
    int index = i * 3;
    sb3.AppendFormat("{0} {1} {2}", asd[index], asd[index + 1], asd[index + 2]);
    sb3.AppendLine();
}
Console.WriteLine(sb3.ToString());
sw4.Stop();

Console.WriteLine("MySolution: " + sw1.ElapsedMilliseconds);
Console.WriteLine("Mong Zhu's Solution: " + sw2.ElapsedMilliseconds);
Console.WriteLine("Wojtek's Solution: " + sw3.ElapsedMilliseconds);
Console.WriteLine("Nirmal Subedi's Solution: " + sw4.ElapsedMilliseconds);

Console.ReadKey();
Related