Creating a pyramid of numbers with a certain logic - c++

I need a program that will output this figure:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
If you add the numbers on both ends, it will print the output beside it (inward). And then you will also add those two sums and print it again inwardly. Another thing, the input should be the largest number (in this case, number 8) It could be larger than 8 like the figure below.
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
In this case the input is 16. And so on. This is my latest program.
#include<iostream>
using namespace std;
int main(){
int i, j, k, b, a, space=10;
for(int i=0;i<=5;i++){
for(k=0;k<space;k++){
cout<<" ";
}
for(j=1;j<=2*i-1;j=j*2){
cout<<j<<" ";
}
space--;
cout<<endl;
}
system("pause");
return 0;
}
Please help me improve this. It's not yet a pyramid. Help me to output the desired figure at least.

To correctly format your pyramid, supposing you're using fixed width characters, you need to know beforehand some information, e.g.:
what is the largest number that you're going to print.
how many numbers have which width.
Since the pyramid is increasing downwards, this information is available when you print the last line.
So what you need to do is to calculate (but not output, of course) the last line first. Say that you want five rows, then the middle number will be 2^(5-1), i.e. 16. So you will have to output 1 2 4 8 16. The column positions will be 0 (beginning), 2 (0 plus length of "1" plus 1 space), 4 (2 plus 1 plus 1 space), 6 (4 plus 1 plus 1), 8, 11 (8 plus length of "16" which is 2, plus 1 space), 13, 15, 17.
At this point you start output of the first line, beginning at column 5, i.e. at position 8.
The second line will start at column 4, i.e. at position 6.
And so on.
Another possibility is to imagine you're filling a table (as if you were generating a HTML table):
- fill it top to bottom
- "explore" every cell size the same way as above, in any order
- generate column positions accordingly
- print the table top to bottom
This requires only one round of calculations, but needs memory storage for the table itself.
A shortcut is to verify what is the largest number you're gonna print, and format all columns with that width. In this case 16 is 2 characters, so you add one space padding and output all columns padded to 3 character width. This may waste unnecessary space.
The latter case can be implemented using cout.width:
int main() {
int line;
// Read input from standard input
cin >> line;
// We output the pyramid by allocating a fixed width to each number.
// This requires to know beforehand which will be the largest number.
// We can observe that at every line, the largest number is 2 to the
// power of that line number: on line 0, the largest number is 2^0
// which is 1, on line 1 it is 2 which is 2^1... on line 4 it is 16
// which is 2^4. So if we have five lines (from 0 to 4), the largest
// number will be 2 to the 4th.
// Now the length of a number in base 10 is given by the logarithm
// base 10 of that number, truncated, plus 1. For example log10 of
// 1000 is exactly 3, and 3+1 is 4 digits. Log10 of 999 is
// 2.9995654... which truncates to 2, 2+1 is 3 and 999 is 3 digits.
// Here our number is 2 to the power of (line-1).
// By the properties of the logarithm
// this is the same as (line-1)*log10(2), and log10(2) is around 0.3.
// So we multiply (line-1) by log10(2), truncate to integer and add 1
// (or vice versa: we add 1 and then assign to width, which is an
// integer, thereby truncating the value to integer.
// But we need to add another 1 for the padding space (we want 1 2 4
// 2 1, not 12421...). So before assigning, we add 2, not 1.
int width = 2+(line-1)*0.30102999566398119521373889472449;
//////////////////////
// TODO: we're gonna output 2*line+1 strings, each 'width' wide.
// So if (2*line+1)*width > 80 we'd better say it and stop, or the
// output will be sorely messed up, since a terminal is only 80 chars
// wide at the most. Which means that N=9 is the maximum number we
// can print out and still be "nice".
// Having not been asked to do this, we proceed instead.
//////////////////////
// For every line that we need to output...
for (int i = 0; i < line; i++) {
// Pad line-i empty spaces
for (int j = 0; j < (line-i); j++) {
// Set the width of the next cout to "width" bytes
cout.width(width);
cout<<" ";
}
int n = 1;
// output the forward sequence: 1, 2, 4... doubling each time
for (int j = 0; j < i; j++) {
cout.width(width);
cout <<n;
n *= 2;
}
// output the top number, which is the next doubling
cout.width(width);
cout <<n;
// output the sequence in reverse. Halve, output, repeat.
for (int j = 0; j < i; j++) {
n /= 2;
cout.width(width);
cout<<n;
}
// Now n is 1 again (not that we care...), and we output newline
cout <<"\n";
}
// Return 0 to signify "no error".
return 0;
}

