Rectángulos en rectángulos

Oct 17 2020

Este código de golf desafío le dará dos números enteros positivos ny kcomo entradas y tienen que contar el número de rectángulos con coordenadas enteras que se pueden extraer con vértices que tocan los cuatro lados de la \$n \times k\$ rectángulo $$ \{(x,y) : 0 \leq x \leq n, 0 \leq y \leq k\}. $$ Es decir, debería haber:

  • al menos un vértice con una \$x\$-coordinada de \$0\$,
  • al menos un vértice con una \$x\$-coordinada de \$n\$,
  • al menos un vértice con una \$y\$-coordinada de \$0\$y
  • al menos un vértice con una \$y\$-coordinada de \$k\$.

Ejemplo

Hay \$a(5,7) = 5\$rectángulos con coordenadas enteras que tocan los cuatro lados de un \$5 \times 7\$ rectángulo:

Mesa

El triángulo inferior de la tabla (simétrica) de \$a(n,k)\$para \$n,k \leq 12\$ es

n\k| 1  2  3  4  5   6   7   8   9  10  11  12
---+----------------------------------------------
 1 | 1  .  .  .  .   .   .   .   .   .   .   .
 2 | 1  2  .  .  .   .   .   .   .   .   .   .
 3 | 1  1  5  .  .   .   .   .   .   .   .   .
 4 | 1  1  1  6  .   .   .   .   .   .   .   .
 5 | 1  1  1  3  9   .   .   .   .   .   .   .
 6 | 1  1  1  1  1  10   .   .   .   .   .   .
 7 | 1  1  1  1  5   1  13   .   .   .   .   .
 8 | 1  1  1  1  1   1   5  14   .   .   .   .
 9 | 1  1  1  1  1   5   1   1  17   .   .   .
10 | 1  1  1  1  1   3   1   3   1  18   .   .
11 | 1  1  1  1  1   1   5   1   5   5  21   .
12 | 1  1  1  1  1   1   1   1   5   1   1  22

Este es un desafío de código de golf , por lo que gana el código más corto.

Respuestas

6 ovs Oct 17 2020 at 22:56

05AB1E , 10 8 bytes

LDI-*`¢O

¡Pruébelo en línea!

Comentó :

          # implicit input: [n, k]
L         # for both values take the [1..x] range
          #   [[1,...,n], [1,...,k]]
 D        # duplicate this list
  I       # push the input [n,k]
   -      # subtract this from the ranges
          #   [[1-n,...,n-n], [1-k,...,k-k]]
          #  =[[-n+1,...,0], [-k+1,...,0]]
    *     # multiply with the ranges
          #   [[1*(-n+1),...,n*0], [1*(-k+1),...,k*0]]
     `    # push all lists of this list on the stack
      ¢   # count the occurences of each value of one list in the other
       O  # sum those counts
14 ovs Oct 17 2020 at 22:06

Python 2 , 66 59 bytes

lambda n,k:sum(a%n*(n-a%n)==a/n*(k-a/n)for a in range(n*k))

¡Pruébelo en línea!

Cada posible rectángulo dentro de \$n \times k\$-rectangle se puede especificar con dos enteros, \$0 \le a \lt n\$y \$0 \le b \lt k\$:

Para verificar un rectángulo dado \$a\$y \$b\$, basta con comprobar si un ángulo es recto. Para hacer esto, tomo el producto escalar de \$\binom{b}{0}-\binom{0}{a}=\binom{-b}{a}\$y \$\binom{k-b}{n}-\binom{0}{a}=\binom{k-b}{n-a}\$para comprobar si el ángulo en \$\binom{0}{a}\$ es un ángulo recto:

$$ \langle \left( \begin{matrix} -b \\ a \\ \end{matrix}\right), \left(\begin{matrix} k-b \\ n-a \\ \end{matrix} \right) \rangle = 0 \\\Leftrightarrow a\cdot(n-a)-b\cdot(k-b)=0 \\\Leftrightarrow a\cdot(n-a)=b\cdot(k-b) $$

4 Noodle9 Oct 18 2020 at 00:41

C (gcc) , 63 61 bytes

Guardado 2 gracias a techocat !!!

s;a;f(n,k){for(s=a=n*k;a--;)s-=a%n*(n-a%n)!=a/n*(k-a/n);a=s;}

¡Pruébelo en línea!

Puerto de la respuesta de Python de ovs .

4 TomerShetah Oct 18 2020 at 13:19

Scala , 65 64 60 51 bytes

n=>k=>0 to n*k-1 count(a=>a%n*(n-a%n)==a/n*(k-a/n))

¡Pruébelo en línea!

  • -1 gracias al usuario !
  • -4 gracias a ovs !
  • -9 gracias a Kjetil !
3 Neil Oct 17 2020 at 22:18

Carbón , 21 bytes

NθNηIΣEθ№Eη×λ⁻ηλ×ι⁻θι

¡Pruébelo en línea! El enlace corresponde a la versión detallada del código. Explicación: Calcula \$ x(n-x) \$para \$ 0 \le x < n \$y \$ y(n-y) \$para \$ 0 \le y < k \$y cuenta el número de veces que aparece un número entero en ambas listas, que corresponde al paralelogramo con coordenadas \$ (x, 0), (0, y), (n - x, 0), (0, k - y) \$ tener ángulos de 90 grados:

