Pascal's Triangle using mainly functions in C++ - c++

I was trying to write a code that would display pascals triangle. Instead of displaying the result as :
my result is displayed as
1
1 1
1 2 1
1 3 3 1
Please help me figure out how to modify it to be able to get the actual triangle. I cant use arrays and pointers since those aren't covered in my class yet. Here's my code:
#include "stdafx.h"
#include <iostream>
using namespace std;
void PascalsTriangle(int);
int main()
{
int n;
cout << "Enter the number of rows you would like to print for Pascal's Triangle: ";
cin >> n;
PascalsTriangle(n);
return 0;
}
void PascalsTriangle (int n){
int i,j,x;
for(i=0;i<n;i++)
{
x=1;
for(j=0;j<=i;j++)
{
cout << x << " ";
x = x * (i - j) / (j + 1);
}
cout << endl;
}
}

Here is the updated version. Works for any n. I've added a function to return the number of digits in a number since that computation is needed each iteration of the inner loop.
#include <iostream>
#include <string>
using namespace std;
void PascalsTriangle(int);
int main()
{
int n;
cout << "Enter the number of rows you would like to print for Pascal's Triangle: ";
cin >> n;
cout << endl;
PascalsTriangle(n);
return 0;
}
int numdigits(int x)
{
int count = 0;
while(x != 0) {
x = x / 10;
++count;
}
return count;
}
void PascalsTriangle (int n)
{
int i, j, x, y, maxlen;
string len;
for(i = 0; i < n; i++) {
x = 1;
len = string((n-i-1)*(n/2), ' ');
cout << len;
for(j = 0; j <= i; j++) {
y = x;
x = x * (i - j) / (j + 1);
maxlen = numdigits(x) - 1;
if(n % 2 == 0)
cout << y << string(n - 1 - maxlen, ' ');
else {
cout << y << string(n - 2 - maxlen, ' ');
}
}
cout << endl;
}
}
OUTPUTS:
Enter the number of rows you would like to print for Pascal's Triangle: 3
1
1 1
1 2 1
Enter the number of rows you would like to print for Pascal's Triangle: 6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Enter the number of rows you would like to print for Pascal's Triangle: 9
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
Enter the number of rows you would like to print for Pascal's Triangle: 12
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1
UPDATE for a more tighter triangle:
void PascalsTriangle(int n)
{
int i, j, x, y, maxlen;
string len;
for(i = 0; i < n; i++) {
x = 1;
if(n % 2 != 0)
len = string((n-i-1)*(n/2), ' ');
else
len = string((n-i-1)*((n/2)-1), ' ');
cout << len;
for(j = 0; j <= i; j++) {
y = x;
x = x * (i - j) / (j + 1);
maxlen = numdigits(x);
if(n % 2 == 0)
cout << y << string(n - 2 - maxlen, ' ');
else {
cout << y << string(n - 1 - maxlen, ' ');
}
}
cout << endl;
}
}
OUTPUT
Enter the number of rows you would like to print for Pascal's Triangle: 3
1
1 1
1 2 1
Enter the number of rows you would like to print for Pascal's Triangle: 6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Enter the number of rows you would like to print for Pascal's Triangle: 9
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
Enter the number of rows you would like to print for Pascal's Triangle: 12
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
1 10 45 120 210 252 210 120 45 10 1
1 11 55 165 330 462 462 330 165 55 11 1

Try this :
#include <iostream>
using namespace std;
int main()
{
int n,k,i,x;
cout << "Enter a row number for Pascal's Triangle: ";
cin >> n;
for(i=0;i<=n;i++)
{
x=1;
for(k=0;k<=i;k++)
{
cout << x << " ";
x = x * (i - k) / (k + 1);
}
cout << endl;
}
return 0;
}
EDITED:
#include <iostream>
using namespace std;
int main()
{
int n,coef=1,space,i,j;
cout<<"Enter number of rows: ";
cin>>n;
for(i=0;i<n;i++)
{
for(space=1;space<=n-i;space++)
cout<<" ";
for(j=0;j<=i;j++)
{
if (j==0||i==0)
coef=1;
else
coef=coef*(i-j+1)/j;
cout<<" "<<coef;
}
cout<<endl;
}
}