Check the Code. This will give the desire output .
#include<iostream>
using namespace std;
int main(){
int line = 4;
for (int i =0; i < line; i++){
for(int j = line - i; j >0 ; j --){
cout<<" ";
}
int temp = 1;
for(int k = 0; k < i + 1; k ++){
cout << " "<<temp;
temp = temp *2;
}
temp /=2;
for(int k =0; k < i; k ++){
temp /=2;
cout << " "<<temp;
}
cout <<"\n";
}
return 0;
}
Output:
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1

Related

Read to array from table in text file, while skipping specific column

I am trying to read the contents of a text file into 2D array in C++. The file contains 125 rows with 21 columns of integers (a table of integers). I'm to read this into an array that is 125 rows of 20 columns, skipping column 21 of the file.
I defined the size of the array with variables, but it just reads column 21 into the next row, ignoring the new line. I need it to start each row in the array at the start of the new line from the file but ignore the last item in the table.
I'm not sure if I'm looking for it to skip column 21, or if I'm looking for it to start reading each column at a new line (or both?)
Text file looks like (is this called a matrix?) and it's number separated by 1 space and \n at end.
(The text file was generated by a program to generate rows of 20 numbers and the sum.)
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 93
" etc
Other solutions I've found can be difficult for me to understand because people write their variables and functions non-descriptively. Some solutions require advanced methods I'm not supposed to use as well, such as vectors and string manipulation. I have currently learned everything before "pointers" so I can only use solutions I've learned in class. I've learned functions, arrays, search/sort, and basics like operators, loops, variables, etc. I'm not supposed to use vectors for this or string manipulation.
I will (eventually) have to sum the numbers in the array (after I extract the first 20 of each row from the file) so to compare the sum from the array final column to the last integer in each row of the file (which is a sum).
My function is (note: We are using namespace std)
void readArray() {
ifstream infile("tableofintegers.txt");
for (int rowcount = 0; rowcount < ROWS; rowcount++) // row loop
{
for (int colcount = 0; colcount < COLS; colcount++) // column loop
{
infile >> twoDArray[rowcount][colcount]; // read to array
}
}
}
These are variables:
const int ROWS = 125;
const int COLS = 20;
I tried this but got a runtime error
file >> array[row][col];
file.ignore(10, '\n');
The error when I tried file.ignore
C:\path\matrix.exe (process 27316) exited with code -2147483645.
Not only is there an error, but it still "wraps" the read starting line two with the sum (last digit) of line 1.) As you can imagine, as this iterates, it keeps pushing the data over further and further.
I expected for the program to stop reading when it reached the limit of the array columns (20) then continue at the next line, but it didn't. My brain tells me something's not logical about that expectation, yet I have a dissonance or something going on. I can't really wrap my head around it. I also tried file.ignore which I expected would ignore 10 characters after the 20th column up to new line, but it just kicked an error and still wrapped.
Note: I'm printing the array to the console. Here is my code for that.
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
cout << setw(5) << dataArray[row][col];
}
cout << endl;
}

919B | nth Numbers having digit sum as 10 | Codeforces

