Forums: » Register « |  Free Tools |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |

New Free Tools on Dev Shed!

#1
October 23rd, 2013, 01:07 PM
 seedofwinter
Contributing User

Join Date: Oct 2013
Posts: 32
Time spent in forums: 5 h 58 m 40 sec
Reputation Power: 1
Need help with a loop program

Hey yall. I'm new to this forum, and pretty new to programming in general, so I must ask that you have a little patience with me. XD

Okay, the problem on the Homework is this: create a program that gives you any number of a pascal triangle, given the user inputs the row and column of it.

This is what I have come up with, and I can't figure out why it's not working

#!/usr/bin/env perl

print "Enter your row of the pascal's triangle?";
\$i = <STDIN> ;

print "Now enter your column of the pascal's triangle?";
\$j = <STDIN> ;

\$product =( \$i - \$j + 1)/\$j * (\$i -(\$j - 1) +1)/(\$j - 1);

\$count = 0;

if (\$j = o) {\$product = 1;

}elsif (\$i = 0) {\$product = 1;

}elsif (\$j > \$i) {print "Your column length must not be

}
else {
until (\$count = \$j ){
\$product++;
\$count++;
}
print "\$product";
}

What am I doing wrong here? I don't get a printed output at all? Is this a synthax issue, or am I not using the counter and loop correctly?

#2
October 23rd, 2013, 02:03 PM
 Laurent_R
Contributing User

Join Date: Jun 2012
Posts: 715
Time spent in forums: 6 Days 11 h 45 m 55 sec
Reputation Power: 474
Hi,

you're doing a number of wrong things.

Code:
`if (\$j = o) {`

1. if you want to make a comparison, the operator should be ==, not =.
2. Here you are trying to compare to letter "o", not 0.

So it should be:

Code:
`if (\$j == 0) {`

Same problems for :
Code:
`}elsif (\$i = 0) `

These things, you would have seen them if you had included the following lines near the top of your program:

Code:
```use strict;
use warnings;```

forcing you to declare your variables with the my operator. ALWAYS include these two commands and always declare your variables, you will save enormous amounts of time, because the compiler will tell you about many of your errors.

Code:
`print "\$product";`

This print statement should be at the very end, after the last curly brace. You would have seen that if you took the time to indent your code correctly.

Code:
`\$product =( \$i - \$j + 1)/\$j * (\$i -(\$j - 1) +1)/(\$j - 1);`

This formula is most certainly wrong: in many cases it will give you non integer numbers, which you certainly don't want to have for binomial coefficients. But I do not know what the correct formula should be, as I don't know what you are trying to do with it.

#3
October 23rd, 2013, 02:11 PM
 seedofwinter
Contributing User

Join Date: Oct 2013
Posts: 32
Time spent in forums: 5 h 58 m 40 sec
Reputation Power: 1
Quote:
 Originally Posted by Laurent_R Hi, you're doing a number of wrong things. Code: `if (\$j = o) {` 1. if you want to make a comparison, the operator should be ==, not =. 2. Here you are trying to compare to letter "o", not 0. So it should be: Code: `if (\$j == 0) {` Same problems for : Code: `}elsif (\$i = 0) ` These things, you would have seen them if you had included the following lines near the top of your program: Code: ```use strict; use warnings;``` forcing you to declare your variables with the my operator. ALWAYS include these two commands and always declare your variables, you will save enormous amounts of time, because the compiler will tell you about many of your errors. Code: `print "\$product";` This print statement should be at the very end, after the last curly brace. You would have seen that if you took the time to indent your code correctly. Code: `\$product =( \$i - \$j + 1)/\$j * (\$i -(\$j - 1) +1)/(\$j - 1);` This formula is most certainly wrong: in many cases it will give you non integer numbers, which you certainly don't want to have for binomial coefficients. But I do not know what the correct formula should be, as I don't know what you are trying to do with it.

That's the correct formula, it was given by the professor, and you could check the values of it yourself to verify. I already have. Keeping in mind that J is never greater than i of course.

Thank you for the help though, I will try out your suggestions and see if it cures the issue.

#4
October 23rd, 2013, 02:48 PM
 Laurent_R
Contributing User

Join Date: Jun 2012
Posts: 715
Time spent in forums: 6 Days 11 h 45 m 55 sec
Reputation Power: 474
Quote:
 Originally Posted by seedofwinter That's the correct formula, it was given by the professor, and you could check the values of it yourself to verify. I already have. Keeping in mind that J is never greater than i of course. .

Try \$i = 5 and \$j = 4. Demonstration under the Perl debugger:

Code:
```  DB<6> \$i = 5;

DB<7> \$j = 4;

DB<8> \$product =( \$i - \$j + 1)/\$j * (\$i -(\$j - 1) +1)/(\$j - 1);

DB<9> p \$product
0.5```

The formula given by your professor may be correct, but if such is the case, your implementation of it is wrong. A binomial coefficient can only be an integer.

This part:
Code:
`.../\$j * (\$i -(\$j - 1) +1)`

is probably wrong because you don't use enough parentheses to make sure the various arithmetic operations are done with the right precedence. I can't help you further without the actual formula, as I have no idea what it should really be.

Last edited by Laurent_R : October 23rd, 2013 at 02:50 PM.

#5
October 23rd, 2013, 03:14 PM
 seedofwinter
Contributing User

Join Date: Oct 2013
Posts: 32
Time spent in forums: 5 h 58 m 40 sec
Reputation Power: 1
Quote:
 Originally Posted by Laurent_R Try \$i = 5 and \$j = 4. Demonstration under the Perl debugger: Code: ``` DB<6> \$i = 5; DB<7> \$j = 4; DB<8> \$product =( \$i - \$j + 1)/\$j * (\$i -(\$j - 1) +1)/(\$j - 1); DB<9> p \$product 0.5``` The formula given by your professor may be correct, but if such is the case, your implementation of it is wrong. A binomial coefficient can only be an integer. This part: Code: `.../\$j * (\$i -(\$j - 1) +1)` is probably wrong because you don't use enough parentheses to make sure the various arithmetic operations are done with the right precedence. I can't help you further without the actual formula, as I have no idea what it should really be.

I was beginning to think the same thing. I have got the program now to print some output, only sometimes the output is off, and sometimes the output is right, so I must not be inputing it in correctly.

Basically the formula is this ( i - j + 1)/ j multiplied by the previous value. For instance, we know that the first number of every row is 1 right? So the value for the 2nd number of the 5th row is given by (5 - 1 + 1)/1 * 1, where I am starting the count from 0.

How could I say that when the count is 0, the product is automatically 1? I am having a little bit of an issue with that?

I thank you for all your help by the way; it's greatly appreciated.

#6
October 23rd, 2013, 03:28 PM
 seedofwinter
Contributing User

Join Date: Oct 2013
Posts: 32
Time spent in forums: 5 h 58 m 40 sec
Reputation Power: 1
Quote:
 Originally Posted by Laurent_R Try \$i = 5 and \$j = 4. Demonstration under the Perl debugger: Code: ``` DB<6> \$i = 5; DB<7> \$j = 4; DB<8> \$product =( \$i - \$j + 1)/\$j * (\$i -(\$j - 1) +1)/(\$j - 1); DB<9> p \$product 0.5``` The formula given by your professor may be correct, but if such is the case, your implementation of it is wrong. A binomial coefficient can only be an integer. This part: Code: `.../\$j * (\$i -(\$j - 1) +1)` is probably wrong because you don't use enough parentheses to make sure the various arithmetic operations are done with the right precedence. I can't help you further without the actual formula, as I have no idea what it should really be.

Check out my new program, that is bringing me a new hell. I did the indentation that you suggested.

#!/usr/bin/env perl

print "Enter the row of your pascal Triangle\n";
\$i = <STDIN>;

print "Now enter the column of the pascal triangle\n";
\$j = <STDIN>;

\$product = (\$i - \$j + 1 )/(\$j)*(\$i - (\$j - 1) + 1)/(\$j - 1);

\$count = 0;

if (\$j > \$i ) {
length";
}elsif (\$j == 1){\$product = \$i;
}elsif (\$j == 0){\$product = 1;
}else {
until (\$count = \$j ) {
\$product++;
\$count++;
}
print "\n \$product";
}

I get a division by zero error even though I specified that if j = 0 or = 1 product automatically equals other values.

#7
October 23rd, 2013, 07:33 PM
 Laurent_R
Contributing User

Join Date: Jun 2012
Posts: 715
Time spent in forums: 6 Days 11 h 45 m 55 sec
Reputation Power: 474
Quote:
 Originally Posted by seedofwinter Basically the formula is this ( i - j + 1)/ j multiplied by the previous value.

That is what I thought, I could not make any sense from your formula.

The formula given by your professor is an iterative formula, you can't calculate it in one shot. If you are at row 5, you need to use values of row 4 to calculate values of row 5. But since you still don't know what values in row 4 are, you need to calculate first row 3, and so on. So, the product has to be calculated iteratively or recursively. Since I do not know what your professor has taught you, I can't really choose between the two methods.

Let's set up the Pascal triangle:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