Do you expect this result?
1111
123
13
1
You need to add endl or constant string equivalent to "\r\n" to the end of the output string, or use commas in output, then, for example:
"1111,123,13,1"
"1,11,121,1331"

If you want it to look like a 'triangle', that is, a symmetric looking isosceles triangle, try this code for your PascalTriangle function. The only problem with this is that when you get larger digits, it will break some of the symmetry but up to 5 rows it'll work fine.
void PascalsTriangle(int n)
{
int i, j, x;
string len;
for(i = 0; i < n; i++)
{
x = 1;
len = string(n - i - 1, ' ');
cout << len;
for(j = 0; j <= i; j++)
{
cout << x << " ";
x = x * (i - j) / (j + 1);
}
cout << endl;
}
}
OUTPUT
Enter the number of rows you would like to print for Pascal's Triangle: 5
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
As opposed to:
Enter the number of rows you would like to print for Pascal's Triangle: 5
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

#include <iostream>
using namespace std;
const int MAXC = 13; //-- Max column constant
const int MAXF = 7; //-- Max row constant
int m, n, k, x, y; //-- Counters and accumulators for loops
int arrayTriangulo[MAXF][MAXC]; // Array that stores the values of the Pascal Triangle
int main() {
m = (MAXC/2); // Middle Column
k = (MAXC/2); // Middle row
//-- 1.- Fill in the Array from Left to Right and from Top to Bottom
//-- 2.- Fill in the Array starting from row 0 through 13 (MAXF)
for ( x = 0; x < MAXF; x++ ) {
n = 1;
//-- 3.- Fill in the Array starting from Column 0 through 7 (MAXC)
for ( y = 0; y < MAXC; y++ ) {
//-- Assign 0 to the Array element that is not part of the triangle.
arrayTriangulo[x][y] = 0;
//-- 4.- If it is on the edges of the triangle assigns the value of "n". Which we initialize in 1.
if (( y == m ) || ( y == k )) {
arrayTriangulo[x][y] = n;
}
//-- 5.- For the rest of the internal values of the triangle other than the edges.
//-- The sum of the value is assigned (upper left row -1) + (upper right row + 1)
if ( ( x > 1 ) && ( x < MAXF ) && ( y < MAXC-1 ) ) {
arrayTriangulo[x][y] = arrayTriangulo[x-1][y-1] + arrayTriangulo[x-1][y+1];
}
//-- 6.- Finally Draw the Triangle by omitting the values at zero.
if ( arrayTriangulo[x][y] > 0 )
cout << arrayTriangulo[x][y] << " ";
else
cout << " ";
}
cout << endl;
m--;
k++;
}
return 0;
}

Related

Incorrect output in Pascal's triangle program in C++

I was creating a Pascal's triangle program in C++, but the output displayed is not as expected.
Output Expected
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
Output got
1
1 1
1 2 1
1 3 3 1
1 2 2 2 1
1 6 6 6 6 1
Till i = 4, output displayed is correct, but after that I couldn't figure out how it goes wrong. Hers is the source code to get reviewed
int main()
{ int num, a[37680], t = 0, b = 2, l;
cout<<"Enter the number of rows: ";
cin>>num;
for (int i = 1; i <= num; i++)
{
for (int j = 1; j <= (num - i); j++)
{
cout<<" ";
}
for (int k = 1; k <= i; k++)
{
l = k;
if (k == 1 || k == i)
{
a[t] = 1;
cout<<a[t]<<" ";
t+=1;
}
else
{
a[t] = a[t - b] + a[t - b - 1];
cout<<a[t]<<" ";
t+=1;
if ( l = (i - 1) )
{
b+=1;
}
}
}
cout<<endl;
}
return 0;}
Equality checking in c++ is done using == and not =, so:
if(l=(i-1))
Should be:
if(l==(i-1))

