Multiplication tables
You are encouraged to solve this task according to the task description, using any language you may know.
Produce a formatted 12×12 multiplication table of the kind memorised by rote when in primary school.
Only print the top half triangle of products.
ALGOL 68
<lang Algol68>main:(
INT max = 12; INT width = ENTIER(log(max)*2)+1; STRING empty = " "*width, sep="|", hr = "+" + (max+1)*(width*"-"+"+"); FORMAT ifmt = $g(-width)"|"$; # remove leading zeros #
printf(($gl$, hr)); print(sep + IF width<2 THEN "x" ELSE " "*(width-2)+"x " FI + sep); FOR col TO max DO printf((ifmt, col)) OD; printf(($lgl$, hr));
FOR row TO max DO [row:max]INT product; FOR col FROM row TO max DO product[col]:=row*col OD; STRING prefix=(empty+sep)*(row-1); printf(($g$, sep, ifmt, row, $g$, prefix, ifmt, product, $l$)) OD; printf(($gl$, hr))
)</lang> Output:
+---+---+---+---+---+---+---+---+---+---+---+---+---+ | x | 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| +---+---+---+---+---+---+---+---+---+---+---+---+---+ | 1| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| 12| | 2| | 4| 6| 8| 10| 12| 14| 16| 18| 20| 22| 24| | 3| | | 9| 12| 15| 18| 21| 24| 27| 30| 33| 36| | 4| | | | 16| 20| 24| 28| 32| 36| 40| 44| 48| | 5| | | | | 25| 30| 35| 40| 45| 50| 55| 60| | 6| | | | | | 36| 42| 48| 54| 60| 66| 72| | 7| | | | | | | 49| 56| 63| 70| 77| 84| | 8| | | | | | | | 64| 72| 80| 88| 96| | 9| | | | | | | | | 81| 90| 99|108| | 10| | | | | | | | | |100|110|120| | 11| | | | | | | | | | |121|132| | 12| | | | | | | | | | | |144| +---+---+---+---+---+---+---+---+---+---+---+---+---+
C
<lang c>#include <math.h>
- include <stdio.h>
int main(int argc, char *argv[]) {
int max = 12; const char *format = " %*d"; const char *format2 = "%*s%c"; int dgts; int i,j; dgts = (int)(.99+ log10(1.0*max*max)); printf(format2, dgts, "",'x'); for (i=1; i <= max; i++) printf(format, dgts, i); printf("\n\n"); for (j=1; j<=max; j++) { printf(format, dgts, j); for(i=1; i<j; i++) printf(format2, dgts, "",' '); for(i=j; i<=max; i++) printf(format, dgts, i*j); printf("\n"); } printf("\n"); return 0;
}</lang> Output:
x 1 2 3 4 5 6 7 8 9 10 11 12 1 1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 3 9 12 15 18 21 24 27 30 33 36 4 16 20 24 28 32 36 40 44 48 5 25 30 35 40 45 50 55 60 6 36 42 48 54 60 66 72 7 49 56 63 70 77 84 8 64 72 80 88 96 9 81 90 99 108 10 100 110 120 11 121 132 12 144
C++
This is a slightly more-generalized version that takes any minimum and maximum table value, and formats the table columns.
<lang cpp>#include <iostream>
- include <iomanip>
- include <cmath> // for log10()
- include <algorithm> // for max()
size_t get_table_column_width(const int min, const int max) {
unsigned int abs_max = std::max(max*max, min*min);
// abs_max is the largest absolute value we might see. // If we take the log10 and add one, we get the string width // of the largest possible absolute value. // Add one for a little whitespace guarantee. size_t colwidth = 1 + std::log10(abs_max) + 1;
// If only one of them is less than 0, then some will // be negative. bool has_negative_result = (min < 0) && (max > 0);
// If some values may be negative, then we need to add some space // for a sign indicator (-) if(has_negative_result) colwidth++;
return colwidth;
}
void print_table_header(const int min, const int max) {
size_t colwidth = get_table_column_width(min, max);
// table corner std::cout << std::setw(colwidth) << " "; for(int col = min; col <= max; ++col) { std::cout << std::setw(colwidth) << col; }
// End header with a newline and blank line. std::cout << std::endl << std::endl;
}
void print_table_row(const int num, const int min, const int max) {
size_t colwidth = get_table_column_width(min, max);
// Header column std::cout << std::setw(colwidth) << num;
// Spacing to ensure only the top half is printed for(int multiplicand = min; multiplicand < num; ++multiplicand) { std::cout << std::setw(colwidth) << " "; }
// Remaining multiplicands for the row. for(int multiplicand = num; multiplicand <= max; ++multiplicand) { std::cout << std::setw(colwidth) << num * multiplicand; }
// End row with a newline and blank line. std::cout << std::endl << std::endl;
}
void print_table(const int min, const int max) {
// Header row print_table_header(min, max);
// Table body for(int row = min; row <= max; ++row) { print_table_row(row, min, max); }
}
int main() {
print_table(1, 12); return 0;
} </lang>
Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 3 9 12 15 18 21 24 27 30 33 36 4 16 20 24 28 32 36 40 44 48 5 25 30 35 40 45 50 55 60 6 36 42 48 54 60 66 72 7 49 56 63 70 77 84 8 64 72 80 88 96 9 81 90 99 108 10 100 110 120 11 121 132 12 144
Common Lisp
<lang lisp> (do ((m 0 (if (= 12 m) 0 (1+ m)))
(n 0 (if (= 12 m) (1+ n) n))) ((= n 13)) (if (zerop n) (case m (0 (format t " *|")) (12 (format t " 12~&---+------------------------------------------------~&")) (otherwise (format t "~4,D" m))) (case m (0 (format t "~3,D|" n)) (12 (format t "~4,D~&" (* n m))) (otherwise (if (>= m n) (format t "~4,D" (* m n)) (format t " "))))))
</lang>
E
<lang e> def size := 12
println(`{|style="border-collapse: collapse; text-align: right;"`) println(`|`) for x in 1..size { println(`|style="border-bottom: 1px solid black; " | $x`) } for y in 1..size { println(`|-`) println(`|style="border-right: 1px solid black;" | $y`) for x in 1..size { println(`| ${if (x >= y) { x*y } else {""}}`) } } println("|}")</lang>
Targets MediaWiki markup. Output:
1 2 3 4 5 6 7 8 9 10 11 12 1 1 2 3 4 5 6 7 8 9 10 11 12 2 4 6 8 10 12 14 16 18 20 22 24 3 9 12 15 18 21 24 27 30 33 36 4 16 20 24 28 32 36 40 44 48 5 25 30 35 40 45 50 55 60 6 36 42 48 54 60 66 72 7 49 56 63 70 77 84 8 64 72 80 88 96 9 81 90 99 108 10 100 110 120 11 121 132 12 144
Factor
<lang factor>USING: io kernel math math.parser math.ranges sequences ; IN: multiplication-table
- print-row ( n -- )
[ number>string 2 CHAR: space pad-head write " |" write ] [ 1 - [ " " write ] times ] [ dup 12 [a,b] [ * number>string 4 CHAR: space pad-head write ] with each ] tri nl ;
- print-table ( -- )
" " write 1 12 [a,b] [ number>string 4 CHAR: space pad-head write ] each nl " +" write 12 [ "----" write ] times nl 1 12 [a,b] [ print-row ] each ;</lang>
1 2 3 4 5 6 7 8 9 10 11 12 +------------------------------------------------ 1 | 1 2 3 4 5 6 7 8 9 10 11 12 2 | 4 6 8 10 12 14 16 18 20 22 24 3 | 9 12 15 18 21 24 27 30 33 36 4 | 16 20 24 28 32 36 40 44 48 5 | 25 30 35 40 45 50 55 60 6 | 36 42 48 54 60 66 72 7 | 49 56 63 70 77 84 8 | 64 72 80 88 96 9 | 81 90 99 108 10 | 100 110 120 11 | 121 132 12 | 144
Forth
<lang forth>
- multiplication-table
cr 2 spaces 13 2 do i 4 u.r loop cr 13 2 do cr i 2 u.r 13 2 do i j < if 4 spaces else i j * 4 u.r then loop loop ;
</lang>
Fortran
<lang fortran>program multtable implicit none
integer :: i, j, k
write(*, "(a)") " x| 1 2 3 4 5 6 7 8 9 10 11 12" write(*, "(a)") "--+------------------------------------------------" do i = 1, 12 write(*, "(i2, a)", advance="no") i, "|"
do k = 2, i
write(*, "(a4)", advance="no") "" end do do j = i, 12 write(*, "(i4)", advance="no") i*j end do write(*, *) end do
end program multtable</lang>
Haskell
<lang haskell>import Control.Monad import Text.Printf
main = do
putStrLn $ " x" ++ concatMap fmt [1..12] zipWithM_ f [1..12] $ iterate (" " ++) "" where f n s = putStrLn $ fmt n ++ s ++ concatMap (fmt . (*n)) [n..12] fmt n = printf "%4d" (n :: Int)</lang>
J
<lang j> multtable=: <:/~ * */~
format=: 'b4.0' 8!:2 ] (('*' ; ,.) ,. ({. ; ])@format@multtable) >:i.12
┌──┬────────────────────────────────────────────────┐ │* │ 1 2 3 4 5 6 7 8 9 10 11 12│ ├──┼────────────────────────────────────────────────┤ │ 1│ 1 2 3 4 5 6 7 8 9 10 11 12│ │ 2│ 4 6 8 10 12 14 16 18 20 22 24│ │ 3│ 9 12 15 18 21 24 27 30 33 36│ │ 4│ 16 20 24 28 32 36 40 44 48│ │ 5│ 25 30 35 40 45 50 55 60│ │ 6│ 36 42 48 54 60 66 72│ │ 7│ 49 56 63 70 77 84│ │ 8│ 64 72 80 88 96│ │ 9│ 81 90 99 108│ │10│ 100 110 120│ │11│ 121 132│ │12│ 144│ └──┴────────────────────────────────────────────────┘</lang>
JavaScript
<lang html4strict><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > <title>12 times table</title> <script type='text/javascript'>
function multiplication_table(n, target) { var table = document.createElement('table');
var row = document.createElement('tr'); var cell = document.createElement('th'); cell.appendChild(document.createTextNode('x')); row.appendChild(cell); for (var x = 1; x <=n; x++) { cell = document.createElement('th'); cell.appendChild(document.createTextNode(x)); row.appendChild(cell); } table.appendChild(row);
for (var x = 1; x <=n; x++) { row = document.createElement('tr'); cell = document.createElement('th'); cell.appendChild(document.createTextNode(x)); row.appendChild(cell); var y; for (y = 1; y < x; y++) { cell = document.createElement('td'); cell.appendChild(document.createTextNode('\u00a0')); row.appendChild(cell); } for (; y <= n; y++) { cell = document.createElement('td'); cell.appendChild(document.createTextNode(x*y)); row.appendChild(cell); } table.appendChild(row); } target.appendChild(table); }
</script> <style type='text/css'>
body {font-family: sans-serif;} table {border-collapse: collapse;} th, td {border: 1px solid black; text-align: right; width: 4ex;}
</style> </head> <body onload="multiplication_table(12, document.getElementById('target'));">
</body> </html></lang>
Outputs (minus the style):
x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | |
3 | 9 | 12 | 15 | 18 | 21 | 24 | 27 | 30 | 33 | 36 | ||
4 | 16 | 20 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | |||
5 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | ||||
6 | 36 | 42 | 48 | 54 | 60 | 66 | 72 | |||||
7 | 49 | 56 | 63 | 70 | 77 | 84 | ||||||
8 | 64 | 72 | 80 | 88 | 96 | |||||||
9 | 81 | 90 | 99 | 108 | ||||||||
10 | 100 | 110 | 120 | |||||||||
11 | 121 | 132 | ||||||||||
12 | 144 |
OCaml
<lang ocaml>let () =
let max = 12 in let fmax = float_of_int max in
let dgts = int_of_float (ceil (log10 (fmax *. fmax))) in let fmt = Printf.printf " %*d" dgts in let fmt2 = Printf.printf "%*s%c" dgts in
fmt2 "" 'x'; for i = 1 to max do fmt i done; print_string "\n\n";
for j = 1 to max do fmt j; for i = 1 to pred j do fmt2 "" ' '; done; for i = j to max do fmt (i*j); done; print_newline() done; print_newline()</lang>
Perl
<lang perl>our $max = 12; our $width = length($max**2) + 1;
printf "%*s", $width, $_ foreach 'x|', 1..$max; print "\n", '-' x ($width - 1), '+', '-' x ($max*$width), "\n"; foreach my $i (1..$max) { printf "%*s", $width, $_
foreach "$i|", map { $_ >= $i and $_*$i } 1..$max;
print "\n"; }</lang>
Output:
x| 1 2 3 4 5 6 7 8 9 10 11 12 ---+------------------------------------------------ 1| 1 2 3 4 5 6 7 8 9 10 11 12 2| 4 6 8 10 12 14 16 18 20 22 24 3| 9 12 15 18 21 24 27 30 33 36 4| 16 20 24 28 32 36 40 44 48 5| 25 30 35 40 45 50 55 60 6| 36 42 48 54 60 66 72 7| 49 56 63 70 77 84 8| 64 72 80 88 96 9| 81 90 99 108 10| 100 110 120 11| 121 132 12| 144
Python
<lang python>>>> size = 12 >>> width = len(str(size**2)) >>> for row in range(-1,size+1): if row==0: print("─"*width + "┼"+"─"*((width+1)*size-1)) else: print("".join("%*s%1s" % ((width,) + (("x","│") if row==-1 and col==0 else (row,"│") if row>0 and col==0 else (col,"") if row==-1 else ("","") if row>col else (row*col,""))) for col in range(size+1)))
x│ 1 2 3 4 5 6 7 8 9 10 11 12
───┼───────────────────────────────────────────────
1│ 1 2 3 4 5 6 7 8 9 10 11 12 2│ 4 6 8 10 12 14 16 18 20 22 24 3│ 9 12 15 18 21 24 27 30 33 36 4│ 16 20 24 28 32 36 40 44 48 5│ 25 30 35 40 45 50 55 60 6│ 36 42 48 54 60 66 72 7│ 49 56 63 70 77 84 8│ 64 72 80 88 96 9│ 81 90 99 108 10│ 100 110 120 11│ 121 132 12│ 144
>>> </lang>
The above works with Python 3.X, which uses Unicode strings by default.
Declaring a file type of UTF-8 and adding a u to all string literals to transform them into Unicode literals would make the above work in Python 2.X.
(As would using ASCII minus, plus, and pipe characters: "-", "+", "|"; instead of the non-ASCII chars used to draw a frame).
Ruby
<lang ruby>def multiplication_table(n)
puts " " + ((" %3d" * n) % (1..n).to_a) 1.upto(n) do |x| print "%3d " % x 1.upto(x-1) {|y| print " "} x.upto(n) {|y| print " %3d" % (x*y)} puts "" end
end
multiplication_table 12</lang>
Tcl
<lang tcl>puts " x\u2502 1 2 3 4 5 6 7 8 9 10 11 12" puts \u0020\u2500\u2500\u253c[string repeat \u2500 48] for {set i 1} {$i <= 12} {incr i} {
puts -nonewline [format "%3d" $i]\u2502[string repeat " " [expr {$i*4-4}]] for {set j 1} {$j <= 12} {incr j} {
if {$j >= $i} { puts -nonewline [format "%4d" [expr {$i*$j}]] }
} puts ""
}</lang> Output:
x│ 1 2 3 4 5 6 7 8 9 10 11 12 ──┼──────────────────────────────────────────────── 1│ 1 2 3 4 5 6 7 8 9 10 11 12 2│ 4 6 8 10 12 14 16 18 20 22 24 3│ 9 12 15 18 21 24 27 30 33 36 4│ 16 20 24 28 32 36 40 44 48 5│ 25 30 35 40 45 50 55 60 6│ 36 42 48 54 60 66 72 7│ 49 56 63 70 77 84 8│ 64 72 80 88 96 9│ 81 90 99 108 10│ 100 110 120 11│ 121 132 12│ 144