可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I recently pointed a student doing work experience to an article about dumping a multiplication table to the console. It used a nested for loop and multiplied the step value of each.
This looked like a .NET 2.0 approach. I was wondering, with the use of Linq and extension methods,for example, how many lines of code it would take to achieve the same result.
Is the stackoverflow community up to the challenge?
The challenge:
In a console application, write code to generate a table like this example:
01 02 03 04 05 06 07 08 09
02 04 06 08 10 12 14 16 18
03 06 09 12 15 18 21 24 27
04 08 12 16 20 24 28 32 36
05 10 15 20 25 30 35 40 45
06 12 18 24 30 36 42 48 54
07 14 21 28 35 42 49 56 63
08 16 24 32 40 48 56 64 72
09 18 27 36 45 54 63 72 81
As this turned into a language-agnostic code-golf battle, I'll go with the communities decision about which is the best solution for the accepted answer.
There's been alot of talk about the spec and the format that the table should be in, I purposefully added the 00 format but the double new-line was originally only there because I didn't know how to format the text when creating the post!
回答1:
J - 8 chars - 24 chars for proper format
*/~1+i.9
Gives:
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
This solution found by @earl:
'r(0)q( )3.'8!:2*/~1+i.9
Gives:
01 02 03 04 05 06 07 08 09
02 04 06 08 10 12 14 16 18
03 06 09 12 15 18 21 24 27
04 08 12 16 20 24 28 32 36
05 10 15 20 25 30 35 40 45
06 12 18 24 30 36 42 48 54
07 14 21 28 35 42 49 56 63
08 16 24 32 40 48 56 64 72
09 18 27 36 45 54 63 72 81
回答2:
MATLAB - 10 characters
a=1:9;a'*a
... or 33 characters for stricter output format
a=1:9;disp(num2str(a'*a,'%.2d '))
回答3:
Brainf**k - 185 chars
>---------[++++++++++>---------[+<[-<+>>+++++++++[->+>>---------[>-<++++++++++<]<[>]>>+<<<<]>[-<+>]<---------<]<[->+<]>>>>++++[-<++++>]<[->++>+++>+++<<<]>>>[.[-]<]<]++++++++++.[-<->]<+]
回答4:
cat - 252 characters
01 02 03 04 05 06 07 08 09
02 04 06 08 10 12 14 16 18
03 06 09 12 15 18 21 24 27
04 08 12 16 20 24 28 32 36
05 10 15 20 25 30 35 40 45
06 12 18 24 30 36 42 48 54
07 14 21 28 35 42 49 56 63
08 16 24 32 40 48 56 64 72
09 18 27 36 45 54 63 72 81
Assuming that a trailing newline is wanted; otherwise, 251 chars.
* runs *
回答5:
Python - 61 chars
r=range(1,10)
for y in r:print"%02d "*9%tuple(y*x for x in r)
回答6:
C#
This is only 2 lines. It uses lambdas not extension methods
var nums = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
nums.ForEach(n => { nums.ForEach(n2 => Console.Write((n * n2).ToString("00 "))); Console.WriteLine(); });
and of course it could be done in one long unreadable line
new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.ForEach(n => { new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.ForEach(n2 => Console.Write((n * n2).ToString("00 "))); Console.WriteLine(); });
all of this is assuming you consider a labmda one line?
回答7:
K - 12 characters
Let's take the rosetta-stoning seriously, and compare Kdb+'s K4 with the canonical J solution (*/~1+i.9
):
a*/:\:a:1+!9
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
J's "table" operator (/
) equals the K "each-left each-right" (/:\:
) idiom. We don't have J's extremely handy "reflexive" operator (~
) in K, so we have to pass a
as both left and right argument.
回答8:
Fortran95 - 40 chars (beating perl by 4 chars!)
This solution does print the leading zeros as per the spec.
print"(9(i3.2))",((i*j,i=1,9),j=1,9);end
回答9:
Oracle SQL, 103 characters:
select n, n*2, n*3, n*4, n*5, n*6, n*7, n*8, n*9 from (select rownum n from dual CONNECT BY LEVEL < 10)
回答10:
C# - 117, 113, 99, 96, 95 89 characters
updated based on NickLarsen's idea
for(int x=0,y;++x<10;)
for(y=x;y<x*10;y+=x)
Console.Write(y.ToString(y<x*9?"00 ":"00 \n"));
99, 85, 82 81 characters
... If you don't care about the leading zeros and would allow tabs for alignment.
for(int x=0,y;++x<10;)
{
var w="";
for(y=1;++y<10;)
w+=x*y+" ";
Console.WriteLine(w);
}
回答11:
COBOL - 218 chars -> 216 chars
PROGRAM-ID.P.DATA DIVISION.WORKING-STORAGE SECTION.
1 I PIC 9.
1 N PIC 99.
PROCEDURE DIVISION.PERFORM 9 TIMES
ADD 1 TO I
SET N TO I
PERFORM 9 TIMES
DISPLAY N' 'NO ADVANCING
ADD I TO N
END-PERFORM
DISPLAY''
END-PERFORM.
Edit
216 chars (probably a different compiler)
PROGRAM-ID.P.DATA DIVISION.WORKING-STORAGE SECTION.
1 I PIC 9.
1 N PIC 99.
PROCEDURE DIVISION.
PERFORM B 9 TIMES
STOP RUN.
B.
ADD 1 TO I
set N to I
PERFORM C 9 TIMES
DISPLAY''.
C.
DISPLAY N" "NO ADVANCING
Add I TO N.
回答12:
Not really a one-liner, but the shortest linq i can think of:
var r = Enumerable.Range(1, 9);
foreach (var z in r.Select(n => r.Select(m => n * m)).Select(a => a.Select(b => b.ToString("00 "))))
{
foreach (var q in z)
Console.Write(q);
Console.WriteLine();
}
In response to combining this and SRuly's answer
Enumberable.Range(1,9).ToList.ForEach(n => Enumberable.Range(1,9).ToList.ForEach(n2 => Console.Write((n * n2).ToString("00 "))); Console.WriteLine(); });
回答13:
Ruby - 42 Chars (including one linebreak, interactive command line only)
This method is two lines of input and only works in irb
(because irb gives us _
), but shortens the previous method by a scant 2 charcters.
1..9
_.map{|y|puts"%02d "*9%_.map{|x|x*y}}
Ruby - 44 Chars (tied with perl)
(a=1..9).map{|y|puts"%02d "*9%a.map{|x|x*y}}
Ruby - 46 Chars
9.times{|y|puts"%02d "*9%(1..9).map{|x|x*y+x}}
Ruby - 47 Chars
And back to a double loop
(1..9).map{|y|puts"%02d "*9%(1..9).map{|x|x*y}}
Ruby - 54 chars!
Using a single loop saves a couple of chars!
(9..89).map{|n|print"%02d "%(n/9*(x=n%9+1))+"\n"*(x/9)}
Ruby - 56 chars
9.times{|x|puts (1..9).map{|y|"%.2d"%(y+x*y)}.join(" ")}
回答14:
Haskell — 85 84 79 chars
r=[1..9]
s x=['0'|x<=9]++show x
main=mapM putStrLn[unwords[s$x*y|x<-r]|y<-r]
If double spacing is required (89 81 chars),
r=[1..9]
s x=['0'|x<=9]++show x
main=mapM putStrLn['\n':unwords[s$x*y|x<-r]|y<-r]
回答15:
F# - 61 chars:
for y=1 to 9 do(for x=1 to 9 do printf"%02d "(x*y));printfn""
If you prefer a more applicative/LINQ-y solution, then in 72 chars:
[1..9]|>Seq.iter(fun y->[1..9]|>Seq.iter((*)y>>printf"%02d ");printfn"")
回答16:
c# - 125, 123 chars (2 lines):
var r=Enumerable.Range(1,9).ToList();
r.ForEach(n=>{var s="";r.ForEach(m=>s+=(n*m).ToString("00 "));Console.WriteLine(s);});
回答17:
C - 97 79 characters
#define f(i){int i=0;while(i++<9)
main()f(x)f(y)printf("%.2d ",x*y);puts("");}}
回答18:
Perl, 44 chars
(No hope of coming anywhere near J, but languages with matrix ops are in a class of their own here...)
for$n(1..9){printf"%3d"x9 .$/,map$n*$_,1..9}
回答19:
R (very similar to Matlab on this level): 12 characters.
> 1:9%*%t(1:9)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 2 3 4 5 6 7 8 9
[2,] 2 4 6 8 10 12 14 16 18
[3,] 3 6 9 12 15 18 21 24 27
[4,] 4 8 12 16 20 24 28 32 36
[5,] 5 10 15 20 25 30 35 40 45
[6,] 6 12 18 24 30 36 42 48 54
[7,] 7 14 21 28 35 42 49 56 63
[8,] 8 16 24 32 40 48 56 64 72
[9,] 9 18 27 36 45 54 63 72 81
回答20:
PHP, 71 chars
for($x=0;++$x<10;print"\n"){for($y=0;++$y<10;){printf("%02d ",$x*$y);}}
Output:
$ php -r 'for($x=0;++$x<10;print"\n"){for($y=0;++$y<10;){printf("%02d ",$x*$y);}}'
01 02 03 04 05 06 07 08 09
02 04 06 08 10 12 14 16 18
03 06 09 12 15 18 21 24 27
04 08 12 16 20 24 28 32 36
05 10 15 20 25 30 35 40 45
06 12 18 24 30 36 42 48 54
07 14 21 28 35 42 49 56 63
08 16 24 32 40 48 56 64 72
09 18 27 36 45 54 63 72 81
回答21:
C#, 135 chars, nice and clean:
var rg = Enumerable.Range(1, 9);
foreach (var rc in from r in rg
from c in rg
select (r * c).ToString("D2") + (c == 9 ? "\n\n" : " "))
Console.Write(rc);
回答22:
PostgreSQL: 81 74 chars
select array(select generate_series(1,9)*x)from generate_series(1,9)as x;
回答23:
Ruby - 56 chars :D
9.times{|a|9.times{|b|print"%02d "%((a+1)*(b+1))};puts;}
回答24:
C - 66 Chars
This resolves the complaint about the second parameter of main :)
main(x){for(x=8;x++<89;)printf("%.2d%c",x/9*(x%9+1),x%9<8?32:10);}
C - 77 chars
Based on dreamlax's 97 char answer. His current answer somewhat resembles this one now :)
Compiles ok with gcc, and main(x,y)
is fair game for golf i reckon
#define f(i){for(i=0;i++<9;)
main(x,y)f(x)f(y)printf("%.2d ",x*y);puts("");}}
回答25:
XQuery 1.0 (96 bytes)
string-join(for$x in 1 to 9 return(for$y in 1 to 9 return concat(0[$x*$y<10],$x*$y,' '),'
'),'')
Run (with XQSharp) with:
xquery table.xq !method=text
回答26:
Scala - 77 59 58 chars
print(1 to 9 map(p=>1 to 9 map(q=>"%02d "format(p*q))mkString)mkString("\n"))
Sorry, I had to do this, the Scala solution by Malax was way too readable...
[Edit] For comprehension seems to be the better choice:
for(p<-1 to 9;q<-{println;1 to 9})print("%02d "format p*q)
[Edit] A much longer solution, but without multiplication, and much more obfuscated:
val s=(1 to 9).toSeq
(s:\s){(p,q)=>println(q.map("%02d "format _)mkString)
q zip(s)map(t=>t._1+t._2)}
回答27:
PHP, 62 chars
for(;$x++<9;print"\n",$y=0)while($y++<9)printf("%02d ",$x*$y);
回答28:
Java - 155 137 chars
- Update 1: replaced string building by direct printing. Saved 18 chars.
class M{public static void main(String[]a){for(int x,y=0,z=10;++y<z;System.out.println())for(x=0;++x<z;System.out.printf("%02d ",x*y));}}
More readable format:
class M{
public static void main(String[]a){
for(int x,y=0,z=10;++y<z;System.out.println())
for(x=0;++x<z;System.out.printf("%02d ",x*y));
}
}
回答29:
Another attempt using C#/Linq with GroupJoin:
Console.Write(
String.Join(
Environment.NewLine,
Enumerable.Range(1, 9)
.GroupJoin(Enumerable.Range(1, 9), y => 0, x => 0, (y, xx) => String.Join(" ", xx.Select(x => x * y)))
.ToArray()));
回答30:
Ruby — 47 chars
puts (a=1..9).map{|i|a.map{|j|"%2d"%(j*i)}*" "}
Output
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
(If we ignore spacing, it becomes 39: puts (a=1..9).map{|i|a.map{|j|j*i}*" "}
And anyway, I feel like there's a bit of room for improvement with the wordy map
stuff.)