NθNη

Entrada \$ n \$y \$ k \$.

IΣ

Genere la suma total de todas las coincidencias encontradas.

Eη×λ⁻ηλ

Calcular \$ y(n-y) \$para \$ 0 \le y < k \$.

Eθ№...×ι⁻θι

Calcular \$ x(n-x) \$para \$ 0 \le x < n \$ y cuente cuántas veces aparece cada número entero en la otra lista.

3 Arnauld Oct 17 2020 at 22:05

JavaScript (ES6),  63 58  56 bytes

Guardado 2 bytes gracias a @ovs

(n,y=x=0)=>g=k=>(x=x||++y*k--&&n)&&(y*k==--x*(n-x))+g(k)

¡Pruébelo en línea!

2 Neil Oct 18 2020 at 09:14

Retina , 45 bytes

\d+
*
L$w`(_+) (_+) $.`*$1=$.2*$' m`^(.*)=\1$

¡Pruébelo en línea! El enlace incluye un conjunto de pruebas. Toma entradas separadas por espacios. Explicación:

\d+
*

Convierta las entradas en unario.

L$w`(_+) (_+)

Coincide con todas las subcadenas que contienen _ _. Esto corresponde a todos los pares de \ $ 0 \ le x <n \ $ y \ $ 0 \ le y <k \ $ que están representados por las partes no coincidentes al principio y al final de la cadena $`y $'respectivamente mientras \ $ n - x \ $ y \ $ k - y \ $ están representados por $1y $2respectivamente.

$.`*$1=$.2*$'

Para cada par, enumere los productos (unarios) \ $ x (n - x) \ $ y \ $ y (k - y) \ $ .

m`^(.*)=\1$

Cuente el número de veces que son iguales.

2 JonathanAllan Oct 18 2020 at 18:34

Gelatina , 8 bytes

r1×ḶċⱮ/S

Un enlace monádico que acepta un par de números enteros que da lugar a la cuenta.

¡Pruébelo en línea! O vea la suite de pruebas .

¿Cómo?

r1×ḶċⱮ/S - Link [n,k]
r1       - ([n,k]) inclusive range to 1 = [[n,n-1,...,1],[k,k-1,...,1]]
   Ḷ     - lowered range ([n,k]) = [[0,1,...,n-1],[0,1,...,k-1]]
  ×      - multiply = [[n×0,(n-1)×1,...,1×(n-1)],[k×0,(k-1)×1,...,1×(k-1)]]
      /  - reduce by - i.e.: f(A=[n×0,(n-1)×1,...,1×(n-1)], B=[k×0,(k-1)×1,...,1×(k-1)])
     Ɱ   -   map with - i.e.: [f(A,v) for v in B]
    ċ    -     count occurrenes (of v in A)
       S - sum
1 AZTECCO Oct 18 2020 at 13:06

Haskell , 53 47 bytes

a#b=sum[1|x<-[1..a],y<-[1..b],x*(a-x)==y*(b-y)]

¡Pruébelo en línea!

  • Guardado 6 gracias a @ovs

Usamos la expresión x/(b-y)==y/(a-x)que se convierte x*(a-x)==y*(b-y)para evitar verificaciones de módulo.

La expresión calcula la relación entre los lados (el segundo invertido) que tiene que ser el mismo para ser un rectángulo válido.

1 NahuelFouilleul Oct 18 2020 at 20:33

Perl 5 , ( -p -Minteger) 54 bytes

/ /;$_=grep$_%$'*($'-$_%$')==$_/$'*($`-$_/$'),1..$`*$'

¡Pruébelo en línea! Usando la misma fórmula y rango de producto que ovs, excepto que el rango comienza desde 1

KevinCruijssen Oct 19 2020 at 08:27

Java 8, 75 bytes

n->k->{int r=0,a=n*k;for(;a-->0;)if(a%n*(n-a%n)==a/n*(k-a/n))r++;return r;}

Port of @ovs 'Python 2 respuesta , ¡así que asegúrate de votarlo!

Pruébelo en línea.

Bubbler Nov 11 2020 at 07:58

Adelante (gforth) , 72 bytes

: f 0e over 0 do dup 0 do
2dup i - i * swap j - j * = s>f f- loop loop ;

¡Pruébelo en línea!

Otro puerto más de la respuesta de Python 2 de ovs , excepto que usa bucles anidados. Los contadores de bucle directo son mucho más económicos cuando se necesitan varias copias.

Toma n kde la pila principal y devuelve el recuento a través de la pila FP.

: f ( n k -- f:cnt )
  0e               \ setup the initial count
  over 0 do        \ outer loop (j): 0 to n-1
    dup 0 do       \ inner loop (i): 0 to k-1
      2dup         \ ( n k n k )
      i - i * swap \ ( n k i*[k-i] n )
      j - j * =    \ ( n k i*[k-i]==j*[n-j] ) Forth boolean is 0/-1
      s>f f-       \ increment count if equal
    loop
  loop
;