Recent

Author Topic: [SOLVED] Pascal's triangle- alignment of values  (Read 4827 times)

qwapp

  • Newbie
  • Posts: 6
[SOLVED] Pascal's triangle- alignment of values
« on: March 21, 2018, 06:38:42 pm »
So I've come up with the code to the values of the triangle itself. What I'm currently strugling is how to aligne/center the values that are printed. I tried many things but, I could use some help now. If anyone has an idea how this can be done feel free to share! Thank you

Code: Pascal  [Select][+][-]
  1. Program Tri_pas;
  2. Uses Crt;
  3. Var
  4.     linha,ordem,a,b: byte;  
  5.  
  6.  
  7. Function fat(X: byte): real; // factorial
  8. Var fat1:  real;
  9. Begin
  10.  
  11.   fat1:=1;  
  12.   If X <= 1 Then  
  13.     fat:=1
  14.   Else
  15.   Begin
  16.     Repeat
  17.       fat1:=(fat1 * X);
  18.       X:=(X - 1);
  19.     Until X <= 1;
  20.     fat:=fat1;
  21.   End;
  22.  
  23. End;
  24.  
  25.  
  26.  
  27. Procedure nCp(n,p: byte);  //Combinations
  28. Var
  29.     i: byte;
  30.     nCp: real;
  31. Begin
  32.  
  33.   If n < 1 Then
  34.     n:=0  
  35.   Else
  36.     n:=(n-1);
  37.    
  38.   For i:=0 to n do    
  39.   Begin
  40.     writeln;
  41.     For p:=0 to i do  
  42.     Begin
  43.       nCp:= fat(i) / (fat(p) * fat(i - p));    //  mathematic formula for the combinations      
  44.       Write(nCp:1:0,' ');
  45.     End;
  46.   End;
  47.  
  48. End;
  49.  
  50.  
  51. { Main Programa  }
  52.  
  53. Begin
  54.  
  55.   Write('Insert a line(1 -> n) :  ');
  56.   Readln(linha);
  57.   nCp(linha,ordem);
  58.   readln;  
  59.  
  60. End.
  61.  
  62.  
« Last Edit: March 23, 2018, 10:58:29 am by qwapp »

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Pascal's triangle- alignment of values
« Reply #1 on: March 21, 2018, 11:11:53 pm »
Assuming you want to center the entire string on the screen and assuming the screen is 80 characters wide, then you can use a function like this to center it on the screen:
(untested code)

Code: Pascal  [Select][+][-]
  1. procedure CenterWriteln(const S: String);
  2. var
  3.   X: Integer;
  4. begin
  5.   X := (80 - Length(S)) div 2;
  6.   GotoXY(X, WhereY);
  7.   writeln(S);
  8. end;
  9.  

Now instead of doing consecutve writes in nCp(), first build up the string (line) and then use CenterWriteln() to display it.

You can extend the function to use the actual characters the screen is wide (80 is just the default on Windows).

Aah, this reminds me of the good old days of TP  ;)

Bart

qwapp

  • Newbie
  • Posts: 6
Re: Pascal's triangle- alignment of values
« Reply #2 on: March 22, 2018, 12:35:56 pm »
I like the idea, but my problem  was to convert Real into String. For some reason I cant implement the "FloatToStr" function and similar ones. Maybe I'm doing something wrong, but I dont know what..
« Last Edit: March 22, 2018, 12:39:33 pm by qwapp »

Handoko

  • Hero Member
  • *****
  • Posts: 5122
  • My goal: build my own game engine using Lazarus
Re: Pascal's triangle- alignment of values
« Reply #3 on: March 22, 2018, 04:10:39 pm »
I guess it is a homework and you're not allowed to use any string functions. It is hard but still doable. Well ... because we're allowed to use CRT unit only, the code is ugly.

Here you are:

