¿Cuántos rectángulos hay en la cuadrícula?


29

Bueno, aunque este desafío resultó ser un gran éxito, también resultó ser muy trivial de resolver. Por lo tanto, para aquellos que buscan más desafíos, creé una secuela de este desafío en el que ahora deben contar la cantidad de rectángulos únicos . ¡Echale un vistazo!

Ahora, para aquellos de ustedes que buscan resolver este desafío, aquí viene.


Bueno, todavía no tenemos un desafío como este, así que aquí vamos.

Considere esta 3 x 3cuadrícula de rectángulos:

Ejemplo

¿Cuántos rectángulos hay? Bueno, contando visualmente, podemos ver que en realidad hay 36rectángulos, incluido todo el plano, que se muestran en el GIF animado a continuación:

Rectángulos en el ejemplo

La tarea

El conteo de rectángulos como se muestra arriba es la tarea. En otras palabras, dados 2 enteros mayores o iguales que0 , my n, donde mrepresenta el ancho y nrepresenta la altura, genera el número total de rectángulos en esa m x ncuadrícula de rectángulos.

Reglas

  • El uso de cualquier incorporado que resuelva directamente este problema está explícitamente prohibido.

  • Este desafío no se trata de encontrar la respuesta más corta, sino de encontrar la respuesta más corta en todos los idiomas. Por lo tanto, no se aceptará ninguna respuesta.

  • Las lagunas estándar están prohibidas.

Casos de prueba

Presentado en el formato Array of Integers Input -> Integer Output:

[0,0] -> 0
[1,1] -> 1
[3,3] -> 36 (Visualized above)
[4,4] -> 100
[6,7] -> 588

Referencias

Recuerde, este es el , ¡así que el código más corto gana!


Calculé 588para el último caso de prueba.
Leaky Nun

@LeakyNun Bueno, entonces, supongo que me perdí algunos mientras los contaba . Está arreglado.
R. Kap

¿Cuál es el valor máximo de la entrada?
Erik the Outgolfer

Respuestas:


34

Python, 22 bytes

lambda m,n:m*~m*n*~n/4

La fórmula m*n*(m+1)*(n+1)/4se acorta usando el complemento de bits ~m=-(m+1), expresándose (m+1)*(n+1)como ~m*~n.

¿Por qué es el número de rectángulos m*n*(m+1)*(n+1)/4? Cada rectángulo se especifica mediante la elección de dos líneas horizontales (superior e inferior) y dos líneas verticales (izquierda y derecha). Hay m+1líneas horizontales, de las cuales elegimos un subconjunto de dos distintas. Entonces, el número de opciones es choose(m+1,2), que es m*(m+1)/2. Multiplicar por las n*(n+1)/2opciones para las líneas verticales da el resultado.


Ese truco +1 es brillante.
David Ljung Madison Stellar

11

Jalea , 4 bytes

RS€P

Pruébalo en línea!

Alternativamente, también 4 bytes

pP€S

Pruébalo en línea!


Buen trabajo. Pulgares hacia arriba. :)
R. Kap

24
¿Le importaria explicar?
Pureferret

También hay בHPy ‘c2Pquizás otras alternativas de 4 bytes.
millas

1
@Pureferret Este utiliza la fórmula de OEIS sobre este ser el producto de la nthy mthnúmero triangular. Rconvierte cada número en el índice 1 basado: [1, 2, ..., n]. Ses suma y medios 'cada uno' por lo que cada lista se suman, dando una lista como: [nth triangle number, mth triangle number]. Luego Ptoma el producto de esa lista, que da el resultado deseado.
FryAmTheEggman

1
@FryAmTheEggman así que lo que dices es ... Magia
Pureferret


9

Mathematica, 15 bytes

##(1##+##+1)/4&

Esta es una función sin nombre que toma dos argumentos enteros y devuelve el número de rectángulos.

Explicación

La implementación es básicamente una forma muy golfística del producto de los dos números triangulares. Puede valer la pena leer la sección "Secuencias de argumentos" en esta publicación para obtener detalles, pero trataré de resumir la esencia aquí.