Suppose we need to compute pascal(5, 3), whose value is 6 (i.e. 5th row, 3rd column). We have: pascal (5, 3) = pascal (4, 2) + pascal (4,3) = 3 + 3. But, of course, you don't know at this point that these two values are both 3. so you need to compute then. And so on until you reach a know value.

So the mathematical rules are as follows:
- pascal (1, 1) = 1;
- pascal (i, j) = pascal (i-1, j-1) + pascal (i-1, j);
- With an additional rule: if j gets to 0, set it to 1.

If you have learned subroutines and recursion, this can be done in about 4 lines of code. Possibly a couple of lines more with iteration.

Please note that I do not wish to give you a ready made solution (this is not proper for a homework in my view, the point is that you should really work out of this problem your way to learn), but I am trying to help you finding one, meaning that I am spending much more time trying to explain how to proceed than I would spend giving you a solution.

Just in case you think that I am bragging, this is an example code to do the work:

Perl Code:
 Original - Perl Code
```use strict;use warnings; my (\$i, \$j) =  @ARGV;die "Error; second number must be smaller than first" if \$j > \$i;print pascal(\$i, \$j); sub pascal {    my (\$i, \$j) = @_;    return 1 if \$i == 1 or \$j == 1;    return 1 if \$j > \$i;    return  pascal (\$i-1, \$j) + pascal (\$i-1, \$j-1?\$j-1:1);
```

Except that (1) I am not sure you will be able to explain it to your professor without a bit of hard work, and (2) I have intentionally left one small bug: it will print one of the Pascal triangle values, but not necessarily the right one.

Sample execution:
Code:
```\$ perl pascal.pl 20 13
125970```

Pascal triangle according to Wikipedia:
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
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1
1 16 120 560 1820 4368 8008 11440 12870 11440 8008 4368 1820 560 120 16 1
1 17 136 680 2380 6188 12376 19448 24310 24310 19448 12376 6188 2380 680 136 17 1
1 18 153 816 3060 8568 18564 31824 43758 48620 43758 31824 18564 8568 3060 816 153 18 1
1 19 171 969 3876 11628 27132 50388 75582 92378 92378 75582 50388 27132 11628 3876 969 171 19 1
1 20 190 1140 4845 15504 38760 77520 125970167960 184756 167960 125970 77520 38760 15504 4845 1140 190 20 1
1 21 210 1330 5985 20349 54264 116280 203490 293930 352716 352716 293930 203490 116280 54264 20349 5985 1330 210 21 1
1 22 231 1540 7315 26334 74613 170544 319770 497420 646646 705432 646646 497420 319770 170544 74613 26334 7315 1540 231 22 1

#8
October 23rd, 2013, 10:50 PM
 seedofwinter
Contributing User

Join Date: Oct 2013
Posts: 32
Time spent in forums: 5 h 58 m 40 sec
Reputation Power: 1
Quote:
Originally Posted by Laurent_R
That is what I thought, I could not make any sense from your formula.

The formula given by your professor is an iterative formula, you can't calculate it in one shot. If you are at row 5, you need to use values of row 4 to calculate values of row 5. But since you still don't know what values in row 4 are, you need to calculate first row 3, and so on. So, the product has to be calculated iteratively or recursively. Since I do not know what your professor has taught you, I can't really choose between the two methods.

Let's set up the Pascal triangle:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1

Suppose we need to compute pascal(5, 3), whose value is 6 (i.e. 5th row, 3rd column). We have: pascal (5, 3) = pascal (4, 2) + pascal (4,3) = 3 + 3. But, of course, you don't know at this point that these two values are both 3. so you need to compute then. And so on until you reach a know value.

So the mathematical rules are as follows:
- pascal (1, 1) = 1;
- pascal (i, j) = pascal (i-1, j-1) + pascal (i-1, j);
- With an additional rule: if j gets to 0, set it to 1.

If you have learned subroutines and recursion, this can be done in about 4 lines of code. Possibly a couple of lines more with iteration.

Please note that I do not wish to give you a ready made solution (this is not proper for a homework in my view, the point is that you should really work out of this problem your way to learn), but I am trying to help you finding one, meaning that I am spending much more time trying to explain how to proceed than I would spend giving you a solution.

Just in case you think that I am bragging, this is an example code to do the work:

Perl Code:
 Original - Perl Code
```use strict;use warnings; my (\$i, \$j) =  @ARGV;die "Error; second number must be smaller than first" if \$j > \$i;print pascal(\$i, \$j); sub pascal {    my (\$i, \$j) = @_;    return 1 if \$i == 1 or \$j == 1;    return 1 if \$j > \$i;    return  pascal (\$i-1, \$j) + pascal (\$i-1, \$j-1?\$j-1:1);
```