Code: Pascal  [Select][+][-]
  1. Program Tri_pas;
  2. Uses Crt;
  3. Var
  4.     linha,ordem,a,b: byte;
  5.  
  6.  
  7. Function fat(X: byte): real; // factorial
  8. Var fat1:  real;
  9. Begin
  10.  
  11.   fat1:=1;
  12.   If X <= 1 Then
  13.     fat:=1
  14.   Else
  15.   Begin
  16.     Repeat
  17.       fat1:=(fat1 * X);
  18.       X:=(X - 1);
  19.     Until X <= 1;
  20.     fat:=fat1;
  21.   End;
  22.  
  23. End;
  24.  
  25.  
  26.  
  27. Procedure nCp(n,p: byte);  //Combinations
  28. Var
  29.     i: byte;
  30.     nCp: real;
  31.     LineLength: Integer;
  32. Begin
  33.  
  34.   If n < 1 Then
  35.     n:=0
  36.   Else
  37.     n:=(n-1);
  38.  
  39.   For i:=0 to n do
  40.   Begin
  41.     writeln;
  42.  
  43.     // Fill spaces for centering the output
  44.     LineLength := 0;
  45.     For p:=0 to i do
  46.     Begin
  47.       nCp:= fat(i) / (fat(p) * fat(i - p));
  48.       if nCp > 999999 then Inc(LineLength, 8)
  49.         else
  50.           if nCp > 99999 then Inc(LineLength, 7)
  51.             else
  52.               if nCp > 9999 then Inc(LineLength, 6)
  53.                 else
  54.                   if nCp > 999 then Inc(LineLength, 5)
  55.                     else
  56.                       if nCp > 99 then Inc(LineLength, 4)
  57.                         else
  58.                           if nCp > 9 then Inc(LineLength, 3)
  59.                             else
  60.                               Inc(LineLength, 2);
  61.     end;
  62.     if LineLength > 80 then LineLength := 80;
  63.     Write(Space(40 - LineLength div 2));
  64.  
  65.     For p:=0 to i do
  66.     Begin
  67.       nCp:= fat(i) / (fat(p) * fat(i - p));    //  mathematic formula for the combinations
  68.       Write(nCp:1:0,' ');
  69.     End;
  70.   End;
  71.  
  72. End;
  73.  
  74.  
  75. { Main Programa  }
  76.  
  77. Begin
  78.  
  79.   Write('Insert a line(1 -> n) :  ');
  80.   Readln(linha);
  81.   nCp(linha,ordem);
  82.   readln;
  83.  
  84. End.

I didn't modify your code, I only added lines #43..#63 and variable "LineLength".

Below is the screenshot running the program on my Linux Terminal.

--- edit ---
If Space function is not allowed, you can rewrite it using a for-do looping.
« Last Edit: March 22, 2018, 04:30:47 pm by Handoko »

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Pascal's triangle- alignment of values
« Reply #4 on: March 22, 2018, 08:03:51 pm »
I like the idea, but my problem  was to convert Real into String.

That to me was totally unclear from your post.

I have another observation about your code.
For each line you calc the binomial co-efficients and you use floating point arithmatic to do so.
This of course will fail for larger numbers (due to rounding errors and the inherit nature of floating point numbers on a binary system).
I understand why you use floats, because even 64-bit integers will overflow rapidly when using them to calculate factorials.

However, when you always calculate/display the entire Pascal triangle (up to some level n), there is no need to do so.
You can construct all numbers by adding (which is way faster than floating point calculations): each number in a row is constructe by adding the 2 nodes diagonally above them.

Consider the first 3 rows
Code: [Select]
  1
 1 1
1 2 1

You can construct the 4th row: 1 (=0+1), 3 (=1+2), 3 (=2+1) and 1 (=1 + 0)

So, as long as you remember the last row (call it R) you calculated, you can calculate the next: 0+R[1], R[1]+R[2], R[2]+R[3], .. R[n-1]+R[n], R[n]+0.
Notice that 0+R1 will always be equal to 1, as is R[n+0]
Also notice that you only have to calculate half of the row, since R[k] = R[n-k].

