Quantos retângulos na grade?


29

Bem, embora esse desafio tenha sido um enorme sucesso, ele também foi muito trivial de resolver. Portanto, para quem procura mais desafios, criei uma sequência para esse desafio, na qual você deve contar agora o número de retângulos únicos . Confira!

Agora, para aqueles que procuram resolver este desafio, aqui está.


Bem, ainda não temos um desafio como esse, então aqui vamos nós.

Considere esta 3 x 3grade de retângulos:

Exemplo

Quantos retângulos existem? Bem, contando visualmente, podemos ver que na verdade existem 36retângulos, incluindo todo o próprio plano, que são mostrados no GIF animado abaixo:

Retângulos no exemplo

A tarefa

A contagem de retângulos, como mostrado acima, é a tarefa. Em outras palavras, dado 2 inteiros maiores do que ou igual a 0, me n, onde mrepresenta a largura e nrepresenta a altura, a saída do número total de rectângulos em que m x ngrade de rectângulos.

Regras

  • O uso de quaisquer recursos internos que resolvem diretamente esse problema é explicitamente proibido.

  • Esse desafio não é encontrar a resposta mais curta, mas encontrar a resposta mais curta em todos os idiomas. Portanto, nenhuma resposta será aceita.

  • As brechas padrão são proibidas.

Casos de teste

Apresentado no formato Array of Integers Input -> Integer Output:

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

Referências

Lembre-se, este é o , portanto o código mais curto vence!


Eu calculei 588para o último caso de teste.
Freira

@LeakyNun Bem, acho que perdi alguns contando- os. Está consertado.
R. Kap

Qual é o valor máximo da entrada?
Erik the Outgolfer

Respostas:


34

Python, 22 bytes

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

A fórmula m*n*(m+1)*(n+1)/4é reduzida usando o complemento de bit ~m=-(m+1), expressando (m+1)*(n+1)como ~m*~n.

Por que o número de retângulos m*n*(m+1)*(n+1)/4? Cada retângulo é especificado pela escolha de duas linhas horizontais (superior e inferior) e duas linhas verticais (esquerda e direita). Existem m+1linhas horizontais, das quais escolhemos um subconjunto de duas linhas distintas. Portanto, o número de opções é choose(m+1,2), qual é m*(m+1)/2. Multiplicar pelas n*(n+1)/2opções de linhas verticais fornece o resultado.


Esse truque +1 é brilhante.
David Ljung Madison Stellar

11

Gelatina , 4 bytes

RS€P

Experimente online!

Como alternativa, também 4 bytes

pP€S

Experimente online!


Bom trabalho. Afirmativo. :)
R. Kap

24
Gostaria de explicar?
Pureferret 01/08/16

Há também בHPe / ‘c2Pe talvez outras alternativas de 4 bytes.
milhas

11
@Pureferret Utiliza a fórmula da OEIS, sendo este o produto do número triangular nthe mth. Rconverte cada número no índice 1 com base: [1, 2, ..., n]. Sé a soma e meio 'each' para que cada lista é somados, dando uma lista como: [nth triangle number, mth triangle number]. Em seguida, Ppega o produto dessa lista, que fornece o resultado desejado.
FryAmTheEggman

11
@FryAmTheEggman então o que seu dizer é .... Magia
Pureferret


9

Mathematica, 15 bytes

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

Esta é uma função sem nome, recebendo dois argumentos inteiros e retornando o número de retângulos.

Explicação

A implementação é basicamente uma forma muito eficiente do produto dos dois números triangulares. Pode valer a pena ler a seção "Sequências de argumentos" neste post para obter detalhes, mas tentarei resumir a essência aqui.

##expande para uma sequência de todos os argumentos. Isso é semelhante a splatting em outros idiomas. Por exemplo, se os argumentos forem 3e 4, então {1, 2, ##, 5}você fornecerá {1, 2, 3, 4, 5}. Mas isso não funciona apenas em listas, mas em qualquer expressão, por exemplo f[1, 2, ##, 5], também seria f[1, 2, 3, 4, 5].

Isso fica interessante quando você combina ##com os operadores. Todos os operadores no Mathematica são apenas mãos curtas para alguma f[...]expressão semelhante (possivelmente aninhada). Por exemplo, a+bé Plus[a, b]e a-brealmente representa Plus[a, Times[-1, b]]. Agora, quando você combina ##com operadores, o que o Mathematica faz é expandir os operadores primeiro, tratando ##como um único operando e expandi-los apenas no final. Ao inserir ##nos lugares certos, podemos, portanto, usá-lo para multiplicar e adicionar os operandos.