How to write this recursion with loops

I saw the following as an exercise in a website. It basically says write the following function without using recursion and without using structures like vector, stack, etc:
void rec(int n) {
if (n != 0) {
cout << n << " ";
rec(n-1);
rec(n-1);
}
}
At first I thought it was going to be easy, but I'm suprisingly struggling to accomplish it.
To understand it better, I defined it like a math function as the following:
f(x) = {1 if x = 0, f(x-1) + f(x-1) otherwise} (where + operator means concatenation and - is the normal minus)
However, Unrolling this made it harder, and I'm stuck. Is there any direct way to write it as a loop? And also, more generally, is there an algorithm to solve this type of problems?
If you fiddle with it enough, you can get at least one way that will output the ordered sequence without revisiting it :)
let n = 5
// Recursive
let rec_str = ''
function rec(n) {
if (n != 0) {
rec_str += n
rec(n-1);
rec(n-1);
}
}
rec(n)
console.log(rec_str)
// Iterative
function f(n){
let str = ''
for (let i=1; i<1<<n; i++){
let t = i
let p = n
let k = (1 << n) - 1
while (k > 2){
if (t < 2){
break
} else if (t <= k){
t = t - 1
p = p - 1
k = k >> 1
} else {
t = t - k
}
}
str += p
}
console.log(str)
}
f(n)
(The code is building a string, which I think should be disallowed according to the rules, but only for demonstration; we could just output the number instead.)
void loop(int n)
{
int j = 0;
int m = n - 1;
for (int i = 0; i < int(pow(2, n)) - 1; i++)
{
j = i;
if (j == 0)
{
std::cout << n << " ";
continue;
}
m = n - 1;
while (true)
{
if (m == 1)
{
std::cout << m << " ";
m = n - 1;
break;
}
if (j >= int(pow(2, m)))
{
j = j - int(pow(2, m)) + 1;
}
if (j == 1)
{
std::cout << m << " ";
m = n - 1;
break;
}
else
{
j--;
}
m--;
}
}
std::cout << std::endl;
}
For n = 3 for instance
out = [3 2 1 1 2 1 1]
indexes = [0 1 2 3 4 5 6]
Consider the list of indexes; for i > 0 and i <= 2^(m) the index i has the same value as the index i + 2^(m)-1 where m = n - 1. This is true for every n. If you are in the second half of the list, find its correspondent index in the first half by this formula. If the resulting number is 1, the value is m. If not, you are in a lower level of the tree. m = m - 1 and repeat until the index is 1 or m =1, in which case you've reached the end of the tree, print 1.
For instance, with n = 4, this is what happens with all the indexes, at every while step. p(x) means the value x gets printed at that index. A / means that index has already been printed.:
n = 4,m = 3
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
m = 3
[p(n=4) 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
if(i >=2^3) -> i = i -2^3 + 1)
[/ 1 2 3 4 5 6 7 1 2 3 4 5 6 7]
if(i == 1) -> print m, else i = i -1
[/ p(3) 1 2 3 4 5 6 p(3)1 2 3 4 5 6]
m = 2
if (i >=2^2) -> i = i - 2^2 +1
[/ / 1 2 3 1 2 3 / 1 2 3 1 2 3]
if(i == 1) -> print m, else i = i -1
[ / / p(2) 1 2 p(2) 1 2 / p(2) 1 2 p(2) 1 2]
m = 1
if (m == 1) -> print(m)
[ / / / p(1) p(1) / p(1) p(1) / / p(1) p(1) / p(1) p(1)]
Therefore the result is:
[4 3 2 1 1 2 1 1 3 2 1 1 2 1 1]
void via_loop(int n) {
string prev = "1 ", ans = "1 ";
for (int i = 2; i <= n; i++) {
ans = to_string(i) + " " + prev + prev;
prev = ans;
}
cout << ans;
}
Idea is to save result from the previous computation of each number. Full code:
void rec(int n) {
if (n != 0) {
cout << n << " ";
rec(n-1);
rec(n-1);
}
}
void via_loop(int n) {
string prev = "1 ", ans = "1 ";
for (int i = 2; i <= n; i++) {
ans = to_string(i) + " " + prev + prev;
prev = ans;
}
cout << ans;
}
int main() {
int n = 5;
cout << "Rec : ";
rec(n);
cout << endl;
cout << "Loop: ";
via_loop(n);
cout << endl;
}
Output:
Rec : 5 4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 4 3 2 1 1 2 1 1 3 2 1 1 2 1 1
Loop: 5 4 3 2 1 1 2 1 1 3 2 1 1 2 1 1 4 3 2 1 1 2 1 1 3 2 1 1 2 1 1