Here is the link to the question. Essentially, it asks to find the kth number having digit sum as 10. I have tried multiple solutions and also looked upon solutions online. Specifically this one (also shared below). The one with constant time talks about outliers in Arithmetic Progression and uses it to find the nth number having sum as 10. Obviously, the code is incorrect as it fails for test cases when k=1000 etc.
#include <bits/stdc++.h>
using namespace std;
int findNth(int n)
{
int nthElement = 19 + (n - 1) * 9;
int outliersCount = (int)log10(nthElement) - 1;
// find the nth perfect number
nthElement += 9 * outliersCount;
return nthElement;
}
int main()
{
cout << findNth(5) << endl;
return 0;
}
Eventually, I ended up writing combination of Arithmetic Progression + brute force as below
#include <bits/stdc++.h>
using namespace std;
#define ll unsigned long long
int main() {
int n;
cin >> n;
int count = 0;
ll i = 19;
for (; ; i += 9) {
int curr = i;
int localSum = 0;
while (curr) {
localSum += curr%10;
curr /= 10;
}
if (localSum == 10) {
count += 1;
}
if (count == n) {
break;
}
}
cout << i << endl;
return 0;
}
I am wondering, if there is no constant time or better algorithm that does not require me to calculate the sum, but my algorithm always hops in a way that I have number whose digit sum is 10?
Here is a Python solution that you can translate into C++.
cached_count_ds_l = {}
def count_digit_sum_length (s, l):
k = (s, l)
if k not in cached_count_ds_l:
if l < 2:
if s == 0:
return 1
elif l == 1 and s < 10:
return 1
else:
return 0
else:
ans = 0
for i in range(min(10, s+1)):
ans += count_digit_sum_length(s-i, l-1)
cached_count_ds_l[k] = ans
return cached_count_ds_l[k]
def nth_of_sum (s, n):
l = 0
while count_digit_sum_length(s, l) < n:
l += 1
digits = []
while 0 < l:
for i in range(10):
if count_digit_sum_length(s-i, l-1) < n:
n -= count_digit_sum_length(s-i, l-1)
else:
digits.append(str(i))
s -= i
l -= 1
break
return int("".join(digits))
print(nth_of_sum(10, 1000))
The idea is to use dynamic programming to find how many numbers there are of a given maximum length with a given digit sum. And then to use that to cross off whole blocks of numbers on the way to finding the right one.
The main logic goes like this:
0 numbers of length 0 sum to 10
- need longer
0 numbers of length 1 sum to 10
- need longer
9 numbers of length 2 sum to 10
- need longer
63 numbers of length 3 sum to 10
- need longer
282 numbers of length 4 sum to 10
- need longer
996 numbers of length 5 sum to 10
- need longer
2997 numbers of length 6 sum to 10
- answer has length 6
Looking for 1000th number of length 6 that sums to 10
- 996 with a leading 0 sum to 10
- Need the 4th past 99999
- 715 with a leading 1 sum to 10
- Have a leading 1
Looking for 4th number of length 5 that sums to 9
- 495 with a leading 0 sum to 9
- Have a leading 10
Looking for 4th number of length 4 that sums to 9
- 220 with a leading 0 sum to 9
- Have a leading 100
Looking for 4th number of length 3 that sums to 9
- 55 with a leading 0 sum to 9
- Have a leading 1000
Looking for 4th number of length 2 that sums to 9
- 1 with a leading 0 sum to 9
- Need the 3rd past 9
- 1 with a leading 1 sum to 9
- Need the 2nd past 19
- 1 with a leading 2 sum to 9
- Need the 1st past 29
- 1 with a leading 3 sum to 9
- Have a leading 10003
Looking for 1st number of length 1 that sums to 6
- 0 with a leading 0 sum to 6
- Need the 1st past 0
- 0 with a leading 1 sum to 6
- Need the 1st past 1
- 0 with a leading 2 sum to 6
- Need the 1st past 2
- 0 with a leading 3 sum to 6
- Need the 1st past 3
- 0 with a leading 4 sum to 6
- Need the 1st past 4
- 0 with a leading 5 sum to 6
- Need the 1st past 5
- 1 with a leading 6 sum to 6
- Have a leading 100036
And it finishes in a fraction of a second.
Incidentally the million'th is 20111220000010, the billionth is 10111000000002000000010000002100, and the trillionth is 10000000100000100000100000000000001000000000000100000000010110001000.

Longest Increasing Sub sequence in a range

I have come across a problem where we want to tell the maximum size of the longest increasing sub-sequence.
an array A consisting of N integers.
M queries (Li, Ri)
for each query we wants to find the length of the longest increasing subsequence in
array A[Li], A[Li + 1], ..., A[Ri].
I implemented finding the sub-sequence using dp approach
// mind the REPN, LLD, these are macros I use for programming
// LLD = long long int
// REPN(i, a, b) = for (int i = a; i < b; ++i)
LLD a[n], dp[n];
REPN(i, 0, n)
{
scanf("%lld", &a[i]);
dp[i] = 1;
}
REPN(i, 1, n)
{
REPN(j, 0, i)
{
if(a[i] > a[j])
dp[i] = std::max(dp[j] + 1, dp[i]);
}
}
For example:
Array: 1 3 8 9 7 2 4 5 10 6
dplis: 1 2 3 4 3 1 3 4 5 5
max: 5
But if it was for range Li=2 & Ri=9
Then:
Array: 3 8 9 7 2 4 5 10
dplis: 1 2 3 2 1 2 3 4
max: 4
How can i determine the maximum longest increasing sub-sequence in a sub array?
PS: I don't want to recompute the whole dplis array, I want to use the original one because too much computation will kill the purpose of the question.
One of the approaches was to construct a complete 2D DP array that consists of sub-sequence from position i where range of i is from 0 to n, but it fails on many cases due to TLE(Time limit exceeded)
REPN(k,0,n) {
REPN(i,k+1,n) {
REPN(j,k,i) {
if(a[i]>a[j]) dp[k][i]=std::max(dp[k][j]+1, dp[k][i]);
}
}
}
REPN(i,0,q) {
read(l); read(r);
LLD max=-1;
REPN(i,0,r) {
if(max<dp[l-1][i]) max=dp[l-1][i];
}
printf("%lld\n", max);
}
If you have any new logic/implementation, I will gladly study it in-depth. Cheers.