##se expande a una secuencia de todos los argumentos. Esto es similar a las salpicaduras en otros idiomas. Por ejemplo, si los argumentos son 3y 4, entonces {1, 2, ##, 5}te darán {1, 2, 3, 4, 5}. Pero esto no solo funciona en las listas, sino en cualquier expresión, por ejemplo f[1, 2, ##, 5], también lo sería f[1, 2, 3, 4, 5].

Esto se pone interesante cuando se combina ##con operadores. Todos los operadores en Mathematica son solo manos cortas para alguna f[...]expresión similar (posiblemente anidada). Por ejemplo, a+bes Plus[a, b]y a-brealmente representa Plus[a, Times[-1, b]]. Ahora, cuando se combina ##con operadores, lo que hace Mathematica es expandir los operadores primero, tratándolos ##como un solo operando, y expandirlos solo al final. Al insertar ##en los lugares correctos, podemos usarlo tanto para multiplicar como para agregar los operandos.

Hagamos esto para el código anterior:

##(1##+##+1)/4

Expandiéndolo a su forma completa, obtenemos esto:

Times[##, Plus[Times[1, ##], ##, 1], Rational[1/4]]

Insertemos los argumentos de la función ay b:

Times[a, b, Plus[Times[1, a, b], a, b, 1], Rational[1/4]]

Y ahora lo convertimos nuevamente en notación matemática estándar:

a * b * (a * b + a + b + 1) / 4

Un poco de reorganización muestra que este es el producto de los números triangulares:

a * b * (a + 1) * (b + 1) / 4
(a * (a + 1) / 2) * (b * (b + 1) / 2)
T(a) * T(b)

Dato curioso: esta implementación es tan deportiva que tiene la misma longitud que la integrada para calcular un solo número triangular PolygonalNumber.


8

C, 25 bytes

#define r(x,y)x*y*~x*~y/4

Versión purista (27):

r(x,y){return x*y*~x*~y/4;}

Versión ISO-er (35):

#define r(x,y)((x)*(y)*~(x)*~(y)/4)

¿Qué versión crees que es mejor?
Erik the Outgolfer

8

Medusa , 16 bytes

p|%/**+1
  4  Ei

El formato de entrada es [x y], la salida es solo el resultado.

Pruébalo en línea!

Solución alternativa, mismo recuento de bytes:

pm%/*[*i
  4  +1

Explicación

¡Es hora de darle a Jellyfish la presentación que se merece! :)

Jellyfish es el lenguaje de Zgarb basado en su desafío de sintaxis 2D . La semántica está inspirada en gran medida por J, pero la sintaxis es una obra de arte. Todas las funciones son caracteres individuales y se presentan en una cuadrícula. Las funciones toman sus argumentos de la siguiente ficha al sur y al este de ellos y devuelven el resultado al norte y al oeste. Esto le permite crear una red interesante de llamadas a funciones donde reutiliza valores pasándolos a varias funciones desde múltiples direcciones.

Si ignoramos el hecho de que algunos de los tokens en el programa anterior son operadores especiales (funciones de nivel superior), el programa anterior se escribiría algo así en un lenguaje sensato:

p(|( /*(i*(i+1)) % 4 ))

Veamos el código de abajo hacia arriba. La entrada es alimentada por i, que por lo tanto se evalúa como [x y].

La +parte superior recibe esta entrada junto con el literal 1y, por lo tanto, incrementa ambos elementos para dar [(x+1) (y+1)](la mayoría de las operaciones se enhebran automáticamente en las listas).

El otro valor de ise envía a la izquierda, pero las Edivisiones son argumentos orientales norte y oeste. Eso significa que las entradas a la derecha *son en realidad [x y]y [(x+1) (y+1)]esto calcula [x*(x+1) y*(y+1)].

El siguiente *es modificado por el precedente, lo /que lo convierte en una operación de plegado. Doblar *sobre un par simplemente lo multiplica, para que podamos obtener x*(x+1)*y*(y+1).

Ahora %es solo división, así que computa x*(x+1)*y*(y+1)/4. Desafortunadamente, esto da como resultado un flotador, por lo que debemos redondearlo con el unario |. Finalmente, se alimenta este valor pque imprime el resultado final.


Podría haber jurado que leí algo en los documentos sobre la división de enteros ...
Conor O'Brien

7

R, 40 35 bytes

Bueno, ¡es hora de saltar al fondo! Aquí está mi código R , inspirado en la respuesta @xnor:

a=scan();(n=a[1])*(m=a[2])*(n+1)*(m+1)/4 

EDITAR : En esta versión, R pedirá dos veces entradas.

(n=scan())*(m=scan())*(n+1)*(m+1)/4

cat(prod(choose(scan()+1,2)))es de 29 bytes.
Giuseppe

6

CJam, 12 10 Bytes

2 bytes guardados gracias a Martin.

{_:)+:*4/}

Pruébalo en línea!

Este es un bloque que toma una lista de 2 elementos de la pila y deja la solución en la pila. Programa completo utilizable para la prueba: riari+{_:)+:*4/}~.

Basado en la excelente solución python de xnor.

Explicación:

{_:)+:*4/}
{        } -- Define a block
 _:)       -- Duplicate list, increment all values in new list
    +      -- Join the two lists
     :*    -- Fold multiply over all 4 elements
       4/  -- Divide by 4

2
¿Creo que esto funciona para 10 si ingresas una lista de dos elementos? {_:~+:*4/}
Martin Ender

En realidad, no hay necesidad de usarlo ~en CJam. Solo úsalo ).
Martin Ender

5

Matlab 23 19 bytes

@(x)prod([x/2,x+1])

Implementación de la fórmula m*n*(m+1)*(n+1)/4
Uso:ans([m,n])


4

MATL , 6 bytes

tQ*2/p

La entrada es una matriz de la forma [m,n].

Pruébalo en línea!

Explicación

Cálculo directo basado en la fórmula m*(m+1)*n*(n+1)/4.

t     % Input array [m,n] implicitly. Duplicate
Q     % Add 1 to each entry of the copy: gives [m+1,n+1]
*     % Multiply element-wise: gives [m*(m+1),n*(n+1)]
2/    % Divide each entry by 2: [m*(m+1)/2,n*(n+1)/2]
p     % Product of the two entries: m*(m+1)*n*(n+1)/4. Display implicitly


4

Java 7, 39 38 bytes

int c(int a,int b){return~a*a*b*~b/4;}

Java 8, 26 25 19 18 17 bytes

a->b->a*~a*b*~b/4

Basado en la excelente respuesta de @xnor . Múltiples bytes guardados gracias a @DavidConrad . Pruébalo aquí.

Código de prueba (Java 7):

Pruébalo aquí.

class M{
  static int c(int a,int b){return~a*a*b*~b/4;}

  public static void main(String[] a){
    System.out.println(c(0, 0));
    System.out.println(c(1, 1));
    System.out.println(c(3, 3));
    System.out.println(c(4, 4));
    System.out.println(c(6, 7));
  }
}

Salida:

0
1
36
100
588

1
No necesita eso returny a->b->es un byte más corto que (a,b)->.
David Conrad el

2
Tampoco creo que necesite el punto y coma, ya que si pasara la lambda a un método que tomara Function<Integer, Function<Integer, Integer>>como parámetro, no sería seguido por un punto y coma.
David Conrad el

2
Estoy de acuerdo con @DavidConrad: no cuento el final ;en una sola declaración J8 lambdas.
CAD97

@DavidConrad Perdón por la edición muy tardía, pero solo ahora me di cuenta de que leí más allá de tu comentario para eliminar el return .. Además, casi nunca programo en Java 8 (de ahí todas mis respuestas de Java 7), pero ¿cómo me pongo a->b->a trabajar? Aquí está la ideona para el caso actual.
Kevin Cruijssen

1
Perdón por la muy tardía respuesta! Necesita curry la función, por lo que necesita cambiar MathOperation.operationpara tomar solo uno int, devolver a Function<Integer, Integer>, y cuando lo llama, inicialmente pasa solo el primer parámetro a, y luego llama .apply(b)al Function. También necesitas importar java.util.function.Function. Aquí hay una idea con los cambios.
David Conrad

3

Ruby, 22 bytes

Robando el truco de @xnor y haciendo una lambda stabby

r=->(m,n){m*n*~m*~n/4}

Llamada de ejemplo:

r[6,7]     # => 588

O como proceso, también 22 bytes:

proc{|m,n|m*n*~m*~n/4}

A lo que luego podríamos llamar:

proc{|m,n|m*n*~m*~n/4}.call(6,7)     # => 588

No necesita nombrarlo: las funciones anónimas están bien según la convención del sitio
Conor O'Brien el

3

Laberinto , 13 11 bytes

*?;*_4/!
):

Pruébalo en línea!

Explicación

Esto también calcula el producto de los números triangulares como la mayoría de las respuestas. El bloque principal de 2x2 es un pequeño bucle:

*?
):

En la primera iteración *no hace nada, por lo que el orden de bucle real es este:

?   Read integer N from STDIN or 0 at EOF and push onto stack. If 0, exit the loop.
:   Duplicate N.
)   Increment.
*   Multiply to get N*(N+1).

El código restante es solo lineal:

;   Discard the zero that terminated the loop.
*   Multiply the other two values.
_4  Push a 4.
/   Divide.
!   Print.

Labyrinth luego intenta ejecutarse /nuevamente, lo que termina el programa debido a una división por cero.


2

Pyke, 6 bytes

mh+Bee

Pruébalo aquí!

mh     -    map(increment, input)
  +    -   ^ + input
   B   -  product(^)
    ee - ^ \ 4

Esto podría usar un desglose, pero personalmente considero que es una obra de arte.
corsiKa

2

05AB1E, 4 bytes

€LOP

Explicación

Utiliza la fórmula descrita en A096948

      # Implicit input, ex: [7,6]
€L    # Enumerate each, [[1,2,3,4,5,6,7],[1,2,3,4,5,6]]
  O   # Sum, [28,21]
   P  # Product, 588
      # Implicit display

Toma la entrada como [n, m] .

Pruébalo en línea


1

Pyth 8 6 bytes

Dos bytes guardados gracias a @DenkerAffe.

*FmsSd

La entrada se espera como una lista como [m,n]. Pruébalo aquí .

Explicación:

          Implicit assignment of Q to eval(input).
*         Multiplication.
 F        Splat the following sequence onto the arguments of the previous function.
  m       Map the following function of d over Q (Q is implicitly added to the end).
   s      Reduce the following list with addition, initial value of 0.
    Sd    Return range(1,d+1).

1
Puede usar en Flugar de .*y eliminar el Qya que se agrega implícitamente.
Denker

Lo sabía Fpero no sabía cómo usarlo y pensé que tenía que usarlo .*en su lugar ... ¡Gracias!
Rhyzomatic

1

C #, 19 bytes

(n,m)=>m*n*~m*~n/4;

Una función anónima basada en la respuesta de @ xnor.


1

Lua, 74 63 bytes

x,y=...n=0 for i=1,y do for j=i,i*x,i do n=n+j end end print(n)

La función toma la entrada como parámetros numéricos.

Debido a la forma en que se implementa Lua, esta es técnicamente una función, con argumentos variables, que se puede invocar envolviéndola en una declaración de "función", o cargándola desde el código fuente usando "cargas de cadena"


1
Veo que tienes bastante código allí solo para E / S. ¿Quizás sería más corto simplemente hacer una función que tome los dos números y devuelva la respuesta, y elimine todo este código de E / S innecesario?
Zwei

@Zwei Olvidé que las funciones pueden ingresar datos por parámetros. Gracias por señalar eso.
brianush1

La función podría llamarse algo así como "f" en lugar del nombre completo "función" para guardar 7 bytes más
Zwei

En Lua, se requiere la palabra clave "función" para declarar una función. Si no se especifica ningún nombre (por ejemplo, "función f ()"), es una función anónima. (ej: "función ()"). Por lo tanto, la "función" es necesaria para que el código funcione.
brianush1

Oh, olvidé que lua funciona así. ¡Mi error!
Zwei


1

Brain-Flak , 84 80 bytes

({}<>)({({})<({}[()])>}{})<>({({})<({}[()])>}{}[()]){<>(({}))<>({}[()])}<>({{}})

Pruébalo en línea!

Probablemente muy subóptimo, especialmente debido a la reutilización del código con respecto a los números de triángulo, pero al menos tenemos una solución Brain-Flak que funciona.

Lamentablemente, parece fallar haciendo un bucle infinito con el caso de 0 0prueba, pero todos los demás funcionan bien.




Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.