Vamos fazer isso para o código acima:

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

Expandindo-o para sua forma completa, obtemos o seguinte:

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

Vamos inserir os argumentos da função ae b:

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

E agora nós o convertemos novamente em notação matemática padrão:

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

Um pouco de reorganização mostra que este é o produto dos números triangulares:

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

Curiosidade: essa implementação é tão divertida que tem o mesmo comprimento que a embutida para calcular um único número triangular PolygonalNumber.


8

C, 25 bytes

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

Versão purista (27):

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

Versão ISO-er (35):

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

Qual versão você acha que é melhor?
Erik the Outgolfer

8

Água-viva , 16 bytes

p|%/**+1
  4  Ei

O formato de entrada é [x y], a saída é apenas o resultado.

Experimente online!

Solução alternativa, mesma contagem de bytes:

pm%/*[*i
  4  +1

Explicação

Hora de dar a Jellyfish a introdução que merece! :)

Água-viva é a linguagem de Zgarb , baseada em seu desafio de sintaxe 2D . A semântica é amplamente inspirada em J, mas a sintaxe é uma obra de arte. Todas as funções são caracteres únicos e dispostas em uma grade. As funções recebem seus argumentos do próximo token ao sul e leste deles e retornam o resultado ao norte e oeste. Isso permite que você crie uma rede interessante de chamadas de função nas quais você reutiliza valores passando-os para várias funções de várias direções.

Se ignorarmos o fato de que alguns dos tokens no programa acima são operadores especiais (funções de nível superior), o programa acima seria escrito assim em uma linguagem sã:

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

Vamos analisar o código de baixo para cima. A entrada é alimentada pelo i, que, portanto, avalia como [x y].

A +parte superior recebe essa entrada juntamente com o literal 1e, portanto, incrementa os dois elementos a serem fornecidos [(x+1) (y+1)](a maioria das operações é encadeada automaticamente por listas).

O outro valor de ié enviado para a esquerda, mas as Edivisões são o argumento leste, norte e oeste. Isso significa que as entradas à direita *são realmente [x y]e, [(x+1) (y+1)]portanto, isso é calculado [x*(x+1) y*(y+1)].

O próximo *passo é realmente modificado pelo anterior, /que o transforma em uma operação fold. Dobrar *um par simplesmente o multiplica, de modo que conseguimos x*(x+1)*y*(y+1).

Agora % é apenas uma divisão, então calcula x*(x+1)*y*(y+1)/4. Infelizmente, isso resulta em uma flutuação, por isso precisamos arredondá-la com o unário |. Finalmente, esse valor é alimentado para o pqual imprime o resultado final.


Eu podia jurar que li algo nos documentos sobre a divisão inteira ...
Conor O'Brien

7

R, 40 35 bytes

Bem, é hora de pular no fundo do poço! Aqui está o meu código R , inspirado na resposta @xnor:

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

EDIT : Nesta versão, R pedirá duas vezes entradas.

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

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

6

CJam, 12 10 bytes

2 bytes salvos graças a Martin.

{_:)+:*4/}

Experimente online!

Este é um bloco que pega uma lista de 2 elementos da pilha e deixa a solução na pilha. Programa completo utilizável para testes: riari+{_:)+:*4/}~.

Baseado na excelente solução python do xnor.

Explicação:

{_:)+:*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
Eu acho que isso funciona para 10 se você fizer entrada uma lista de dois elementos? {_:~+:*4/}
Martin Ender

Na verdade, não há necessidade de usar o ~CJam. Apenas use ).
Martin Ender

5

Matlab, 23 19 bytes

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

Implementação da fórmula m*n*(m+1)*(n+1)/4
Uso:ans([m,n])


4

MATL , 6 bytes

tQ*2/p

Entrada é uma matriz do formulário [m,n].

Experimente online!

Explicação

Cálculo direto baseado na 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

Com base na excelente resposta de @xnor . Vários bytes salvos graças a @DavidConrad . Experimente aqui.

Código de teste (Java 7):

Experimente aqui.

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

Saída:

0
1
36
100
588

11
Você não precisa disso returne a->b->é um byte menor que (a,b)->.
David Conrad

2
Também não acho que você precise do ponto e vírgula, pois se você estivesse passando o lambda para um método que tomou Function<Integer, Function<Integer, Integer>>como parâmetro, ele não seria seguido por um ponto e vírgula.
David Conrad

2
Concordo com @DavidConrad: não conto o final ;na única declaração J8 lambdas.
CAD97

@DavidConrad Desculpe pela edição tardia, mas só agora notei que li o seu comentário para remover o return .. Além disso, quase nunca programa em Java 8 (daí todas as minhas respostas em Java 7), mas como faço a->b->para trabalhar? Aqui está o ideone para o caso atual.
Kevin Cruijssen

11
Desculpe pela resposta muito tardia! Você precisa de caril a função, então você precisa mudar MathOperation.operationa tomar apenas um int, retornar um Function<Integer, Integer>, e quando você chamá-lo, você inicialmente passar apenas o primeiro parâmetro, ae, em seguida, chamar .apply(b)no Function. Você também precisa importar java.util.function.Function. Aqui está um ideone com as mudanças.
David Conrad

3

Ruby, 22 bytes

Roubando o truque do @ xnor e fazendo um stabby-lambda:

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

Chamada de exemplo:

r[6,7]     # => 588

Ou como proc, também 22 bytes:

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

O que poderíamos chamar:

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

Você não precisa de nomeá-lo-anônimos funções estão bem como por convenção local
Conor O'Brien

3

Labirinto , 13 11 bytes

*?;*_4/!
):

Experimente online!

Explicação

Isso também calcula o produto dos números triangulares como a maioria das respostas. O bloco 2x2 principal é um pequeno loop:

*?
):

Na primeira iteração *não faz nada, de modo que a ordem real do loop é esta:

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

O código restante é apenas linear:

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

O labirinto tenta executar /novamente, o que finaliza o programa devido a uma divisão por zero.


2

Pyke, 6 bytes

mh+Bee

Experimente aqui!

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

Isso poderia ser um colapso, mas acho que é uma obra de arte, pessoalmente.
CorsiKa

2

05AB1E, 4 bytes

€LOP

Explicação

Usa a fórmula descrita em 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

Recebe a entrada como [n, m] .

Experimente online


1

Pitão, 8 6 bytes

Dois bytes salvos graças ao @DenkerAffe.

*FmsSd

A entrada é esperada como uma lista como [m,n]. Experimente aqui .

Explicação:

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

11
Você pode usar em Fvez de .*e remover o, Qpois ele é adicionado implicitamente.
Denker1

Eu sabia, Fmas não conseguia descobrir como usá-lo e achei que precisava usá-lo .*... Obrigado!
Rhyzomatic

1

C #, 19 bytes

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

Uma função anônima baseada na resposta do @ 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)

A função recebe a entrada como parâmetros numéricos.

Devido à maneira como Lua é implementada, essa é tecnicamente uma função, com variável args, que pode ser chamada envolvendo-a em uma instrução "function" ou carregando-a do código-fonte usando "loadstring"


11
Vejo que você tem bastante código lá apenas para E / S. Talvez fosse mais curto simplesmente criar uma função que pegue os dois números e retorne a resposta e remova todo esse código de E / S desnecessário?
Zwei

@Zwei Eu esqueci que as funções podem receber dados pelos parâmetros. Obrigado por apontar isso.
Brianush1

A função pode ser nomeado algo como "f" em vez de toda a "função" nome para salvar mais 7 bytes
Zwei

Em Lua, a palavra-chave "função" é necessária para declarar uma função. Se nenhum nome for especificado (ex: "função f ()"), é uma função anônima. (ex: "função ()"). Portanto, a "função" é necessária para o código funcionar.
Brianush1

Ah, esqueci que a lua funciona assim. Minha culpa!
Zwei


1

Brain-Flak , 84 80 bytes

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

Experimente online!

Provavelmente muito abaixo do ideal, principalmente por causa da reutilização do código em relação aos números dos triângulos, mas pelo menos temos uma solução Brain-Flak que funciona.

Infelizmente, parece falhar fazendo um loop infinito com o 0 0testcase, mas todos os outros funcionam bem.


0

Convexo, 7 bytes

Eu sei que isso pode ser menor, só não consigo descobrir até agora ...

_:)+×½½

Experimente online!. Usa a codificação CP-1252.



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.