Constructing the triangle this way will be much faster, and it will be acurate until you overflow the largest unsigned integer type we currently have (UInt64).

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: Pascal's triangle- alignment of values
« Reply #5 on: March 22, 2018, 10:11:54 pm »
Of course one could use the LOG function to find out number of places!

or make a Function that counts the number of times 10 can be divided into the numerator.

This at least can give you the number whole digits..

 at least that is what I think is happening here.

 There is always the STR Procedure ! :D
The only true wisdom is knowing you know nothing

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Pascal's triangle- alignment of values
« Reply #6 on: March 22, 2018, 10:33:48 pm »
Based on my previous observations:

Code: Pascal  [Select][+][-]
  1. Program Tri_pas;
  2.  
  3. {$mode objfpc}
  4.  
  5. uses
  6.   SysUtils, Crt;
  7.  
  8. type
  9.   TUInt64Array = array of UInt64;
  10.   TPascalTriangle = array of TUInt64Array;
  11.  
  12.  
  13. procedure CenterLn(const S: String);
  14. begin
  15.   GotoXY((80-Length(S)) div 2, WhereY);
  16.   writeln(S);
  17. end;
  18.  
  19. function ArrToString(Line: TUInt64Array): String;
  20. var
  21.   i: Integer;
  22. begin
  23.   Result := '';
  24.   for i := Low(Line) to High(Line) do
  25.   begin
  26.     Result := Result + IntToStr(Line[i]);
  27.     if (i < High(Line)) then Result := Result + #32;
  28.   end;
  29. end;
  30.  
  31. procedure MakeTriangle(var Triangle: TPascalTriangle; Depth: Word);
  32. var
  33.   Len, Row, Mid, i: Integer;
  34. begin
  35.   SetLength(Triangle, 0);
  36.   SetLength(Triangle, Depth);
  37.   for Row := 0 to Depth - 1 do
  38.   begin
  39.     Len :=  Row + 1;
  40.     Mid := ((Len+1) div 2) - 1; //zero indexed
  41.     SetLength(Triangle[Row], Len);
  42.     if (Row = 0) then
  43.       Triangle[0,0] := 1
  44.     else
  45.     begin
  46.       Triangle[Row,0] := 1;
  47.       Triangle[Row,Len-1] := 1;
  48.       for i := 1 to Mid do
  49.       begin
  50.         Triangle[Row,i] := Triangle[Row-1,i-1] + Triangle[Row-1,i];
  51.       end;
  52.       for i := Mid + 1 to Len - 2 do
  53.       begin
  54.         Triangle[Row,i] := Triangle[Row,Len-i-1];
  55.       end;
  56.     end;
  57.   end;
  58. end;
  59.  
  60. procedure DisplayTriangle(Triangle: TPascalTriangle);
  61. var
  62.   Row: Integer;
  63.   S: String;
  64. begin
  65.   for Row := Low(Triangle) to High(Triangle) do
  66.   begin
  67.     S := ArrToString(Triangle[Row]);
  68.     CenterLn(S);
  69.   end;
  70. end;
  71.  
  72.  
  73. var
  74.   Triangle: TPascalTriangle;
  75.   Depth: Integer;
  76. begin
  77.   SetLength(Triangle, 0);
  78.   write('Enter number of lines for Pascal''s Triangle: ');
  79.   readln(Depth);
  80.   MakeTriangle(Triangle, Depth);
  81.   DisplayTriangle(Triangle);
  82. end.

Example:
Code: [Select]
Enter number of lines for Pascal's Triangle: 15
                                      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

Bart

qwapp

  • Newbie
  • Posts: 6
Re: Pascal's triangle- alignment of values
« Reply #7 on: March 23, 2018, 10:57:34 am »
Wow ,  thank you so much for the help everyone, i really appreciated it!  :D
« Last Edit: March 23, 2018, 11:10:37 am by qwapp »

 

TinyPortal © 2005-2018