printing 1D array in 6 columns

So I encountered this problem of not knowing how to display my random numbers from an array. The display should have 6 columns and I don’t know how about the rows. It is up to the user to enter amount of numbers in the array. Then, rand() will generate the numbers and display them in 6 columns like that (IF USER ENTERED 26 NUMBERS)
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1
I know how to generate the numbers and all that, my problem is only in displaying 1d array in that format. (the output has to compatible with other numbers entered as well not only 26) Any help or pointing in the right direction would be much appreciated.
Thanks,
uszy 123345.
Since you worry about just the output, you can insert a newline character every 6 numbers printed and just stop when you get at the end of the array.
Very often in c++ programming you can make use of extra variables to accomplish something every X number of iterations in a loop. In your case it looks like you want to insert a newline after every 6 numbers. Here is an example of how you would do that in code:
//I am assuming an array called arr with 26 elements already exists
for(int x = 1, i = 0; i < 26; ++i)
{
std::cout << arr[i] << ' ';
x++;
if(x == 6)
{
std::cout << std::endl;
x = 0;
}
}

Getting a Matrix from a file and assigning it to an array with a max size

Okay, so i have an array a[maxsize] [maxsize] where maxsize=10 how do i get an array to work correctly when taking an array from a file that is smaller than the max size.
Example matrix:
1 2 3
4 5 6
7 8 9
Is coming out:
1 2 3 4 5 6 7 8 9
My code:
`int main()
{
const int maxsize = 10;
double original_matrix[maxsize][maxsize], transposed_matrix[maxsize][maxsize];
ifstream fin;
ofstream fout;
fin.open ("input.txt");
if (fin.fail())
{
cout << "Input file opening failed. \n";
return 0;
}
for(i=0; i<maxsize; i++)
{
for(j=0; j<maxsize; j++)
{
fin >> original_matrix [i][j];
}
}
transpose(original_matrix[][maxsize], transposed_matrix[][maxsize],maxsize)
return 0;
}
I want the array to assign it like this
M [0] [0]=1 M [0] [1]=2 M [0] [2]=3
M [1] [0]=4 M [1] [1]=5 M [1] [2]=6
M [2] [0]=7 M [2] [1]=8 M [2] [2]=9
Not
M [0] [0]=1 M [0] [1]=1 M [0] [2]=1 M [0] [3]=1 M [0] [4]=1 M [0] [5]=1 M [0] [6]=1 M [0] [7]=1 M [0] [8]=1
..... So on
The text file looks like this:
2
1 0
0 1
3
8 9 1
3 5 2
-2 3 -1
0
If you want the matrix to come out in matrix form, why dont you:
for(i=0; i<maxsize; i++)
{
for(j=0; j<maxsize; j++)
{
fin >> original_matrix [i][j];
}
cout << "\n"
}
That way it comes out as a box instead of a single line. I think you will also have to play around with maxsize, because you want it to be a matrix with no empties, so you should check how many vectors make up the matrix, and use that as a condition (instead of maxsize)
edit - Input file psuedo code
So the first line is a single number, that tells use how many rows or columns the matrix will be. This program will assume that it is a square matrix, therefore. the condition value that you want is the first line (ie 2,3,0). Make sure to check that the value is greater than 0 and less than 10. Parse through the input line for each value, inject it into your matrix. Set the condition value, and therefore you will have a perfect square matrix.
Open File
Read line, is it the length of matrix?
* if so, set to condition
* if not, it is a value in the matrix
Check conition to make sure 0 < cond < 10
Print.