Floyd's triangle

From Rosetta Code
Task
Floyd's triangle
You are encouraged to solve this task according to the task description, using any language you may know.

Floyd's triangle lists the natural numbers in a right triangle aligned to the left where

  • the first row is just 1
  • successive rows start towards the left with the next number followed by successive naturals listing one more number than the line above.

The first few lines of a Floyd triangle looks like this:

 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15

The task is to:

  1. Write a program to generate and display here the first n lines of a Floyd triangle.
    (Use n=5 and n=14 rows).
  2. Ensure that when displayed in a monospace font, the numbers line up in vertical columns as shown and that only one space separates numbers of the last row.

D

<lang d>import std.stdio, std.conv;

void floyd(in uint n) {

   immutable llc = n * (n - 1) / 2 + 1; // lower left corner
   foreach (r; 0 .. n) {
       foreach (c; 0 .. r + 1) {
           const nc = text(llc + c).length.text();
           writef("%" ~ nc ~ (c == r ? "d" : "d "),
                  r * (r + 1) / 2 + c + 1);
       }
       writeln();
   }

}

void main() {

   floyd(5);
   floyd(14);

}</lang>

Output:
 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15
 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44  45
46 47 48 49 50 51 52 53  54  55
56 57 58 59 60 61 62 63  64  65  66
67 68 69 70 71 72 73 74  75  76  77  78
79 80 81 82 83 84 85 86  87  88  89  90  91
92 93 94 95 96 97 98 99 100 101 102 103 104 105

Go

<lang go>package main

import "fmt"

func main() {

   floyd(5)
   floyd(14)

}

func floyd(n int) {

   fmt.Printf("Floyd %d:\n", n)
   lowerLeftCorner := n*(n-1)/2 + 1
   lastInColumn := lowerLeftCorner
   lastInRow := 1
   for i, row := 1, 1; row <= n; i++ {
       w := len(fmt.Sprint(lastInColumn))
       if i < lastInRow {
           fmt.Printf("%*d ", w, i)
           lastInColumn++
       } else {
           fmt.Printf("%*d\n", w, i)
           row++
           lastInRow += row
           lastInColumn = lowerLeftCorner
       }
   }

}</lang>

Output:
Floyd 5:
 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15
Floyd 14:
 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15
16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35 36
37 38 39 40 41 42 43 44  45
46 47 48 49 50 51 52 53  54  55
56 57 58 59 60 61 62 63  64  65  66
67 68 69 70 71 72 73 74  75  76  77  78
79 80 81 82 83 84 85 86  87  88  89  90  91
92 93 94 95 96 97 98 99 100 101 102 103 104 105

J

Note: require 'strings' does nothing in J7, but is harmless (strings is already incorporated in J7).