How to print numbers in N x (N+1) rectangles?

the program should take an integer from user and print pattern like below.
if n=3, then
333
313
323
333
if n=4, then
4444
4114
4224
4334
4444
if n=5, then
55555
51115
52225
53335
54445
55555
and so on
Here is what is have tried.
#include<iostream>
using namespace std;
int main()
{
int pattern[10][10], i, j, n;
cout << "Enter dimension of square matrix: ";
cin >> n;
for (i = 0;i <= n;i++)
{
pattern[i][0] = n;
pattern[i][n - 1] = n;
}
for (j = 1;j < n - 2;j++)
{
pattern[0][j] = n;
pattern[n][j] = n;
}
for (i = 1;i < n - 1;i++)
{
for (j = 1;j < n - 2;j++)
{
pattern[i][j] = i;
}
}
for (i = 0;i <=n;i++)
{
for (j = 0;j < n;j++)
{
cout << pattern[i][j];
cout << "\t";
}
cout << "\n";
}
return 0;
}
I am getting the right pattern but in some places, there are some garbage value (or something else)
Quite simple to do in a clear, concise manner:
#include<iostream>
int main()
{
int n = 0;
std::cout << "Enter dimension of square matrix: ";
std::cin >> n;
for (int i = 0; i < n + 1; ++i) {
for (int j = 0; j < n; ++j) {
// if on the first or last column or row: print n, else: print i
std::cout << ((i == 0 || j == 0 || i == n || j == n-1) ? n : i) << '\t';
}
std::cout << '\n';
}
return 0;
}
Example output:
Enter dimension of square matrix: 5
5 5 5 5 5
5 1 1 1 5
5 2 2 2 5
5 3 3 3 5
5 4 4 4 5
5 5 5 5 5
You are on the right way! Some simple change will give the right answer .
#include<iostream>
using namespace std;
int main()
{
int pattern[10][10], i, j, n;
cout << "Enter dimension of square matrix: ";
cin >> n;
for (i = 0;i <= n;i++)
{
pattern[i][0] = n;
pattern[i][n - 1] = n;
}
for (j = 1;j <n ;j++)
{
pattern[0][j] = n;
pattern[n][j] = n;
}
for (i = 1;i < n ;i++)
{
for (j = 1;j < n -1;j++)
{
pattern[i][j] = i;
}
}
for (i = 0;i <=n;i++)
{
for (j = 0;j < n;j++)
{
cout << pattern[i][j];
cout << "\t";
}
cout << "\n";
}
return 0;
}
I think you are overcomplicating things - there is absolutely no need for the two-dimensional array and all the loops.
You could just use a basic helper function printer, that prints the version with the nested number i and execute that in a loop from 1 to the last number, for example 5.
#include <cstdio>
#include <iostream>
int main() {
unsigned user_input = 5; // change to ask for actual user input
// Helper function, i.e. for 3 it prints 53335
auto printer = [](unsigned i) {
for (unsigned n = 0; n < user_input; ++n) {
if (n == 0 || n + 1 == user_input) std::cout << user_input;
else std::cout << i;
}
std::cout << '\n';
};
printer(user_input); // print 55555
// print the rest 51115, 52225 ... up to 55555 again
for (unsigned i = 1; i <= user_input; ++i) printer(i);
}
If you think you need the printer function elsewhere too or don't want to use a lambda, you can of course just move it and give it a signature like that:
void printer(unsigned i, unsigned user_input) {
/* copy-paste the code from printer */
}
In fact there is no need to define an array to output the pattern.
All you need is two loops.
Here is a demonstration program.
#include <iostream>
int main()
{
while ( true )
{
const unsigned int MAX_VALUE = 10;
std::cout << "Enter a non-negative number less than "
<< MAX_VALUE << " (0 - exit): ";
unsigned int n;
if ( not ( std::cin >> n ) or ( n == 0 ) ) break;
if ( MAX_VALUE - 1 < n ) n = MAX_VALUE - 1;
std::cout << '\n';
for ( unsigned int i = 0; i < n + 1; i++ )
{
for ( unsigned int j = 0; j < n; j++ )
{
if ( j == 0 || j == n - 1 )
{
std::cout << n;
}
else if ( i == 0 || i == n )
{
std::cout << n;
}
else
{
std::cout << i;
}
}
std::cout << '\n';
}
std::cout << '\n';
}
}
Its output might look like
Enter a non-negative number less than 10 (0 - exit): 1
1
1
Enter a non-negative number less than 10 (0 - exit): 2
22
22
22
Enter a non-negative number less than 10 (0 - exit): 3
333
313
323
333
Enter a non-negative number less than 10 (0 - exit): 4
4444
4114
4224
4334
4444
Enter a non-negative number less than 10 (0 - exit): 5
55555
51115
52225
53335
54445
55555
Enter a non-negative number less than 10 (0 - exit): 6
666666
611116
622226
633336
644446
655556
666666
Enter a non-negative number less than 10 (0 - exit): 7
7777777
7111117
7222227
7333337
7444447
7555557
7666667
7777777
Enter a non-negative number less than 10 (0 - exit): 8
88888888
81111118
82222228
83333338
84444448
85555558
86666668
87777778
88888888
Enter a non-negative number less than 10 (0 - exit): 9
999999999
911111119
922222229
933333339
944444449
955555559
966666669
977777779
988888889
999999999
Enter a non-negative number less than 10 (0 - exit): 0
That is you can substitute all your loops that fill the array for if statements in one pair of loops that output the pattern.
The if statements can be substituted for the conditional operator the following way
for ( unsigned int i = 0; i < n + 1; i++ )
{
for ( unsigned int j = 0; j < n; j++ )
{
std::cout << ( i % n == 0 || j % ( n - 1 ) == 0 ? n : i );
}
std::cout << '\n';
}
The restriction to output the pattern only for numbers [1, 9] is artificial.
It would be more reasonable to set the range at least to [1, 255] where 255 is the maximum value that can be stored in an object of type unsigned char.
You can get the value through the expression
std::numeric_limits<unsigned char>::max()
To make an alignment for outputted columns you can use standard function std::setw that sets the width of an outputted field.
Taking all this into account the program can look the following way.
#include <iostream>
#include <iomanip>
#include <limits>
int main()
{
while ( true )
{
const unsigned int Base = 10;
const unsigned int MAX_VALUE = std::numeric_limits<unsigned char>::max();
std::cout << "Enter a non-negative number less than or equal to "
<< MAX_VALUE << " (0 - exit): ";
unsigned int n = 0;
if ( not ( std::cin >> n ) || ( n == 0 ) ) break;
if ( MAX_VALUE < n ) n = MAX_VALUE;
// Calculating the width of numbers plus one space between them.
int number_width = 1;
unsigned int tmp = n;
do { ++number_width; } while ( tmp /= Base );
std::cout << '\n';
for ( unsigned int i = 0; i < n + 1; i++ )
{
for ( unsigned int j = 0; j < n; j++ )
{
std::cout << std::setw( number_width )
<< ( i % n == 0 || j % ( n - 1 ) == 0 ? n : i );
}
std::cout << '\n';
}
std::cout << '\n';
}
}
The program output might look like
Enter a non-negative number less than 255 (0 - exit): 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20
20 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 20
20 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 20
20 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 20
20 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 20
20 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 20
20 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 20
20 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 20
20 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 20
20 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 20
20 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 20
20 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 20
20 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 20
20 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 20
20 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 20
20 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 20
20 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 20
20 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 20
20 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
Enter a non-negative number less than 255 (0 - exit): 0
As for your code then for starters you should check whether the user entered a number that is greater than 9
And for example in this pair of loops
for (i = 1;i < n - 1;i++)
{
for (j = 1;j < n - 2;j++)
{
pattern[i][j] = i;
}
}
the conditions should look at least like
for (i = 1; i < n; i++)
{
for (j = 1; j < n - 1; j++ )
{
pattern[i][j] = i;
}
}
because the height of the pattern is equal to n + 1 and the width is equal to n. So if you want to exclude the last row and last column you have to use correspondingly the expressions n and n - 1 in the conditions of the loops.

