Combien de rectangles dans la grille?

29

Eh bien, bien que ce défi se soit avéré un énorme succès, il s'est également avéré très trivial à résoudre. Par conséquent, pour ceux qui recherchent plus d'un défi, j'ai créé une suite à ce défi dans laquelle vous devez maintenant compter le nombre de rectangles uniques . Vérifiez-le!

Maintenant, pour ceux d'entre vous qui cherchent à résoudre ce défi, le voici.


Eh bien, nous n'avons pas encore vraiment de défi comme celui-ci, alors c'est parti.

Considérez cette 3 x 3grille de rectangles:

Example

Combien de rectangles y a-t-il? Eh bien, en comptant visuellement, nous pouvons voir qu'il existe en fait des 36rectangles, y compris le plan entier lui-même, qui sont tous montrés dans le GIF animé ci-dessous:

Rectangles in Example

La tâche

Le comptage des rectangles comme indiqué ci-dessus est la tâche. En d'autres termes, étant donné 2 entiers supérieurs ou égaux à 0, met n, où mreprésente la largeur et nla hauteur, affiche le nombre total de rectangles dans cette m x ngrille de rectangles.

Règles

  • L'utilisation de tout module intégré qui résout directement ce problème est explicitement interdite.

  • Ce défi ne consiste pas à trouver la réponse la plus courte, mais à trouver la réponse la plus courte dans toutes les langues. Par conséquent, aucune réponse ne sera acceptée.

  • Les failles standard sont interdites.

Cas de test

Présenté dans le format Array of Integers Input -> Integer Output:

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

Les références

Rappelez-vous, c'est le , donc le code le plus court gagne!

R. Kap
la source
J'ai calculé 588pour le dernier cas de test.
Leaky Nun
@LeakyNun Eh bien, je suppose que j'en ai manqué en les comptant . C'est réparé.
R. Kap
Quelle est la valeur maximale de l'entrée?
Erik the Outgolfer
Pertinent
shooqie

Réponses:

34

Python, 22 octets

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

La formule m*n*(m+1)*(n+1)/4est raccourcie en utilisant le complément de bits ~m=-(m+1), exprimant (m+1)*(n+1)comme ~m*~n.

Pourquoi le nombre de rectangles m*n*(m+1)*(n+1)/4? Chaque rectangle est spécifié par le choix de deux lignes horizontales (haut et bas) et deux lignes verticales (gauche et droite). Il y a des m+1lignes horizontales, dont nous choisissons un sous-ensemble de deux lignes distinctes. Donc, le nombre de choix est choose(m+1,2), ce qui est m*(m+1)/2. La multiplication par les n*(n+1)/2choix des lignes verticales donne le résultat.

xnor
la source
Cette astuce +1 est géniale.
David Ljung Madison Stellar
11

Gelée , 4 octets

RS€P

Essayez-le en ligne!

Alternativement, également 4 octets

pP€S

Essayez-le en ligne!

Leaky Nun
la source
Bon travail. Pouces vers le haut. :)
R. Kap
24
Soin d'expliquer?
Pureferret
Il existe également בHPet ‘c2Pet peut-être d'autres alternatives de 4 octets.
miles
1
Cette @Pureferret utilise la formule de OEIS sur ce qui est le produit de la nthet mthnombre triangulaire. Rconvertit chaque nombre dans l'index de base 1: [1, 2, ..., n]. Sest somme et signifie «chacun», donc chaque liste est additionnée, donnant une liste comme:[nth triangle number, mth triangle number] . Prend ensuite Ple produit de cette liste, ce qui donne le résultat souhaité.
FryAmTheEggman
1
@FryAmTheEggman alors quel est votre dicton .... Magic
Pureferret
9

Javascript (ES6), 17 octets

m=>n=>m*n*~m*~n/4

Une fourchette de cette réponse .

f=m=>n=>m*n*~m*~n/4
alert(f(prompt())(prompt()))

Leaky Nun
la source
Je ne suis pas sûr, le curry est-il OK dans les langues qui ne le font pas par défaut?
John Dvorak
1
@JanDvorak Meta post .
Leaky Nun
9

