language agnostic - Code-golf: tabla de multiplicar de salida a la consola
language-agnostic rosetta-stone (30)
Hace poco, señalé a un estudiante que estaba haciendo una experiencia laboral un artículo sobre cómo volcar una tabla de multiplicar en la consola. Usó un bucle anidado y multiplicó el valor del paso de cada uno.
Esto parecía un enfoque de .NET 2.0. Me preguntaba, con el uso de Linq y los métodos de extensión, por ejemplo, cuántas líneas de código se necesitarían para lograr el mismo resultado.
¿La comunidad de stackoverflow está a la altura del desafío?
El desafío: en una aplicación de consola, escriba código para generar una tabla como este ejemplo:
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
Dado que esto se convirtió en una batalla de golf de código sin idioma, recurriré a la decisión de la comunidad sobre cuál es la mejor solución para la respuesta aceptada.
Se ha hablado mucho sobre la especificación y el formato en el que debería estar la tabla; a propósito, agregué el formato 00, ¡pero la doble nueva línea originalmente solo estaba allí porque no sabía cómo formatear el texto al crear la publicación!
F # - 61 caracteres:
for y=1 to 9 do(for x=1 to 9 do printf"%02d "(x*y));printfn""
Si prefiere una solución más aplicativa / LINQ-y, entonces en 72 caracteres:
[1..9]|>Seq.iter(fun y->[1..9]|>Seq.iter((*)y>>printf"%02d ");printfn"")
Perl, 44 caracteres
(No hay esperanza de acercarse a J, pero los idiomas con operaciones matriciales están en una clase propia aquí ...)
for$n(1..9){printf"%3d"x9 .$/,map$n*$_,1..9}
Scala - 77 59 58 caracteres
print(1 to 9 map(p=>1 to 9 map(q=>"%02d "format(p*q))mkString)mkString("/n"))
Lo siento, tuve que hacer esto, la solución Scala de Malax era demasiado legible ...
[Editar] Para la comprensión parece ser la mejor opción:
for(p<-1 to 9;q<-{println;1 to 9})print("%02d "format p*q)
[Editar] Una solución mucho más larga, pero sin multiplicación, y mucho más confusa:
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)}
gato - 252 caracteres
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
Suponiendo que se quiere una nueva línea final; De lo contrario, 251 caracteres.
* carreras *
C - 66 caracteres
Esto resuelve la queja sobre el segundo parámetro de main :)
main(x){for(x=8;x++<89;)printf("%.2d%c",x/9*(x%9+1),x%9<8?32:10);}
C - 77 caracteres
Basado en la respuesta de 97 caracteres de dreamlax. Su respuesta actual se parece un poco a esta ahora :)
Compila ok con gcc, y main(x,y)
es un juego justo para el golf, creo
#define f(i){for(i=0;i++<9;)
main(x,y)f(x)f(y)printf("%.2d ",x*y);puts("");}}
C - 97 79 caracteres
#define f(i){int i=0;while(i++<9)
main()f(x)f(y)printf("%.2d ",x*y);puts("");}}
COBOL - 218 caracteres -> 216 caracteres
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.
Editar
216 caracteres (probablemente un compilador diferente)
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.
Fortran95 - 40 caracteres (superando a Perl por 4 caracteres!)
Esta solución imprime los ceros iniciales según la especificación.
print"(9(i3.2))",((i*j,i=1,9),j=1,9);end
Haskell - 85 84 79 caracteres
r=[1..9]
s x=[''0''|x<=9]++show x
main=mapM putStrLn[unwords[s$x*y|x<-r]|y<-r]
Si se requiere doble espacio ( 89 81 caracteres),
r=[1..9]
s x=[''0''|x<=9]++show x
main=mapM putStrLn[''/n'':unwords[s$x*y|x<-r]|y<-r]
Java - 155 137 caracteres
- Actualización 1: se reemplazó la construcción de cadenas por impresión directa. Guarda 18 caracteres.
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));}}
Formato más legible:
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));
}
}
K - 12 caracteres
Tomemos en serio el apedreamiento de rosetta y comparemos el K4 de Kdb + con la solución J canónica ( */~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
El operador de "tabla" de J ( /
) es igual a la expresión K "cada-izquierda, cada una derecha" ( /:/:
:). No tenemos el operador "reflexivo" extremadamente práctico de J ( ~
) en K, así que tenemos que pasar a
argumento tanto a la izquierda como a la derecha.
MATLAB - 10 caracteres
a=1:9;a''*a
... o 33 caracteres para un formato de salida más estricto
a=1:9;disp(num2str(a''*a,''%.2d ''))
PHP, 62 caracteres
for(;$x++<9;print"/n",$y=0)while($y++<9)printf("%02d ",$x*$y);
PHP, 71 caracteres
for($x=0;++$x<10;print"/n"){for($y=0;++$y<10;){printf("%02d ",$x*$y);}}
Salida:
$ 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
PostgreSQL: 81 74 caracteres
select array(select generate_series(1,9)*x)from generate_series(1,9)as x;
Python - 61 caracteres
r=range(1,10)
for y in r:print"%02d "*9%tuple(y*x for x in r)
Ruby - 56 caracteres: D
9.times{|a|9.times{|b|print"%02d "%((a+1)*(b+1))};puts;}
Ruby: 42 caracteres (incluido un salto de línea, solo línea de comandos interactiva)
Este método es de dos líneas de entrada y solo funciona en irb
(porque irb nos da _
), pero acorta el método anterior en unos pocos caracteres.
1..9
_.map{|y|puts"%02d "*9%_.map{|x|x*y}}
Ruby - 44 caracteres (atado con perl)
(a=1..9).map{|y|puts"%02d "*9%a.map{|x|x*y}}
Ruby - 46 caracteres
9.times{|y|puts"%02d "*9%(1..9).map{|x|x*y+x}}
Ruby - 47 caracteres
Y volviendo a un bucle doble.
(1..9).map{|y|puts"%02d "*9%(1..9).map{|x|x*y}}
Ruby - 54 caracteres!
¡Usar un solo bucle guarda un par de caracteres!
(9..89).map{|n|print"%02d "%(n/9*(x=n%9+1))+"/n"*(x/9)}
Ruby - 56 caracteres
9.times{|x|puts (1..9).map{|y|"%.2d"%(y+x*y)}.join(" ")}
c # - 125 , 123 caracteres (2 líneas):
var r=Enumerable.Range(1,9).ToList();
r.ForEach(n=>{var s="";r.ForEach(m=>s+=(n*m).ToString("00 "));Console.WriteLine(s);});
Ruby - 47 caracteres
puts (a=1..9).map{|i|a.map{|j|"%2d"%(j*i)}*" "}
Salida
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
(Si ignoramos el espacio, se convierte en 39: puts (a=1..9).map{|i|a.map{|j|j*i}*" "}
Y de todos modos, siento que hay un poco de espacio para mejorar con el map
Wordy cosas.)
J - 8 caracteres - 24 caracteres para un formato adecuado
*/~1+i.9
Da:
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
Esta solución encontrada por @earl:
''r(0)q( )3.''8!:2*/~1+i.9
Da:
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
Brainf ** k - 185 caracteres
>---------[++++++++++>---------[+<[-<+>>+++++++++[->+>>---------[>-<++++++++++<]<[>]>>+<<<<]>[-<+>]<---------<]<[->+<]>>>>++++[-<++++>]<[->++>+++>+++<<<]>>>[.[-]<]<]++++++++++.[-<->]<+]
C #, 135 caracteres, agradable y limpio:
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);
No es realmente de una sola línea, pero el linq más corto que se me ocurre:
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();
}
En respuesta a la combinación de esto y la respuesta de SRuly.
Enumberable.Range(1,9).ToList.ForEach(n => Enumberable.Range(1,9).ToList.ForEach(n2 => Console.Write((n * n2).ToString("00 "))); Console.WriteLine(); });
Oracle SQL, 103 caracteres:
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)
Otro intento de usar C # / Linq con 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()));
R (muy similar a Matlab en este nivel): 12 caracteres.
> 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
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,'' ''),''
''),'''')
Ejecutar (con XQSharp ) con:
xquery table.xq !method=text
C # - 117, 113, 99, 96, 95 89 caracteres
actualizado basado en NickLarsen''s idea NickLarsen''s
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 caracteres ... Si no te importan los ceros iniciales y permitirías las pestañas para la alineación.
for(int x=0,y;++x<10;)
{
var w="";
for(y=1;++y<10;)
w+=x*y+" ";
Console.WriteLine(w);
}
DO#
Esto es sólo 2 líneas. Utiliza lambdas no métodos de extensión.
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(); });
Y, por supuesto, se podría hacer en una larga línea ilegible.
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(); });
¿Todo esto suponiendo que consideres un labmda una línea?