Rectangles en rectangles

Oct 17 2020

Ce défi de code-golf vous donnera deux entiers positifs net kcomme entrées et vous fera compter le nombre de rectangles avec des coordonnées entières qui peuvent être dessinés avec des sommets touchant les quatre côtés du \$n \times k\$ rectangle $$ \{(x,y) : 0 \leq x \leq n, 0 \leq y \leq k\}. $$ Autrement dit, il devrait y avoir:

  • au moins un sommet avec un \$x\$-coordonné de \$0\$,
  • au moins un sommet avec un \$x\$-coordonné de \$n\$,
  • au moins un sommet avec un \$y\$-coordonné de \$0\$, et
  • au moins un sommet avec un \$y\$-coordonné de \$k\$.

Exemple

Il y a \$a(5,7) = 5\$rectangles avec des coordonnées entières touchant les quatre côtés d'un \$5 \times 7\$ rectangle:

Table

Le triangle inférieur de la table (symétrique) de \$a(n,k)\$pour \$n,k \leq 12\$ est

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

C'est un défi de code-golf , donc le code le plus court l'emporte.

Réponses

6 ovs Oct 17 2020 at 22:56

05AB1E , 10 8 octets

LDI-*`¢O

Essayez-le en ligne!

Commenté :

          # 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 octets

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

Essayez-le en ligne!

Chaque rectangle possible à l'intérieur du \$n \times k\$-rectangle peut être spécifié par deux entiers, \$0 \le a \lt n\$et \$0 \le b \lt k\$:

Pour vérifier un rectangle donné \$a\$et \$b\$, il suffit de vérifier si un angle est un angle droit. Pour ce faire, je prends le produit scalaire de \$\binom{b}{0}-\binom{0}{a}=\binom{-b}{a}\$et \$\binom{k-b}{n}-\binom{0}{a}=\binom{k-b}{n-a}\$pour vérifier si l'angle à \$\binom{0}{a}\$ est un angle droit:

$$ \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 octets

Enregistré 2 grâce à plafonnier !!!

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

Essayez-le en ligne!

La réponse Python du port de ovs .

4 TomerShetah Oct 18 2020 at 13:19

Scala , 65 64 60 51 octets

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

Essayez-le en ligne!

  • -1 merci à l' utilisateur !
  • -4 grâce aux ovs !
  • -9 grâce à Kjetil !
3 Neil Oct 17 2020 at 22:18

Charbon , 21 octets

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

Essayez-le en ligne! Le lien est vers la version verbeuse du code. Explication: Calcule \$ x(n-x) \$pour \$ 0 \le x < n \$et \$ y(n-y) \$pour \$ 0 \le y < k \$et compte le nombre de fois qu'un entier apparaît dans les deux listes, ce qui correspond au parallélogramme avec les coordonnées \$ (x, 0), (0, y), (n - x, 0), (0, k - y) \$ ayant des angles de 90 degrés:

NθNη

Entrée \$ n \$et \$ k \$.

IΣ

Affiche la somme totale de toutes les correspondances trouvées.

Eη×λ⁻ηλ

Calculer \$ y(n-y) \$pour \$ 0 \le y < k \$.

Eθ№...×ι⁻θι

Calculer \$ x(n-x) \$pour \$ 0 \le x < n \$ et comptez combien de fois chaque entier apparaît dans l'autre liste.

3 Arnauld Oct 17 2020 at 22:05

JavaScript (ES6),  63 58  56 octets

Sauvegardé 2 octets grâce à @ovs

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

Essayez-le en ligne!

2 Neil Oct 18 2020 at 09:14

Rétine , 45 octets

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

Essayez-le en ligne! Le lien comprend une suite de tests. Prend des entrées séparées par des espaces. Explication:

\d+
*

Convertissez les entrées en unaire.

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

Correspond à toutes les sous-chaînes qui contiennent _ _. Cela correspond à toutes les paires de \ $ 0 \ le x <n \ $ et \ $ 0 \ le y <k \ $ qui sont représentées par les parties sans correspondance au début et à la fin de la chaîne $`et $'respectivement tandis que \ $ n - x \ $ et \ $ k - y \ $ sont respectivement représentés par $1et $2.

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

Pour chaque paire, listez les produits (unaires) \ $ x (n - x) \ $ et \ $ y (k - y) \ $ .

m`^(.*)=\1$

Comptez le nombre de fois où ils sont égaux.

2 JonathanAllan Oct 18 2020 at 18:34

Gelée , 8 octets

r1×ḶċⱮ/S

Un lien monadique acceptant une paire d'entiers qui donne le décompte.

Essayez-le en ligne! Ou voir la suite de tests .

Comment?

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 octets

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

Essayez-le en ligne!

  • Enregistré 6 grâce à @ovs

Nous utilisons l'expression x/(b-y)==y/(a-x)qui est convertie en x*(a-x)==y*(b-y)pour éviter les vérifications modulo.

L'expression calcule le rapport entre les côtés (le deuxième inversé) qui doit être le même pour être un rectangle valide.

1 NahuelFouilleul Oct 18 2020 at 20:33

Perl 5 , ( -p -Minteger) 54 octets

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

Essayez-le en ligne! En utilisant la même formule et la même gamme de produits que ovs sauf que la gamme commence à 1

KevinCruijssen Oct 19 2020 at 08:27

Java 8, 75 octets

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 de la réponse Python 2 de @ovs , alors assurez-vous de le voter!

Essayez-le en ligne.

Bubbler Nov 11 2020 at 07:58

Forth (gforth) , 72 octets

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

Essayez-le en ligne!

Encore un autre portage de la réponse Python 2 d' ovs , sauf qu'il utilise des boucles imbriquées. Les compteurs en boucle directe sont beaucoup moins chers lorsque plusieurs copies sont nécessaires.

Prend n kde la pile principale et renvoie le compte via la pile 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
;