#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep 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
    larger than your row length";


    }
    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. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    776
    Rep Power
    495
    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.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    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.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    776
    Rep Power
    495
    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 01:50 PM.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    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.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    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 ) {
    print "Your column length must not be larger than your row
    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.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    776
    Rep Power
    495
    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:
    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
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep Power
    1
    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:
    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.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    9
    Rep 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>
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2013
    Posts
    37
    Rep 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
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    9
    Rep 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!

IMN logo majestic logo threadwatch logo seochat tools logo