Contare i rettangoli in una griglia diagonale


21

Come seguito a questa sfida , ora vogliamo contare il numero di rettangoli nella griglia con r righe e colonne c dove c'è una linea che attraversa ogni diagonale di un quadrato nella griglia. Ora contiamo ancora gli stessi rettangoli di prima, ma questa volta dobbiamo includere anche i rettangoli inclinati di 45 gradi.

Il tuo obiettivo è creare una funzione o un programma che, dato il numero di righe r e di colonne c, generi il numero di rettangoli in una griglia diagonale con dimensioni ( r , c ).

Come dimostrazione, questa è un'animazione che scorre attraverso tutti i 37 rettangoli formati da una griglia diagonale (2 x 3).

Esempio

Casi test

Each case is [rows, columns] = # of rectangles
[0, 0] = 0
[0, 1] = 0
[1, 0] = 0
[1, 1] = 1
[3, 2] = 37
[2, 3] = 37
[6, 8] = 2183
[7, 11] = 5257
[18, 12] = 40932
[42, 42] = 2889558
[51, 72] = 11708274

Regole

  • Questo è quindi vince il codice più corto.
  • I builtin che risolvono questo non sono ammessi.

7
Solo Mathematica potrebbe essere integrata per questo XD
Conor O'Brien il

3
Accidenti, questo è molto più difficile degli altri rettangoli .....
GamrCorps

5

1
Penso che i built-in dovrebbero essere ammessi. Mi piace vedere quelle risposte.
mbomb007,

Risposte:


8

Rubino, 58 byte

Questa è un'implementazione diretta dell'algoritmo nella risposta C di Rilascio di Helium Nuclei .

g=->m,n{n>m ?g[n,m]:m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6}

Ho studiato perché questa formula funziona, con un successo limitato. È facile confermare che il numero di rettangoli verticali è uguale a (m+1)*m/2 * (n+1)*n/2, il numero di rettangoli diagonali è un po 'più sfuggente.

Neil ha confermato per m==nil numero di rettangoli inclinati in un n*nquadrato è (4*n**4-n*n-3*n)/6e che quando m>n è necessario aggiungere un ulteriore (m-n)(n*(4*n*n-1)/3)(in relazione alla OEIS A000447 ), anche se questo non spiega dove queste due formule provenienza. Ho trovato parte della risposta.

Perché m==n, la forma all'interno della griglia è un diamante azteco .

Immagine del diamante azteco da Wolfram Alpha

Il numero di rettangoli in un diamante Aztec è la somma del numero di grandi rettangoli sovrapposti per renderlo (per il quarto diamante, che si trova in una 5x5griglia, 2x8, 4x6, 6x4, e 8x2) meno il numero dei rettangoli contato due volte (il numero di rettangoli nel diamante azteco precedente ).

La formula qui è (TeX da aggiungere in seguito):

# superimposed rectangles, 2x(2n-2), 4*(2n-4), ...
f = lambda n: sum( (2*k)*(2*k+1)/2 * (2*n-2*k)*(2*n-2*k+1)/2 for k in range(1, n) )
aztec_rect = f(n) - f(n-1)

Secondo Wolfram Alpha, la forma chiusa per fIS 1/30*(n-1)*n*(4*n**3+14*n**2+19*n+9)e la forma chiusa per aztec_rectdire, come ha scoperto Neil, 1/6*n*(n-1)*(4*n**2+4*n+3) == 1/6*(4*n**4-n**2-3*n).

Devo ancora scoprire perché (m-n)(n*(4*n*n-1)/3)funziona, anche se sospetto che sia perché una definizione di A000447 è binomial(2*n+1, 3). Vi terremo aggiornati.

Aggiornamento: ho motivo di credere che la funzione del numero di rettangoli in un diamante azteco esteso m>nsia correlata al numero di 2k*2(n-k)rettangoli sovrapposti nel meno diamante F(m-1,n-1). Altri risultati quando li ho.

Aggiornamento: ho provato un percorso diverso e ho finito con un'altra formula per diamanti aztechi estesi che è principalmente spiegabile ma ha un termine che non ho ancora capito. Huzzah! : D

def f(m,n):
 if n > m:
     return f(n,m)
 if n == 0:
     return 0
 else:
     return(m-n+1)*(4*n**4-n*n-3*n)/6-f(m-1,n-1)+(m-n)*2+(m-n)*(n-2)-(m-n-1)*f(n-1,n-1)