C++, outputting the the sum of proper divisors for numbers from 2 to 20

My question looks like this
For numbers from 2 to 20, output the proper divisors and their sum.
So it should look like this:
2: 1 = 1
3: 1 = 1
4: 1+2 = 3
5: 1 = 1
6: 1+2+3 = 6
...
20: 1+2+4+5+10 = 23
This is what i wrote so far:
#include <iostream>
int main () {
int a=2;
int sum=1;
while (a<=10){
std::cout<<a<<": ";
for(int b=1; b<a; b=b+1)
{
if(a%b == 0)
{
std::cout<<b<<" + ";
sum+=b;}
if (b == a-1){
std::cout<<"= "<<sum<<"\n";
}
}
a++;
}
return 0;
}
When i compile and run, the output ends up looking like this:
2: 1 + = 2
3: 1 + = 3
4: 1 + 2 + = 6
5: 1 + = 7
6: 1 + 2 + 3 + = 13
7: 1 + = 14
8: 1 + 2 + 4 + = 21
9: 1 + 3 + = 25
10: 1 + 2 + 5 + = 33
My issues are currently:
Why does it give me the sum of all of the previous b results? I am trying to get the sum of only the divisors for each number. It gives me the sum of all previous sums.
Also, how do i get rid of the extra (+) at the end?
Many thanks!
EDIT:
Thanks guys! Here's the code after i adjusted it and cleaned it up a little bit!
#include <iostream>
int main() {
int a = 2;
while (a <= 20) {
std::cout <<a <<": ";
int sum = 0;
for (int b = 1; b < a; b = b + 1) {
if (a%b == 0) {
if (b == 1) {
std::cout <<b;
} else {
std::cout <<" + " <<b; }
sum += b; }
if (b == a-1) {
std::cout <<"= " <<sum <<"\n";
}
}
a++;
}
return 0;
}
It now works like a charm. The output has a few too many whitespaces but its good enough. Many thanks!
You need to reset the value of sum to zero at the beginning of each iteration of the while loop to avoid the multiple sum problem.
As far as the extra +, you could print "+" before the value of 'b' instead of after, and only if b > 1 (there is guaranteed a printed value before the current value of b).
Try something like this it uses this answer for not adding the + after the last item of divisors:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
std::vector<int> properDivisors ( int number ) {
std::vector<int> divisors ;
for ( int i = 1 ; i < number / 2 + 1 ; i++ )
if ( number % i == 0 )
divisors.push_back( i ) ;
return divisors ;
}
int main()
{
for(size_t i = 2; i <= 20; ++i)
{
std::vector<int> divisors = properDivisors(i);
std::cout << i << ": ";
const char *padding = "";
for (auto iter = divisors.begin(); iter != divisors.end(); ++iter) {
std::cout << padding << *iter;
padding = " + ";
}
int sum = 0;
for (auto& n : divisors)
sum += n;
std::cout << " = " << sum;
std::cout << std::endl;
}
}
Output:
2: 1 = 1
3: 1 = 1
4: 1 + 2 = 3
5: 1 = 1
6: 1 + 2 + 3 = 6
7: 1 = 1
8: 1 + 2 + 4 = 7
9: 1 + 3 = 4
10: 1 + 2 + 5 = 8
11: 1 = 1
12: 1 + 2 + 3 + 4 + 6 = 16
13: 1 = 1
14: 1 + 2 + 7 = 10
15: 1 + 3 + 5 = 9
16: 1 + 2 + 4 + 8 = 15
17: 1 = 1
18: 1 + 2 + 3 + 6 + 9 = 21
19: 1 = 1
20: 1 + 2 + 4 + 5 + 10 = 22
Try it here!