Mathematica, 15 octets

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

Il s'agit d'une fonction sans nom prenant deux arguments entiers et renvoyant le nombre de rectangles.

Explication

L'implémentation est fondamentalement une forme très golfique du produit des deux nombres triangulaires. Il vaut peut-être la peine de lire la section "Séquences d'arguments" dans ce post pour les détails, mais je vais essayer de résumer l'essentiel ici.

##se développe en une séquence de tous les arguments. C'est similaire à l' éclaboussure dans d'autres langues. Par exemple, si les arguments sont 3et 4, {1, 2, ##, 5}vous obtiendrez {1, 2, 3, 4, 5}. Mais cela ne fonctionne pas seulement dans les listes, mais dans n'importe quelle expression, par exemple, f[1, 2, ##, 5]serait égalementf[1, 2, 3, 4, 5] .

Cela devient intéressant lorsque vous combinez ##avec des opérateurs. Tous les opérateurs de Mathematica ne sont que des raccourcis pour une f[...]expression similaire (éventuellement imbriquée). Par exemple, a+best Plus[a, b]et a-breprésente réellement Plus[a, Times[-1, b]]. Maintenant, lorsque vous combinez ##avec des opérateurs, Mathematica fait d'abord développer les opérateurs, en les traitant ##comme un opérande unique, et en les développant uniquement à la fin. En insérant## aux bons endroits, on peut donc l'utiliser à la fois pour multiplier et pour ajouter les opérandes.

Faisons cela pour le code ci-dessus:

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

En l'étendant à sa pleine forme, nous obtenons ceci:

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

Insérons les arguments de la fonction aet b:

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

Et maintenant, nous le reconvertissons en notation mathématique standard:

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

Un petit réarrangement montre que c'est le produit des nombres triangulaires:

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

Fait d'amusement: cette mise en œuvre est si Golfy, c'est la même longueur que le intégré pour le calcul d' un seul numéro triangulaire, PolygonalNumber.

Martin Ender
la source
8

C, 25 octets

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

Version puriste (27):

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

Version ISO-er (35):

#define r(x,y)((x)*(y)*~(x)*~(y)/4)
Erik le Outgolfer
la source
Quelle version pensez-vous est la meilleure?
Erik the Outgolfer
8

Méduse , 16 octets