Una rapida analisi di quest'ultima formula:

  • (m-n+1)*(4*n**4-n*n-3*n)/6è il numero di diamanti aztechi sovrapposti di dimensioni nnella struttura, come f(n,n) = (4*n**4-n*n-3*n)/6. f(7,3)ha 5 diamanti aztechi sovrapposti 3, mentre f(3,3)ha solo 1 diamante.
  • -f(m-1,n-1) rimuove alcuni dei rettangoli duplicati dal centro dei diamanti sovrapposti.
  • +(m-n)*2rappresenta il 2 extra 2-by- (2n-1)rettangoli per ogni diamante in più.
  • +(m-n)*(n-2)rappresenta un nquadrante in più nper ogni diamante in più.
  • -(m-n-1)*f(n-1,n-1)Questo è il nuovo termine enigmatico. Apparentemente non ho tenuto conto di alcuni quadrati extra nel mio conteggio, ma non ho capito dove si trovano nel diamante esteso.

Nota: quando m==n, m-n-1 = -1significa che quest'ultimo termine aggiunge quadrati al conteggio. Potrei mancare qualcosa nella mia formula normale. Divulgazione completa, questo doveva solo essere una patch per una bozza precedente di questa formula che ha funzionato. Chiaramente, ho ancora bisogno di scavare in quello che sta succedendo e potrebbe essere che la mia formula abbia alcuni bug. Vi terrò aggiornati.

Russell, Gary e Weisstein, Eric W. "Aztec Diamond". Da MathWorld - Una risorsa Web Wolfram. http://mathworld.wolfram.com/AztecDiamond.html


Mi piace come questa risposta abbia più voti rispetto alla risposta originale, e una taglia +100 ...: P
HyperNeutrino

5

C, 71 64 byte

f(m,n){return n>m?f(n,m):m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6;}

Provalo su Ideone


2
Mi piacerebbe sapere cosa sta succedendo qui e come sei arrivato a questa soluzione.
Giordania,

1
@Jordan Finora ho verificato la seconda metà della formula per m==n: il numero di rettangoli inclinati in un n*nquadrato è (4*n*n*n*n-n*n-3*n)/6. La sequenza è 0, 9, 51, 166, 410, 855, 1589, 2716, 4356, 6645 ma non appare in OEIS.
Neil,

1
Ora ho verificato che quando m>nè necessario aggiungere un ulteriore (m-n)(n*(4*n*n-1)/3)(ultima parte della formula presa da OEIS A000447). Riorganizzare e aggiungere la formula di @ betseg.
Neil,

@Neil Come sei arrivato a quelle formule?
Sherlock9,

2
@ Sherlock9 Ho calcolato manualmente il numero di rettangoli inclinati nei primi 10 quadrati e ho inserito la sequenza nel motore di ricerca OEIS che non ha riconosciuto la sequenza ma ho trovato una formula corrispondente alla formula dell'OP m==n. Ho quindi calcolato manualmente il numero di rettangoli inclinati in piccoli rettangoli e ho notato che aumentando la dimensione più lunga ho sempre aggiunto la stessa quantità di rettangoli per una data dimensione più corta. Ho inserito gli incrementi in OEIS che ha trovato una corrispondenza su A000447.
Neil,

4

Python, 73 68 byte

x=lambda m,n:m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6if m>n else x(n,m)

E mentre la versione seguente ha un byte superiore (75), è stato un buon esercizio trovare luoghi da usare ~:

def f(r,c):
 if r<c:r,c=c,r
 x=(4*c**3-c)/3
 return r*c*~r*~c/4+x*r--~x*c/2

68 byte se usi un lambda:x=lambda m,n:m*~m*n*~n/4+n*((2*m-n)*(4*n*n-1)-3)/6if m>n else x(n,m)
GamrCorps

Ahh, per qualche ragione ho pensato che dovessimo usare def. Grazie! Aggiornato.
Marcus Andrews,

3

Convesso, 37 36 byte

__:)+×½½\~æ<{\}&:N\¦\-N¦¦N*(*3-N*6/+

Provalo online!

Utilizza l'algoritmo di betseg modificato e ottimizzato per un linguaggio basato su stack. Spiegazione a venire quando avrò più tempo libero. Scommetto che questo può essere abbreviato, ma al momento non mi preoccuperò.


2

Lotto, 82 byte

@if %2 gtr %1 %0 %2 %1
@cmd/cset/a%1*~%1*%2*~%2/4+((%1+%1-%2)*(%2*%2*4-1)-3)*%2/6
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.