Quanti rettangoli nella griglia?


29

Bene, sebbene questa sfida si sia rivelata un enorme successo, si è rivelata anche molto banale da risolvere. Pertanto, per coloro che sono alla ricerca di più di una sfida, ho creato un seguito a questa sfida in cui ora è necessario contare il numero di rettangoli unici . Controlla!

Ora, per quelli di voi che vogliono risolvere questa sfida, ecco che arriva.


Bene, non abbiamo ancora una sfida come questa, quindi eccoci qui.

Considera questa 3 x 3griglia di rettangoli:

Example

Quanti rettangoli ci sono? Bene, contando visivamente, possiamo vedere che in realtà ci sono 36rettangoli, incluso l'intero piano stesso, che sono tutti mostrati nella GIF animata di seguito:

Rectangles in Example

L'obiettivo

Il conteggio dei rettangoli come mostrato sopra è il compito. In altre parole, dati 2 numeri interi maggiori o uguali a 0, me n, dove mrappresenta la larghezza e nrappresenta l'altezza, genera il numero totale di rettangoli in quella m x ngriglia di rettangoli.

Regole

  • L'uso di qualsiasi built-in che risolve direttamente questo problema è esplicitamente vietato.

  • Questa sfida non riguarda la ricerca della risposta più breve, ma la ricerca della risposta più breve in ogni lingua. Pertanto, nessuna risposta sarà accettata.

  • Sono vietate le scappatoie standard.

Casi test

Presentato nel formato Array of Integers Input -> Integer Output:

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

Riferimenti

Ricorda, questo è , quindi vince il codice più corto!


Ho calcolato 588per l'ultimo test-case.
Leaky Nun,

@LeakyNun Ebbene, credo che mi mancava un po ', mentre il conteggio di loro. È sistemato.
R. Kap

Qual è il valore massimo dell'input?
Erik the Outgolfer

Risposte:


34

Python, 22 byte

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

La formula m*n*(m+1)*(n+1)/4viene abbreviata usando il complemento di bit ~m=-(m+1), esprimendo (m+1)*(n+1)come ~m*~n.

Perché il numero di rettangoli m*n*(m+1)*(n+1)/4? Ogni rettangolo è specificato dalla scelta di due linee orizzontali (superiore e inferiore) e due linee verticali (sinistra e destra). Ci sono m+1linee orizzontali, di cui scegliamo un sottoinsieme di due distinti. Quindi il numero di scelte è choose(m+1,2), che è m*(m+1)/2. Moltiplicando per le n*(n+1)/2scelte per le linee verticali si ottiene il risultato.


Quel trucco +1 è geniale.
David Ljung Madison Stellar il

11

Gelatina , 4 byte

RS€P

Provalo online!

In alternativa, anche 4 byte

pP€S

Provalo online!


Buon lavoro. Pollice su. :)
R. Kap

24
Ti interessa spiegare?
Pureferret,

Ci sono anche בHPe ‘c2Pe forse altre alternative a 4 byte.
miglia

1
@Pureferret Questo utilizza la formula di OEIS sul fatto che questo è il prodotto del numero triangolare nthe mth. Rconverte ogni numero nell'indice 1 basata: [1, 2, ..., n]. Sè la somma e mezzi 'ogni' così ogni lista si riassume, dando una lista come: [nth triangle number, mth triangle number]. Quindi Pprende il prodotto di quell'elenco, che fornisce il risultato desiderato.
FryAmTheEggman,

1
@FryAmTheEggman quindi quello che dici è ... Magia
Pureferret


9

Mathematica, 15 byte

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

Questa è una funzione senza nome che accetta due argomenti interi e restituisce il numero di rettangoli.

Spiegazione

L'implementazione è sostanzialmente una forma molto golfosa del prodotto dei due numeri triangolari. Potrebbe valere la pena leggere la sezione "Sequenze di argomenti" in questo post per i dettagli, ma cercherò di riassumere qui l'essenza.

##si espande in una sequenza di tutti gli argomenti. Questo è simile allo splatting in altre lingue. Ad esempio, se gli argomenti sono 3e 4, allora {1, 2, ##, 5}ti daranno {1, 2, 3, 4, 5}. Ma questo non funziona solo negli elenchi, ma in qualsiasi espressione, ad esf[1, 2, ##, 5] sarebbe anche f[1, 2, 3, 4, 5].

Questo diventa interessante quando si combina ##con gli operatori. Tutti gli operatori di Mathematica sono solo a corto di f[...]espressioni simili (forse nidificate). Ad esempio a+bè Plus[a, b]e in a-brealtà rappresenta Plus[a, Times[-1, b]]. Ora quando si combina ##con gli operatori, Mathematica fa prima di tutto espandere gli operatori, trattandoli ##come un singolo operando, ed espanderli solo alla fine. Inserendo ##nei punti giusti, possiamo quindi utilizzarlo sia per moltiplicare che per aggiungere gli operandi.