c++ read in csv file and manipulate data then print error

This is a continuation for my problem here: c++ reading in text file into vector<vector> then writing to vector or array depending on first word in internal vector .Im reading in a file and the using the values of node coordinates to calc cell centres and want to pring the cell centres file with Headers: ID,X,Y,Z, with Z all 0s.
Code so far:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>
std::vector<double> GetValues(const std::vector<std::string>& src, int start, int end)
{
std::vector<double> ret;
for(int i = start; i <= end; ++i)
{
ret.push_back(std::strtod(src[i].c_str(), nullptr));
}
return ret;
}
std::vector<double> polycentre(const std::vector<double>& x,const std::vector<double>& y,int ID)
{
std::vector<double> C(3, 0);
std::vector<double> x1(x.size(),0);
std::vector<double> y1(y.size(),0);
int sizx = x.size();
int sizy = y.size();
if(sizy != sizx)
{
std::cerr << "polycentre inputs not equal length";
}
double x0 = x[0];
double y0 = y[0];
for(int aa = 1; aa < sizx; ++aa)
{
if(x[aa] < x0){x0 = x[aa];}
if(y[aa] < y0){y0 = y[aa];}
}
double A = 0.0;
double B = 0.0;
for(int aa = 0; aa < sizx; ++aa)
{
x1[aa] = x[aa] - x0;
y1[aa] = y[aa] - x0;
if(aa != sizx-1)
{
A = A + (x1[aa]*y1[aa+1] - x1[aa+1]*y1[aa]);
B = B + ((x1[aa]+x1[aa+1])*(x1[aa]*y1[aa-1]-x1[aa-1]*y1[aa]));
}
else if(aa == sizx-1)
{
A = A + (x1[aa] - y1[aa]);
B = B + ((x1[aa]+1)*(x1[aa]*1-1*y1[aa]));
}
}
A = A*0.5;
C[0] = ID;
C[1] = ((1/6/A)*B)+x0;
C[2] = ((1/6/A)*B)+y0;
return C;
}
void PrintValues(const std::string& title, std::vector<std::vector<double>>& v)
{
std::cout << title << std::endl;
for(size_t line = 0; line < v.size(); ++line)
{
for(size_t val = 0; val < v[line].size(); ++val)
{
std::cout << v[line][val] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int main()
{
std::vector<std::vector<std::string>> values;
std::ifstream fin("example.2dm");
for (std::string line; std::getline(fin, line); )
{
std::istringstream in(line);
values.push_back(
std::vector<std::string>(std::istream_iterator<std::string>(in),
std::istream_iterator<std::string>()));
}
std::vector<std::vector<double>> cells;
std::vector<std::vector<double>> nodes;
for (size_t i = 0; i < values.size(); ++i)
{
if(values[i][0] == "E3T")
{
cells.push_back(GetValues(values[i], 1, 5));
}
else if(values[i][0] == "E4Q")
{
cells.push_back(GetValues(values[i], 1, 6));
}
else if(values[i][0] == "ND")
{
nodes.push_back(GetValues(values[i], 1, 4));
}
}
std::vector<std::vector<double>> cell_centres;
for (size_t aa = 0; aa < cells.size(); ++aa)
{
if(cells[aa].size() == 4)
{
std::vector<double> xs = {nodes[cells[aa][1]][1], nodes[cells[aa][2]][1], nodes[cells[aa][3]][1]};
std::vector<double> ys = {nodes[cells[aa][1]][2], nodes[cells[aa][2]][2], nodes[cells[aa][3]][2]};
cell_centres.push_back(polycentre(xs,ys,aa));
}
}
PrintValues("Cell Centres", cell_centres);
PrintValues("Cells", cells);
PrintValues("Nodes", nodes);
return 0;
}
When I run the program I don't get any output for cell centres:
$ ./a.exe
Cell Centres
Cells
1 19 20 14 16 2
2 17 16 15 23 2
3 22 15 14 21 2
4 4 3 21 20 1
5 6 20 19 7 1
6 18 17 10 9 1
7 17 23 12 11 1
8 7 19 18 8 1
9 22 1 13 23 1
10 14 20 21 2
11 21 2 22 1
12 21 3 2 1
13 22 2 1 1
14 5 20 6 1
15 20 5 4 1
16 16 14 15 2
17 23 13 12 1
18 22 23 15 2
19 17 11 10 1
20 17 18 16 2
21 8 18 9 1
22 18 19 16 2
Nodes
1 -325.811 77.0286 0
2 -324.209 76.0395 0
3 -323.012 74.4784 0
4 -322.754 72.5327 0
5 -323.617 70.8079 0
6 -325.162 69.8134 0
7 -327.129 69.876 0
8 -329.096 69.9385 0
9 -330.301 71.4668 0
10 -330.787 73.3242 0
11 -330.836 75.2916 0
12 -329.587 76.5401 0
13 -327.743 77.227 0
14 -326.109 73.2068 0
15 -327.041 74.207 0
16 -327.35 73.1717 0
17 -329.154 74.0024 0
18 -328.659 71.9967 0
19 -326.846 71.4063 0
20 -325 72.0535 0
21 -324.701 73.9639 0
22 -326.168 75.3361 0
23 -328.06 75.4195 0
could someone tell me where I went wrong??
BTW the MATLAB code is:
function cell_centres(infil,outfil)
% read 2DM file
MESH = RD2DM(infil);
% get cell centres
if (isfield(MESH,'E3T'))
ne3 = length(MESH.E3T);
else
ne3 = 0;
end
if (isfield(MESH,'E4Q'))
ne4 = length(MESH.E4Q);
else
ne4 = 0;
end
ne = ne3 + ne4;
ctrd = zeros(ne,2);
id = zeros(ne,1);
z = zeros(ne,1);
k = 1;
if (isfield(MESH,'E3T'))
for i = 1:length(MESH.E3T)
pts = MESH.E3T(i,2:4);
x = MESH.ND(pts,2);
y = MESH.ND(pts,3);
z(k) = mean(MESH.ND(pts,4));
ctrd(k,:) = polycentre(x,y);
id(k) = MESH.E3T(i,1);
k = k+1;
end
end
if (isfield(MESH,'E4Q'))
for i = 1:length(MESH.E4Q)
pts = MESH.E4Q(i,2:5);
x = MESH.ND(pts,2);
y = MESH.ND(pts,3);
z(k) = mean(MESH.ND(pts,4));
ctrd(k,:) = polycentre(x,y);
id(k) = MESH.E4Q(i,1);
k = k+1;
end
end
% order cell ids
[id i] = sort(id,'ascend');
ctrd = ctrd(i,:);
z = z(i);
% write .csv file
fid = fopen(outfil,'w');
fprintf(fid,'%s\n','ID,X,Y,Z');
for aa = 1:ne
fprintf(fid,'%i,%.7f,%.7f,%.7f\n',id(aa),ctrd(aa,1),ctrd(aa,2),z(aa));
end
fclose(fid);
display('done & done :-)')
Cheers
Delete the &s in the following two lines
std::vector<double> xs = {&nodes[cells[aa][1]][1], &nodes[cells[aa][2]][1], &nodes[cells[aa][3]][1]};
std::vector<double> ys = {&nodes[cells[aa][1]][2], &nodes[cells[aa][2]][2], &nodes[cells[aa][3]][2]};
you need the double values instead of integers (& operator get the address which is a integral type). And initializer list does not do the implicit conversion for you.