Except that (1) I am not sure you will be able to explain it to your professor without a bit of hard work, and (2) I have intentionally left one small bug: it will print one of the Pascal triangle values, but not necessarily the right one.

Sample execution:
Code:
```\$ perl pascal.pl 20 13
125970```

Pascal triangle according to Wikipedia:
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
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1
1 16 120 560 1820 4368 8008 11440 12870 11440 8008 4368 1820 560 120 16 1
1 17 136 680 2380 6188 12376 19448 24310 24310 19448 12376 6188 2380 680 136 17 1
1 18 153 816 3060 8568 18564 31824 43758 48620 43758 31824 18564 8568 3060 816 153 18 1
1 19 171 969 3876 11628 27132 50388 75582 92378 92378 75582 50388 27132 11628 3876 969 171 19 1
1 20 190 1140 4845 15504 38760 77520 125970167960 184756 167960 125970 77520 38760 15504 4845 1140 190 20 1
1 21 210 1330 5985 20349 54264 116280 203490 293930 352716 352716 293930 203490 116280 54264 20349 5985 1330 210 21 1
1 22 231 1540 7315 26334 74613 170544 319770 497420 646646 705432 646646 497420 319770 170544 74613 26334 7315 1540 231 22 1

I agree, I wouldn't want you to give me the answer either. I don't think he wants us to do it the way you just did it though, you are correct.

However, I must say that you don't need to know the value of the previous row to use the formula.

I could choose any row, say 6. Since I know that the first value of row 6 is 1, the value for the second value is given by:

(6 -1 + 1)/1 *1 which equals 6. Now, the second value for the 6th row is given by (6-2 +1)/2 *6 which equals (5/2)*6 which equals 15. This pattern will continue, no matter what number you pick. Keeping in mind that the j doesn't pass the i.

This is where the loop comes that iterates until I reach whatever j value I want to reach, which is what I've been trying to do, but have been having lots of trouble doing.

I want to set up a program that counts from 1, where I set the first value I'm counting from to 1, so I could avoid that division by 0, but it is not coming out the way I want it to. I came here because I thought it was a synthax issue I was having.

So let me ask this way, is there anyway I could write a program for what I just said, using loops? Is my method correct, or do you still think that the formula is off base and I was fed bad information?

Thanks a lot for all the help, though brother. You don't have to keep answering me if you are busy, you have helped more than enough.

#9
November 1st, 2013, 07:00 PM
 Chris Charley
Registered User

Join Date: Jul 2013
Posts: 3
Time spent in forums: 1 h 12 m 45 sec
Reputation Power: 0
Another way to get binomial coefficients for Pascal's Triangle and others. This uses Math::BigInt from the bignum module (included in the perl distribution since v5.8). (bnok is n over k)

Code:
```#!/usr/bin/perl
use strict;
use warnings;
use bignum;

# Pascal's triangle
my \$row = 15;
for my \$n (0 .. \$row) {
print join(' ', map nCr(\$n, \$_), 0 .. \$n), "\n";
}
print "\n\n";

for my \$r (2 .. 10) {
printf "C (%d, %d): %d\n", 2 * \$r, \$r, nCr(2*\$r, \$r);
}

# n-Choose-r : A combination of n items r at a time.
sub nCr {
my (\$n, \$r) = @_;
return Math::BigInt->new(\$n)->bnok(\$r);
}

__END__
C:\Old_Data\perlp>perl nCr.pl
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
1 12 66 220 495 792 924 792 495 220 66 12 1
1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
1 15 105 455 1365 3003 5005 6435 6435 5005 3003 1365 455 105 15 1

C (4, 2): 6
C (6, 3): 20
C (8, 4): 70
C (10, 5): 252
C (12, 6): 924
C (14, 7): 3432
C (16, 8): 12870
C (18, 9): 48620
C (20, 10): 184756

C:\Old_Data\perlp>```

#10
November 1st, 2013, 07:03 PM
 seedofwinter
Contributing User

Join Date: Oct 2013
Posts: 32
Time spent in forums: 5 h 58 m 40 sec
Reputation Power: 1
I'm not supposed to print the entire thing into the screen. What is basically supposed to happen is that I'm supposed to be given a row and column, and I'm supposed to give them only that particular value. And since my professor didn't teach all that stuff you are talking about, I'm pretty sure it's a foul ball. Thanks for the help though, Charles

#11
November 1st, 2013, 09:41 PM
 Chris Charley
Registered User

Join Date: Jul 2013
Posts: 3
Time spent in forums: 1 h 12 m 45 sec
Reputation Power: 0
Yes, I see your point. I just wanted to show that it could be done with a method included with the Perl package. Best of luck on your assignment!

 Viewing: Dev Shed Forums > Programming Languages > Perl Programming > Need help with a loop program