<lang J>require 'strings' floyd=: [: rplc&(' 0';' ')"1@":@(* ($ $ +/\@,)) >:/~@:i.</lang>

Note, the parenthesis around ($ $ +/\@,) is optional, and only included for emphasis.

Example use:

<lang J> floyd 5

1            
2  3         
4  5  6      
7  8  9 10   

11 12 13 14 15

  floyd 14
1                                             
2  3                                          
4  5  6                                       
7  8  9 10                                    

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105</lang>

How it works:

First, we create a square lower triangular matrix with our argument as the length of one side. We have 1s along the diagonal and the lower triangle, and 0s for the upper triangle.

Second, we create a running sum of these values (treating rows as being adjacent horizontally for this purpose). Then, we multiply this result by our lower triangular matrix (forcing the upper triangle to be 0s).

Then, we format the matrix as text (which gives us the required vertical alignment), and in each row we replace each space followed by a zero with two spaces.

Efficiency note: In a measurement of time used: in floyd 100, 80% the time here goes into the string manipulations -- sequential additions and multiplications are cheap. In floyd 1000 this jumps to 98% of the time.

Java

<lang java> public class Floyd { public static void main(String[] args){ System.out.println("5 rows:"); printTriangle(5); System.out.println("14 rows:"); printTriangle(14); }

private static void printTriangle(int n){ for(int rowNum = 1, printMe = 1, numsPrinted = 0; rowNum <= n; printMe++){ int cols = (int)Math.ceil(Math.log10(n*(n-1)/2 + numsPrinted + 2)); System.out.printf("%"+cols+"d ", printMe); if(++numsPrinted == rowNum){ System.out.println(); rowNum++; numsPrinted = 0; } } } }</lang> Output:

5 rows:
 1 
 2  3 
 4  5  6 
 7  8  9 10 
11 12 13 14 15 
14 rows:
 1 
 2  3 
 4  5  6 
 7  8  9 10 
11 12 13 14 15 
16 17 18 19 20 21 
22 23 24 25 26 27 28 
29 30 31 32 33 34 35 36 
37 38 39 40 41 42 43 44  45 
46 47 48 49 50 51 52 53  54  55 
56 57 58 59 60 61 62 63  64  65  66 
67 68 69 70 71 72 73 74  75  76  77  78 
79 80 81 82 83 84 85 86  87  88  89  90  91 
92 93 94 95 96 97 98 99 100 101 102 103 104 105 

Pascal

Works with: Free_Pascal

<lang pascal>Program FloydDemo (input, output);

procedure floyd (numberOfLines: integer);

 var
   i, j, digits, numbersInLine: integer;
 begin
   digits := trunc(ln(numberOfLines*(numberOfLines+1))/ln(10));
   i := 1;
   j := 1;
   numbersInLine := 1;
   repeat
     repeat
       write(i: digits+1, ' ');
       inc(i);

inc(j);

     until (j > numbersInLine);
     writeln;
     j := 1;
     inc(numbersInLine);
   until (numbersInLine > numberOfLines);
 end;

begin

 floyd(5);
 floyd(14);

end.</lang> Output:

% ./Floyd
 1 
 2  3 
 4  5  6 
 7  8  9 10 
11 12 13 14 15 
  1 
  2   3 
  4   5   6 
  7   8   9  10 
 11  12  13  14  15 
 16  17  18  19  20  21 
 22  23  24  25  26  27  28 
 29  30  31  32  33  34  35  36 
 37  38  39  40  41  42  43  44  45 
 46  47  48  49  50  51  52  53  54  55 
 56  57  58  59  60  61  62  63  64  65  66 
 67  68  69  70  71  72  73  74  75  76  77  78 
 79  80  81  82  83  84  85  86  87  88  89  90  91 
 92  93  94  95  96  97  98  99 100 101 102 103 104 105 

Python

<lang python>>>> def floyd(rowcount=5): rows = 1 while len(rows) < rowcount: n = rows[-1][-1] + 1 rows.append(list(range(n, n + len(rows[-1]) + 1))) return rows

>>> floyd() [[1], [2, 3], [4, 5, 6], [7, 8, 9, 10], [11, 12, 13, 14, 15]] >>> def pfloyd(rows=[[1], [2, 3], [4, 5, 6], [7, 8, 9, 10]]): colspace = [len(str(n)) for n in rows[-1]] for row in rows: print( ' '.join('%*i' % space_n for space_n in zip(colspace, row)))


>>> pfloyd() 1 2 3 4 5 6 7 8 9 10 >>> pfloyd(floyd(5))

1
2  3
4  5  6
7  8  9 10

11 12 13 14 15 >>> pfloyd(floyd(14))

1
2  3
4  5  6
7  8  9 10

11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 >>> </lang>

Tcl

<lang tcl>proc floydTriangle n {

   # Compute the column widths
   for {set i [expr {$n*($n-1)/2+1}]} {$i <= $n*($n+1)/2} {incr i} {

lappend w [string length $i]

   }
   # Print the triangle
   for {set i 0; set j 1} {$j <= $n} {incr j} {

for {set p -1; set k 0} {$k < $j} {incr k} { puts -nonewline [format "%*d " [lindex $w [incr p]] [incr i]] } puts ""

   }

}

  1. Demonstration

puts "Floyd 5:" floydTriangle 5 puts "Floyd 14:" floydTriangle 14</lang>

Output:
Floyd 5:
 1 
 2  3 
 4  5  6 
 7  8  9 10 
11 12 13 14 15 
Floyd 14:
 1 
 2  3 
 4  5  6 
 7  8  9 10 
11 12 13 14 15 
16 17 18 19 20 21 
22 23 24 25 26 27 28 
29 30 31 32 33 34 35 36 
37 38 39 40 41 42 43 44  45 
46 47 48 49 50 51 52 53  54  55 
56 57 58 59 60 61 62 63  64  65  66 
67 68 69 70 71 72 73 74  75  76  77  78 
79 80 81 82 83 84 85 86  87  88  89  90  91 
92 93 94 95 96 97 98 99 100 101 102 103 104 105