Number Patterns 2
Hello coders : )
I hope you went through previous articles (I am optimistic, I'll take it as a yes ðŸ¤). Till now we solved many questions on star patterns and numeric patterns with 0s and 1s. These were the problems that utilised only 1 or 2 variables in the entire pattern. But now we'll use different mathematical numbers for creating number patterns.
Excited already? Let's go🚀
Numeric Square Patterns
In the last article, we practiced square patterns only by using 0s and 1s but now let's play with more numbers. Patterns would be same, user would input the no. of of rows and columns but now the pattern would be using a range of numbers and you would be writing the codes for the same.
So get ready coders! Here comes the problems..
Pattern 1
Input
rows = 5
cols = 5
Output
11111
22222
33333
44444
55555
Intuition
If you have read our previous articles, the you must have been familiar with the concept of using nested loops, outer one for printing rows and inner one for printing columns. But the question arises for what to print exactlty?
Here if you observe carefully, we print 1 in 1st row, 2 in 2nd row etc. So doesn't it make it obvious that we have to print our current row's value in that row. In coding terms, we'll print current row's value inside our inner loop.
Logic
- Run a loop on i from 1 to rows for iterating through rows.
- Run a loop on j from 1 to cols for iterating through columns.
- For each row the current row number is printed. Hence, in the inner loop, print the value of i to print current row number.
Solution
#include <iostream>
using namespace std;
int main() {
int rows, cols;
/* Input rows and columns from user */
cout << "Enter number of rows: "<<endl;
cin >> rows;
cout << "Enter number of columns: "<<endl;
cin >> cols;
for(int i = 1; i <= rows; i++) {
for(int j = 1; j <= cols; j++) {
// Print the current row number
cout << i;
}
cout << endl;
}
return 0;
}
Pattern 2
Input
rows = 5
cols = 5
Output
12345
12345
12345
12345
12345
Intuition
If we relate this to our previous problem, then it's exactly the same with just a minor change. Here rather than printing the current row, we print current column. Now, can you guess the change that we would have to do in our previous problem's code??
Rather than printing current_row's value, we'll print current_column's value. Simple, isn't it?
Logic
- Run a loop on i from 1 to rows for iterating through rows.
- Run a loop on j from 1 to cols for iterating through columns.
- For each column the current column number is printed. Hence, in the inner loop, print the value of j to print current column number.
Solution
#include <iostream>
using namespace std;
int main() {
int rows, cols;
/* Input rows and columns from user */
cout << "Enter number of rows: "<<endl;
cin >> rows;
cout << "Enter number of columns: "<<endl;
cin >> cols;
for(int i = 1; i <= rows; i++) {
for(int j = 1; j <= cols; j++) {
// Print the current row number
cout << j;
}
cout << endl;
}
return 0;
}
Pattern 3
Input
rows = 5
cols = 5
Output
12345
23456
34567
45678
56789
Intuition
Let's think once that we have to write this pattern manually. Then what I'll do is, write the first no. and then keep incrementing it as per the no. of columns. Example I'll write 2 for 2nd row and then increment it till 5 columns aren't filled.
Now let's focus on what would be our first value?
For 1st row, first value is 1
For 2nd row, first value is 2
For 3rd row, first value is 3
and so on.
Decoding this, we get that the first value of any row is equal to the current row number. But till what value do we need to increment it in following columns. Since, we know that we have to increment it till 5th column(total column value) starting from first column, means we have to go from current_row value to current_row+cols.
Understand it with observation:
If our current_row=1, then we go till 1+5=6
If our current_row=2, then we go till 2+5=7
If our current_row=2, then we go till 3+5=8
and so on.
These observations imply that our inner loop would run from current_row till current_row+cols. Note that the last value would be excluded and the inner loop would be constructed in the same way.
Logic
- Run a loop on i from 1 to rows for iterating through rows.
- Run a loop on j from row count i and go till i+cols like 'for(int j=i; j<i+cols; j++)'.
- Inside this loop we'll simply print j's value to achieve the desired output.
Solution
#include <iostream>
using namespace std;
int main() {
int rows, cols;
/* Input rows and columns from user */
cout << "Enter number of rows: "<<endl;
cin >> rows;
cout << "Enter number of columns: "<<endl;
cin >> cols;
for(int i = 1; i <= rows; i++) {
for(int j = i; j < i + cols; j++) {
cout << j;
}
cout << endl;
}
return 0;
}
Tired? Don't worry we are already midway💪 Think of the sense of achievement that you are going to have after ending this article! If not, then keep going 😄
Pattern 4
Input
rows = 5
cols = 5
Output
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Intuition
Let's think this pattern from a lazy person's perspective (yup that's me). This pattern seems like a single sequence of no. where I just add an enter when my desired columns (here 5) are filled. The sequence of numbers is a simple one: 1,2,3,4,5,6.........
According to the pattern, I'll simply start writing from 1 and keep incrementing the value till 5 columns are filled. As soon as I write the value for 5th column, I'll move to the next row and continue the sequence of no.s
This gives me 2 hints:
1. I need an external value to keep a track of the number in the sequence.
2. Keep printing this external value with adding appropriate breaks when a column ends
To manage the rows and columns, we'll simply run a nested loop with outer loop from 1 to rows and inner loop from 1 to cols to iterate over rows and columns. We'll define a variable k=1 outside these loops and keep incrementing it with the inner loop (every changing column).
Logic
- Run a loop on i from 1 to rows for iterating through rows.
- Run a loop on j from 1 to cols for iterating through columns.
- To print this pattern we will use another variable outside the loop: k=1 which will keep track of the number to be printed. Each time the number gets printed we will increment the value of k to get the next number.
Solution
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int rows, cols, k = 1;
/* Input rows and columns from user */
cout << "Enter number of rows: "<<endl;
cin >> rows;
cout << "Enter number of columns: "<<endl;
cin >> cols;
for(int i = 1; i <= rows; i++) {
for(int j = 1; j <= cols; j++, k++) {
// setw function is a C++ manipulator which stands for set width
// Here width's set for value 3 to give proper spacing between the values
cout << setw(3) << k;
}
cout << endl;
}
return 0;
}
Now let's see some pattern division problems. These problems are solved by dividing the given patterns into 2 or more different patterns. Sounding scary enough? Don't forget the initial suggestion: dry run is the key and you are good to go : )
Pattern 5
Input
rows = 5
cols = 5
Output
55555
54444
54333
54322
54321
Intuition
This pattern if observed carefully can be divided into two parts:
5----
54---
543--
5432-
54321
-5555
--444
---33
----2
-----
This indicates that there need to be 2 inner loops for each pattern inside one outer loop. The results of both the inner loops when combined will give us the desired final output.
To iterate through rows, we'll use a similar loop from 1 to rows as we used in our previous problems but need to break the columns.
Pattern 1: To print first part of pattern, we are printing the columns value in a decreasing fashion.
For row 1: We start from 5 and print all values that are greater than 4.
For row 2: We start from 5 and print all values that are greater than 3.
For row 3: We start from 5 and print all values that are greater than 2.
and so on.
What we observe here is that we are starting from the total columns value (5) and goes till 5-current_row. This indicates that we need to run a loop from 5 to 5-current_row or in generic terms: from cols to cols-current_row.
Pattern 2: Carefully observe the value that's printed and its frequency.
Row 1: Value = 5 Frequency = 4
Row 2: Value = 4 Frequency = 3
Row 3: Value = 3 Frequency = 2
and so on.
Decoding the pattern, value to be printed is equal to current row from the opposite end ( last row value for first row, 2nd last row value for 2nd row etc.)
This value is nothing but, total rows - current row +1.
For the frequency, it's equal to total columns - current row.
Hence we need to run the loop from (1 to total columns - current_row) and print (total rows - current row +1).
Logic
- To iterate through rows, run an outer loop from 1 to rows (where rows is total rows to be printed).
- Pattern 1: Run an inner loop on j starting from total columns going till total columns – current_row. In this example, total columns value is 5. Inside this loop keep printing the value of j.
- Pattern 2: Run another inner loop from 1 to total columns – current_row. Inside this loop print the value of rows – current row + 1.
Solution
#include <iostream>
using namespace std;
int main() {
int rows, cols, i, j;
// Input rows and columns from user
cout << "Enter number of rows: "<<endl;
cin >> rows;
cout << "Enter number of columns: "<<endl;
cin >> cols;
// i refers to current row
for (i = 1; i <= rows; i++) {
//Loop 1 runs j from cols to cols - current_row and print this j value
for (j = cols; j > cols - i; j--) {
cout << j;
}
//Loop 2 runs j from 1 to cols - current_row and print row-i+1 value
for (j = 1; j <= cols - i; j++) {
cout << rows - i + 1;
}
cout << endl;
}
return 0;
}
Pattern 6
Input
rows = 5
cols = 5
Output
55555
44445
33345
22345
12345
Pattern Division
This pattern if observed carefully can be divided into two parts:
5555-
444--
33---
2----
-----
----5
---45
--345
-2345
12345
Relating to the last problem, we need 2 inner loops for each pattern inside one outer loop. The results of both the inner loops when combined will give us the desired final output.
Outer loop
For the outer loop, we need to observe that the pattern seems decreasing in our first pattern, and so we need to compare the current rows to the opposite ones (print 5 for first, 4 for second, 3 for third etc.)
There's a trick that I use to escape from this first-last analogy but promise me you'll keep it secret🤫
An active person like you would suggest run a loop from 1 to rows and print total rows - current row + 1. But a lazy person like me would simply run a loop from rows to 1 and print the current_row value. (It would be automatically reversedðŸ¤)
Same thing we are going to do in this and in many upcoming articles. We would run our loop from 5 to 1 (rows to 1) so that we can simply print the current row rather than total rows - current row + 1. Remember that the other way is also right but this one will will simplify our variables.
Note: In this question, current_row reference means the opposite row only (i.e like 5, 4, 3, 2, 1) and not the actual current_row (1,2,3,4,5) due to the decreasing loop
Inner loop 1
Focusing on the value's frequency in first question, it's decreasing (4->3->2->1: i decreases with increasing row). This pattern when generalised is nothing but current_row - 1. Hence, we would run a loop from 1 to current_row - 1. Also, the printed value in first pattern is 5,4,3,2,1 i.e. the current_row's value. Hence, we would print current_row's value and 'current_row - 1' times.
Inner loop 2
In the 2nd pattern, we are directly printing the column's value. The range of this value clearly ends at the last row. But where does it start?
We print from 5th column in 1st row
from 4th column in 2nd row
from 3rd column in 3rd row
and so on.
The starting column is nothing but the 'current_row' of this pattern. Hence, the loop will run from current_row to cols and prints the column value.
NOTE: Notice that how much the change in our outer loop (from rows to 1) has simplified our code in both the patterns. In other words, emphasise on the direct usage of current_row variable: we have directly used it multiple times without needing to change it as in the case of increasing outer loop (from 1 to rows).
Logic
- To iterate through rows, run an outer loop on i from rows to 1 (where rows is total rows to be printed).
- Pattern 1: Run an inner loop on j from 1 to i-1 printing the i value.
Note: Value to be printed is i as i's value is decreasing with every row as required by the pattern. This is the reason that we made our outer loop from rows to 1 rather than 1 to rows. - Pattern 2: Run an inner loop on j starting from i to the total no. of columns and keep printing the jth value.
Solution
#include <iostream>
using namespace std;
int main() {
int rows, cols;
/* Input rows and columns from user */
cout << "Enter number of rows: " << endl;
cin >> rows;
cout << "Enter number of columns: " << endl;
cin >> cols;
for (int i = rows; i >= 1; i--) {
for (int j = 1; j <= i - 1; j++) {
cout << i;
}
for (int j = i; j <= cols; j++) {
cout << j;
}
cout << endl;
}
return 0;
}
Tired or confident? Former might be the case but it's temporary and the latter one is permanent! These patterns can be mind-boggling but as suggested before - dry run the codes! Dry running examples while solving problems is a habit that you should always follow while solving any type of problem because if you do that, you'll retain and understand it more as your brain will always relate it to an example.
"Remember Practice leads to Perfection".
Now let's end this article and be ready for what's coming next : )