4
\$\begingroup\$

I have solved this problem from SPOJ and the code runs well. I want to improve this code using C++11 or C++14.

Using two characters: . (dot) and * (asterisk) print a grid-like pattern. The grid will have l lines, c columns, and each square shaped element of the grid will have the height and width equal to s.

Moreover, each of the grid elements will have a diagonal. The diagonal of the first square in the first line of the grid is directed towards down and right corner - use the \ (backslash) character to print it; while the next diagonal will be directed towards upper right corner - use the / (slash) character to print it. Print the successive diagonals alternately (please consult the example below).

Input

You are given t - the number of test cases and for each of the test case three positive integers: l - the number of lines, c - the number of columns in the grid and s - the size of the single square shaped element.

Output

For each of the test cases output the requested pattern (please have a look at the example). Use one line break in between successive patterns.

Example

Input:

3

3 1 2

4 4 1

2 5 2

Output:

****
*\.*
*.\*
****
*./*
*/.*
****
*\.*
*.\*
****

*********
*\*/*\*/*
*********
*/*\*/*\*
*********
*\*/*\*/*
*********
*/*\*/*\*
*********

****************
*\.*./*\.*./*\.*
*.\*/.*.\*/.*.\*
****************
*./*\.*./*\.*./*
*/.*.\*/.*.\*/.*
****************

Time Limit 1s

Source Limit 50000 B

Memory Limit 1536 MB

Here is the code

#include <iostream>

using namespace std;

int main()
{
  int t;
  cin>>t;
  while(t--)
  {
    int l, c, s;
    cin >> l >> c >> s;
    int breadth = (c * (s + 1)) + 1;
    int height = (l * (s + 1)) + 1;
    for(int i = 0; i < height; i++)
    {
      for(int j = 0; j < breadth; j++)
      {
        if(i % (s+1) == 0 || j % (s+1) == 0)
        {
          cout << "*";
        }
        else if((i/(s+1) + j/(s+1)) % 2 == 0)
        {
          if(i % (s+1) == j % (s+1))
          {
            cout << "\\";
          }
          else
          {
             cout << ".";
          }
        }
        else
        {
          if(i % (s+1) == (s+1) - (j % (s+1)))
          {
            cout <<"/";
          }
          else
          {
            cout << ".";
          }
        }
      }
      cout << "\n";
    }
    cout << "\n";
   }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I don't see how this could benefit from C++11/14 techniques much - modern C++ gives you more tools mainly in terms of template metaprogramming, container algorithms, functional programming etc. You are dealing solely with primitive types and operate on streams, and newer standards haven't brought a revolution to these areas. The code is clean, variables have proper names etc, and that's why I'll stick to some general remarks.

Optimize I/O streams usage

Since you may possibly print a lot of information to std::cout, it might be a good idea to decouple it from the C streams. Synchronizing with C streams is associated with a significant performance hit, but necessary if you try to write to the stream concurrently or mix C and C++ streams - you are not doing any of these things though, so it's safe to do this at the start of your program:

std::ios_base::sync_with_stdio(false);

See this link for further information on this topic. Also, there are some benchamrks backing up this approach on SO, e.g. here.

Usually you don't have to care about the performance of I/O streams that much, but several times this trick helped me get to the top of the shortest execution times in coding exercises like this. Also it does make a difference if you are printing thousand of lines.

Don't use using-directive file-wide

It's considered a bad practice to put e.g. using namespace std; on top of the file as it may introduce subtle bugs when you use functions of the same name coming from different namespaces - it also requires manual checking to see from which namespace a particular function comes. It's not a problem in a simple program like that of course, but it's good to nurture good habits.

Put your code into proper function

Again, maybe you know it and it's just because this program is just a small competitive programming task, but usually you want to put your code inside a function of proper name, avoiding putting too much bare code inside main().

Make variables that are not to be mutated const

breadth and height are set once and never changed. Making them const would prevent you from accidentally mutating them while you expect them to hold their value. It also shows their role in the code better.

\$\endgroup\$
2
  • \$\begingroup\$ Will these improvement help in competitive programming? \$\endgroup\$
    – coder
    Sep 20, 2017 at 13:18
  • \$\begingroup\$ The first one, as I've written in my answer, may actually make a big difference since in competitive programming performance of I/O streams is often a bottleneck. In your particular case it's also important, because we know nothing about the limit of the number of lines and columns, so it's possible there would be hundreds of thousands of them. As for the other remarks - like I said in the answer, they are more applicable to regular projects rather than small programming exercises. \$\endgroup\$
    – KjMag
    Sep 20, 2017 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.