p|%/**+1
  4  Ei

Le format d'entrée est [x y], la sortie n'est que le résultat.

Essayez-le en ligne!

Solution alternative, même nombre d'octets:

pm%/*[*i
  4  +1

Explication

Il est temps de donner à Jellyfish l'introduction qu'il mérite! :)

La méduse est Zgarb de basé sur son défi de syntaxe 2D . La sémantique est largement inspirée de J, mais la syntaxe est une œuvre d'art. Toutes les fonctions sont des caractères uniques et disposées sur une grille. Les fonctions prennent leurs arguments du prochain jeton au sud et à l'est et retournent le résultat au nord et à l'ouest. Cela vous permet de créer un réseau intéressant d'appels de fonctions où vous réutilisez des valeurs en les passant dans plusieurs fonctions de plusieurs directions.

Si nous ignorons le fait que certains des jetons du programme ci-dessus sont des opérateurs spéciaux (fonctions de niveau supérieur), le programme ci-dessus serait écrit quelque chose comme ceci dans un langage sain:

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

Passons en revue le code de bas en haut. L'entrée est alimentée par lei , qui est donc évalué à [x y].

Le +dessus reçoit cette entrée avec le littéral 1et incrémente donc les deux éléments pour donner[(x+1) (y+1)] (la plupart des opérations sont enfilées automatiquement sur les listes).

L'autre valeur de iest envoyée à gauche, mais la Edivision est l'argument est nord et ouest. Cela signifie que les entrées à droite *sont en fait [x y]et [(x+1) (y+1)]donc cela calcule[x*(x+1) y*(y+1)] .

Le suivant *est en fait modifié par le précédent /qui le transforme en opération de pliage. Se replier *sur une paire la multiplie simplement, pour que nous obtenions x*(x+1)*y*(y+1).

Maintenant, %c'est juste la division, donc ça calcule x*(x+1)*y*(y+1)/4. Malheureusement, cela se traduit par un flotteur, nous devons donc l'arrondir avec l'unaire |. Enfin, cette valeur est fournie à plaquelle imprime le résultat final.

Martin Ender
la source
J'aurais juré avoir lu quelque chose dans les documents sur la division entière ...
Conor O'Brien
7

R, 40 35 octets

Eh bien, il est temps de sauter au plus profond! Voici mon code R , inspiré de la réponse @xnor:

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

EDIT : Dans cette version, R demandera deux fois les entrées.

(n=scan())*(m=scan())*(n+1)*(m+1)/4
Frédéric
la source
cat(prod(choose(scan()+1,2)))est de 29 octets.
Giuseppe
6

CJam, 12 10 octets

2 octets économisés grâce à Martin.

{_:)+:*4/}

Essayez-le en ligne!

Il s'agit d'un bloc qui prend une liste de 2 éléments de la pile et laisse la solution sur la pile. Utilisable programme complet pour les tests: riari+{_:)+:*4/}~.

Basé sur la solution python exceptionnelle de xnor.

Explication:

{_:)+:*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
Zwei
la source
2
Je pense que cela fonctionne pour 10 si vous faites entrer une liste de deux éléments? {_:~+:*4/}
Martin Ender
En fait, il n'est pas nécessaire de l'utiliser ~du tout dans CJam. Utilisez simplement ).
Martin Ender
5

Matlab, 23 19 octets

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

Mise en œuvre de la formule m*n*(m+1)*(n+1)/4
Utilisation:ans([m,n])

pajonk
la source
4

MATL , 6 octets

tQ*2/p

L'entrée est un tableau du formulaire [m,n] .

Essayez-le en ligne!

Explication

Calcul direct basé sur la formule 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
Luis Mendo
la source
4

Java 7, 39 38 octets

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

Java 8, 26 25 19 18 17 octets

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

Basé sur l'excellente réponse de @xnor . Plusieurs octets enregistrés grâce à @DavidConrad .Essayez-le ici.

Code de test (Java 7):

Essayez-le ici.

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));
  }
}

Sortie:

0
1
36
100
588
Kevin Cruijssen
la source
1
Vous n'avez pas besoin de cela returnet a->b->est un octet plus court que (a,b)->.
David Conrad
2
Je ne pense pas non plus que vous ayez besoin du point-virgule, car si vous passiez le lambda dans une méthode qui a pris Function<Integer, Function<Integer, Integer>>un paramètre, il ne serait pas suivi d'un point-virgule.
David Conrad
2
Je suis d'accord avec @DavidConrad: Je ne compte pas la fin ;sur une seule déclaration J8 lambdas.
CAD97
@DavidConrad Désolé pour l'édition très tardive, mais j'ai seulement remarqué que j'ai lu au-delà de votre commentaire pour supprimer le return .. De plus, je ne programme presque jamais en Java 8 (d'où toutes mes réponses Java 7), mais comment puis-je a->b->travailler? Voici l'idéone du cas actuel.
Kevin Cruijssen
1
Désolé pour la réponse très tardive! Vous devez curry la fonction, vous devez donc changer MathOperation.operationpour n'en prendre qu'un int, retourner un Function<Integer, Integer>, et lorsque vous l'appelez, vous ne passez initialement que le premier paramètre, apuis appelez .apply(b)le Function. Vous devez également importer java.util.function.Function. Voici une idée avec les changements.
David Conrad
3

Rubis, 22 octets

Voler le truc de @ xnor et faire un stabby-lambda:

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

Exemple d'appel:

r[6,7]     # => 588

Ou en tant que proc, également 22 octets:

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

Que nous pourrions alors appeler:

proc{|m,n|m*n*~m*~n/4}.call(6,7)     # => 588
David Ljung Madison Stellar
la source
Vous n'avez pas besoin de le nommer - les fonctions anonymes sont acceptables selon la convention du site
Conor O'Brien
3

Labyrinthe , 13 11 octets

*?;*_4/!
):

Essayez-le en ligne!

Explication

Cela calcule également le produit des nombres triangulaires comme la plupart des réponses. Le bloc 2x2 de tête est une petite boucle:

*?
):

Sur la première itération *ne fait rien, de sorte que l'ordre de boucle réel est le suivant:

?   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).

Le code restant est juste linéaire:

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

Labyrinth essaie ensuite de s'exécuter à /nouveau, ce qui met fin au programme en raison d'une division par zéro.

Martin Ender
la source
2

Pyke, 6 octets

mh+Bee

Essayez-le ici!

mh     -    map(increment, input)
  +    -   ^ + input
   B   -  product(^)
    ee - ^ \ 4
Bleu
la source
Cela pourrait utiliser une ventilation, mais je trouve que c'est une œuvre d'art, personnellement.
corsiKa
2

05AB1E, 4 octets

€LOP

Explication

Utilise la formule décrite au 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

Prend l'entrée comme [n, m] .

Essayez-le en ligne

Emigna
la source
1

Pyth, 8 6 octets

Deux octets enregistrés grâce à @DenkerAffe.

*FmsSd

L'entrée est attendue comme une liste comme [m,n]. Essayez-le ici .

Explication:

          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).
Rhyzomatic
la source
1
Vous pouvez utiliser au Flieu de .*et enlever le Qcar il est ajouté implictly.
Denker
Je le savais Fmais je ne savais pas comment l'utiliser et j'ai pensé que je devais l'utiliser à la .*place ... Merci!
Rhyzomatic
1

C #, 19 octets

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

Une fonction anonyme basée sur la réponse de @ xnor.

TheLethalCoder
la source
1

Lua, 74 63 octets

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

La fonction prend l'entrée comme paramètres numériques.

En raison de la façon dont Lua est implémentée, il s'agit techniquement d'une fonction, avec des arguments variables, qui peut être appelée en l'enveloppant dans une instruction "function", ou en la chargeant à partir du code source en utilisant "loadstring"

brianush1
la source
1
Je vois que vous avez pas mal de code juste pour les E / S. Peut-être qu'il serait plus court de créer simplement une fonction qui prend les deux nombres et renvoie la réponse, et de supprimer tout ce code d'E / S inutile?
Zwei
@Zwei J'ai oublié que les fonctions sont autorisées à prendre des entrées par paramètres. Merci d'avoir fait remarquer cela.
brianush1
La fonction pourrait être nommée quelque chose comme "f" au lieu du nom entier "fonction" pour économiser 7 octets de plus
Zwei
Dans Lua, le mot-clé "fonction" est requis pour déclarer une fonction. Si aucun nom n'est spécifié (ex: "fonction f ()"), il s'agit d'une fonction anonyme. (ex: "fonction ()"). Par conséquent, la "fonction" est requise pour que le code fonctionne.
brianush1
Oh, j'ai oublié que lua fonctionne comme ça. Ma faute!
Zwei
1

Cheddar , 23 octets

m->n->m*(m+1)*n*(n+1)/4
Leaky Nun
la source
n*(n+1)peut être joué au n^2+n
golf
@Downgoat Qu'en est-il des parenthèses?
Leaky Nun
oh> _> ouais. désolé, nvm, ne pensais pas
Downgoat
essayez de curryer la fonction. m->n->...
Conor O'Brien
1

Brain-Flak , 84 80 octets

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

Essayez-le en ligne!

Probablement très sous-optimal, en particulier à cause de la réutilisation du code concernant les nombres triangulaires, mais au moins nous avons une solution Brain-Flak qui fonctionne.

Malheureusement, il semble échouer en bouclant à l'infini avec le 0 0boîtier de test, mais tous les autres fonctionnent bien.

Zwei
la source
0

Convexe, 7 octets

Je sais que cela peut être plus petit, je ne sais pas encore comment ...

_:)+×½½

Essayez-le en ligne! . Utilise l'encodage CP-1252.

GamrCorps
la source