Floyd's triangle: Difference between revisions
Line 201: | Line 201: | ||
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. |
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. |
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. Here's a faster version (about 3x on floyd 1000) courtesy of Aai of the J forums: |
||
<lang J>floyd=: [: ({.~ i.&1@E.~&' 0')"1@":@(* ($ $ +/\@,)) >:/~@:i.</lang> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
<lang java> |
<lang java> |
Revision as of 16:34, 26 June 2012
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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:
- Write a program to generate and display here the first n lines of a Floyd triangle.
(Use n=5 and n=14 rows). - 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.
Ada
<lang Ada>with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Command_Line;
procedure Floyd_Triangle is
Rows: constant Positive := Integer'Value(Ada.Command_Line.Argument(1)); Current: Positive := 1; Width: array(1 .. Rows) of Positive;
begin
-- compute the width for the different columns for I in Width'Range loop Width(I) := Integer'Image(I + (Rows * (Rows-1))/2)'Length; end loop; -- output the triangle for Line in 1 .. Rows loop for Column in 1 .. Line loop Ada.Integer_Text_IO.Put(Current, Width => Width(Column)); Current := Current + 1; end loop; Ada.Text_IO.New_Line; end loop;
end Floyd_Triangle;</lang>
- Output:
> ./floyd_triangle 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 > ./floyd_triangle 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
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. Here's a faster version (about 3x on floyd 1000) courtesy of Aai of the J forums:
<lang J>floyd=: [: ({.~ i.&1@E.~&' 0')"1@":@(* ($ $ +/\@,)) >:/~@:i.</lang>
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
<lang pascal>Program FloydDemo (input, output);
procedure floyd1 (numberOfLines: integer); { variant with repeat .. until loop }
var i, j, digits, numbersInLine: integer;
begin digits := trunc(ln(numberOfLines*(numberOfLines+1))/ln(10)) + 1; i := 1; j := 1; numbersInLine := 1; repeat repeat write(i: digits, ' '); inc(i);
inc(j);
until (j > numbersInLine); writeln; j := 1; inc(numbersInLine); until (numbersInLine > numberOfLines); end;
procedure floyd2 (numberOfLines: integer); { Variant with for .. do loop }
var i, j, digits, numbersInLine: integer;
begin digits := trunc(ln(numberOfLines*(numberOfLines+1))/ln(10)) + 1; i := 1; for numbersInLine := 1 to numberOfLines do begin for j := 1 to numbersInLine do begin write(i: digits, ' '); inc(i); end; writeln; end; end;
begin
floyd1(5); floyd2(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 ""
}
}
- 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