Facciamo questo per il codice sopra:

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

Espandendolo nella sua forma completa, otteniamo questo:

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

Inseriamo gli argomenti della funzione ae b:

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

E ora lo riconvertiamo in notazione matematica standard:

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

Un piccolo riarrangiamento mostra che questo è il prodotto dei numeri triangolari:

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

Fatto divertente: questa implementazione è così Golfy, è la stessa lunghezza incorporato per calcolare un singolo numero triangolare, PolygonalNumber.


8

C, 25 byte

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

Versione purista (27):

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

Versione ISO-er (35):

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

Quale versione pensi sia la migliore?
Erik the Outgolfer

8

Medusa , 16 byte

p|%/**+1
  4  Ei

Il formato di input è [x y], l'output è solo il risultato.

Provalo online!

Soluzione alternativa, stesso conteggio byte:

pm%/*[*i
  4  +1

Spiegazione

È tempo di dare a Jellyfish l'introduzione che merita! :)

Jellyfish è il linguaggio di Zgarb basato sulla sua sfida di sintassi 2D . La semantica è in gran parte ispirata a J, ma la sintassi è un'opera d'arte. Tutte le funzioni sono caratteri singoli e disposte su una griglia. Le funzioni prendono i loro argomenti dal token successivo a sud e ad est di essi e restituiscono il risultato a nord e ovest. Ciò consente di creare un'interessante rete di chiamate di funzioni in cui riutilizzare i valori passandoli in diverse funzioni da più direzioni.

Se ignoriamo il fatto che alcuni dei token nel programma sopra sono operatori speciali (funzioni di livello superiore), il programma sopra verrebbe scritto in questo modo in un linguaggio sano:

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

Esaminiamo il codice dal basso verso l'alto. L'input viene inserito da the i, che quindi valuta [x y].

In +cima a questo riceve questo input insieme al valore letterale 1e quindi incrementa entrambi gli elementi per dare [(x+1) (y+1)](la maggior parte delle operazioni sono automaticamente passate su elenchi).

L'altro valore di iviene inviato a sinistra, ma le Edivisioni sono argomento orientale nord e ovest. Ciò significa che gli input a destra *sono effettivamente [x y]e [(x+1) (y+1)]quindi questo calcola [x*(x+1) y*(y+1)].

Il successivo *viene effettivamente modificato dal precedente /che lo trasforma in un'operazione di piegatura. Piegare *su una coppia semplicemente la moltiplica, in modo da ottenere x*(x+1)*y*(y+1).

Ora %è solo divisione quindi calcola x*(x+1)*y*(y+1)/4. Sfortunatamente, questo si traduce in un galleggiante, quindi dobbiamo arrotondarlo con l'unario |. Infine, questo valore viene alimentato al pquale stampa il risultato finale.


Avrei potuto giurare di aver letto qualcosa nei documenti sulla divisione di interi ...
Conor O'Brien,

7

R, 40 35 byte

Bene, è tempo di saltare fino in fondo! Ecco il mio codice R , ispirato alla risposta @xnor:

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

EDIT : In questa versione, R chiederà due volte per input.

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

cat(prod(choose(scan()+1,2)))è di 29 byte.
Giuseppe,

6

CJam, 12 10 byte

2 byte salvati grazie a Martin.

{_:)+:*4/}

Provalo online!

Questo è un blocco che prende un elenco di 2 elementi dallo stack e lascia la soluzione nello stack. Programma completo utilizzabile per il test: riari+{_:)+:*4/}~.

Basato sull'eccezionale soluzione Python di xnor.

Spiegazione:

{_:)+:*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
Penso che questo funzioni per 10 se si inserisce un elenco di due elementi? {_:~+:*4/}
Martin Ender,

In realtà, non è necessario utilizzare ~affatto in CJam. Basta usare ).
Martin Ender,

5

Matlab, 23 19 byte

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

Implementazione della formula m*n*(m+1)*(n+1)/4
Utilizzo:ans([m,n])


4

MATL , 6 byte

tQ*2/p

L'input è un array del modulo [m,n] .

Provalo online!

Spiegazione

Calcolo diretto basato sulla formula 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 byte

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

Java 8, 26 25 19 18 17 byte

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

Basato sull'eccellente risposta di @xnor . Più byte salvati grazie a @DavidConrad . Provalo qui.

Codice test (Java 7):

Provalo qui.

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

Produzione:

0
1
36
100
588

1
Non è necessario returned a->b->è un byte più corto di (a,b)->.
David Conrad,

2
Non penso nemmeno che tu abbia bisogno del punto e virgola, poiché se passassi il lambda in un metodo che Function<Integer, Function<Integer, Integer>>utilizzava un parametro come, non sarebbe seguito da un punto e virgola.
David Conrad,

2
Sono d'accordo con @DavidConrad: non conto il finale ;su una singola istruzione J8 lambdas.
CAD97

@DavidConrad Ci scusiamo per la modifica molto tardiva, ma solo ora ho notato che ho letto oltre il tuo commento per rimuovere il return .. Inoltre, non ho quasi mai programmato in Java 8 (quindi tutte le mie risposte Java 7), ma come faccio a->b->a lavorare? Ecco l'ideone per il caso attuale.
Kevin Cruijssen,

1
Ci scusiamo per la risposta molto tardi! Devi curry la funzione, quindi devi cambiare MathOperation.operationper prenderne solo una int, restituire a Function<Integer, Integer>, e quando la chiami, inizialmente passi solo il primo parametro a, e quindi chiama .apply(b)il Function. È inoltre necessario importare java.util.function.Function. Ecco un ideone con i cambiamenti.
David Conrad,

3

Rubino, 22 byte

Rubare il trucco di @ xnor e fare uno stabby-lambda:

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

Esempio di chiamata:

r[6,7]     # => 588

O come un proc, anche 22 byte:

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

Che potremmo quindi chiamare:

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

Non è necessario nominarlo: le funzioni anonime vanno bene secondo la convenzione del sito
Conor O'Brien,

3

Labyrinth , 13 11 byte

*?;*_4/!
):

Provalo online!

Spiegazione

Questo calcola anche il prodotto dei numeri triangolari come la maggior parte delle risposte. Il blocco 2x2 principale è un piccolo loop:

*?
):

Nella prima iterazione *non fa nulla, quindi l'ordine del loop reale è questo:

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

Il codice rimanente è solo lineare:

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

Labyrinth tenta quindi di eseguire /nuovamente, il che termina il programma a causa di una divisione per zero.


2

Pyke, 6 byte

mh+Bee

Provalo qui!

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

Ciò potrebbe comportare un guasto, ma trovo che sia un'opera d'arte, personalmente.
corsiKa

2

05AB1E, 4 byte

€LOP

Spiegazione

Utilizza la formula descritta in 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

Accetta input come [n, m] .

Provalo online


1

Pyth, 8 6 byte

Due byte salvati grazie a @DenkerAffe.

*FmsSd

L'input è previsto come un elenco come [m,n]. Provalo qui .

Spiegazione:

          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
È possibile utilizzare Fanziché .*e rimuovere il Qpoiché viene aggiunto in modo implicito.
Denker

Sapevo Fma non riuscivo a capire come usarlo e ho pensato che avrei dovuto usare .*invece ... Grazie!
Rhyzomatic

1

C #, 19 byte

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

Una funzione anonima basata sulla risposta di @ xnor.


1

Lua, 74 63 byte

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

La funzione accetta input come parametri numerici.

A causa del modo in cui Lua è implementata, questa è tecnicamente una funzione, con variabili arg, che può essere chiamata avvolgendola in un'istruzione "function" o caricandola dal codice sorgente usando "loadstring"


1
Vedo che hai un sacco di codice lì solo per l'I / O. Forse sarebbe più breve semplicemente fare una funzione che prende i due numeri e restituisce la risposta, e rimuovere tutto questo codice I / O non necessario?
Zwei

@Zwei Ho dimenticato che le funzioni possono accettare input per parametri. Grazie per la segnalazione.
brianush1,

La funzione potrebbe essere denominata come "f" anziché l'intero nome "funzione" per salvare altri 7 byte
Zwei

In Lua, la parola chiave "funzione" è richiesta per dichiarare una funzione. Se non viene specificato alcun nome (es: "funzione f ()"), è una funzione anonima. (es: "funzione ()"). Pertanto, la "funzione" è necessaria affinché il codice funzioni.
brianush1,

Oh, ho dimenticato che Lua funziona così. Colpa mia!
Zwei


1

Brain-Flak , 84 80 byte

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

Provalo online!

Probabilmente molto non ottimale, soprattutto a causa del riutilizzo del codice relativo ai numeri dei triangoli, ma almeno abbiamo una soluzione Brain-Flak che funziona.

Purtroppo sembra fallire 0 0eseguendo il loop infinito con la testcase ma tutti gli altri funzionano bene.


0

Convesso, 7 byte

So che questo può essere più piccolo, non riesco proprio a capire come ancora ...

_:)+×½½

Provalo online! . Utilizza la codifica CP-1252.



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.