Riesci a contare il numero di rettangoli?


21

Uno dei miei passatempi matematici preferiti è disegnare una griglia rettangolare, quindi trovare tutti i rettangoli che sono visibili in quella griglia. Ecco, prendi questa domanda e avventurati!

Riesci a contare il numero di rettangoli?

+-----+-----+-----+-----+
|     |     |     |     |
|     |     |     |     |
+-----+-----+-----+-----+
|     |     |     |     |
|     |     |     |     |
+-----+-----+-----+-----+
|     |     |     |     |
|     |     |     |     |
+-----+-----+-----+-----+
|     |     |     |     |
|     |     |     |     |
+-----+-----+-----+-----+

Il numero totale di rettangoli per questa scheda minichess 4 x 4 è esattamente

100

Eri corretto?

Matematica correlata: quanti rettangoli ci sono su una scacchiera 8 × 8?

La sfida

Scrivi la funzione / programma più breve che conta il numero totale di rettangoli visibili su una griglia / immagine non toroidale .

Sfide correlate: Count the Unique Rectangles! , Trova il numero di rettangoli in una matrice di byte 2D .

Formato di input

La tua funzione o programma può scegliere di lavorare con input basato su testo o input grafico.

Input basato su testo

La griglia sarà una griglia ASCII m -by- n ( m righe, n colonne) composta dai seguenti caratteri:

  • spazi,
  • - per parti di un segmento di linea orizzontale,
  • | per parti di un segmento di linea verticale e
  • + per gli angoli.

Puoi introdurre questa griglia ASCII come input / argomento nel tuo programma / funzione sotto forma di

  • una singola stringa delimitata da interruzioni di riga,
  • una stringa senza newline ma con uno o due numeri interi che codificano le dimensioni della griglia, oppure
  • una matrice di stringhe.

Nota: l'input basato sul testo contiene almeno 1 riga e almeno 1 colonna.

Input grafico

In alternativa, le griglie sono codificate come immagini PNG in bianco e nero di 5 * n pixel di larghezza e 5 * m pixel di altezza. Ogni immagine è composta da blocchi di 5 px * 5 px che corrispondono all'ingresso ASCII di:

  • Gli spazi vengono convertiti in blocchi bianchi. Questi blocchi sono chiamati blocchi di spazi bianchi .
  • I segmenti di linea e gli angoli vengono convertiti in blocchi non bianchi. Il pixel centrale di tali blocchi è nero.
  • Modifica: se due angoli (nell'ingresso ASCII) sono collegati da un segmento di linea, anche i centri di blocco corrispondenti (nell'ingresso grafico) devono essere collegati da una linea nera.

Ciò significa che ogni blocco può essere scelto solo Si prega di ignorare i confini blu. (fare clic qui per ingrandire l'immagine) .

Nota: i confini blu sono solo a scopo illustrativo. L'input grafico è largo almeno 5 px e alto 5 px. È possibile convertire l'input grafico in qualsiasi immagine monocromatica, potenzialmente di altri formati di file immagine). Se si sceglie di convertire, si prega di specificare nella risposta. Non è prevista alcuna penalità per la conversione.

Formato di output

Se stai scrivendo un programma, deve visualizzare un numero non negativo che indica il numero totale di rettangoli nell'input.

Se stai scrivendo una funzione, dovrebbe anche restituire un numero non negativo che indica il numero totale di rettangoli nell'input.

Casi di esempio

Caso 1, Grafica: Caso 1( 30 px * 30 px), ASCII: ( 6 righe, 6 cols)

+--+  
|  |  
| ++-+
+-++ |
  |  |
  +--+

Uscita prevista: 3

Caso 2, Grafica: Caso 2( 20 px * 20 px), ASCII: ( 4 file, 4 colonne )

++-+
|+++
+++|
+-++

Uscita prevista: 6

Caso 3, Grafica: Caso 3( 55 px * 40 px), ASCII: ( 8 righe, 11 cols)

  +++--+   
+-+++  |   
|  |  ++--+
+--+--++ ++
      |  ||
      |  ||
++    +--++
++         

Uscita prevista: 9

Caso 4, Grafica: Caso 4( 120 px * 65 px), ASCII: ( 13 righe, 24 cols)

+--+--+ +--+  +--+  +--+
|  |  | |  |  |  |  |  |
+--+--+ |  |  |  |  |  |
|  |  | +--+--+--+--+--+
+--+--+    |  |  |  |   
           |  |  |  | ++
+-+-+-+-+  +--+  +--+ ++
| | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+

Uscita prevista: 243

Caso 5, Grafica: Caso 5( 5 px * 5 px. Sì, è lì!), ASCII: solo un singolo spazio.

Uscita prevista: 0

Caso 6, Grafica: Caso 6( 35 px * 20 px), ASCII: ( 4 righe, 7 cols)

+--+--+
|++|++|
|++|++|
+--+--+

Uscita prevista: 5

ipotesi

Per semplificarti la vita, hai la garanzia che:

  • Essendo non toroidale , la griglia non si avvolge né in orizzontale né in verticale.
  • Non ci sono estremità libere, ad esempio +--- o +- -+. Tutti i segmenti di linea hanno due estremità.
  • In quel punto due linee che si incontrano +devono intersecarsi.
  • Non devi preoccuparti di input non validi.

Si applicano le regole contro le scappatoie standard. Si prega di trattare i quadrati come rettangoli. Facoltativamente, è possibile rimuovere gli spazi finali su ciascuna riga della griglia.

Si tratta di , quindi rendi il tuo ingresso il più breve possibile. Le soluzioni testuali e grafiche competeranno insieme.

Classifica


È consentita la bitmap monocromatica?
user202729

@ user202729 Sì. Se si sceglie di lavorare con immagini non PNG, specificarlo nella risposta.
Frenzy Li,

E ' questo un input valido? (L'angolo del rettangolo tocca il bordo del rettangolo più grande.) In tal caso, considera di aggiungerlo come caso di prova.
Zgarb,

@Zgarb È un input valido. Modificherò anche il post.
Frenzy Li,

C'è un motivo per cui hai messo gli output previsti negli spoiler? Sembra che la verifica del codice sia leggermente più fastidiosa.
FryAmTheEggman,

Risposte:


4

Grime , 31 28 byte

T=\+[+\-]*\+/[+|]/+$
n`T&To2

Provalo online!

Accetta input in formato ASCII.

Spiegazione

La sintassi di Grime è molto vicina alle espressioni regolari. Ogni riga definisce un modello che può o meno corrispondere a un rettangolo di caratteri. Tcorrisponde a un rettangolo la cui riga superiore e colonna sinistra sembrano valide.

T=\+[+\-]*\+/[+|]/+$
T=                    Define T as
  \+[+\-]*\+          a row that matches this regex
            /         and below that
             [+|]/+   a column of + or |
                   $  with anything to its right.

La seconda riga è il "programma principale".

n`T&To2
n`       Print number of rectangles that match
  T      the pattern T
   &     and
    To2  T rotated 180 degrees.

6

JavaScript (ES6), 176 171 byte

g=a=>Math.max(...b=a.map(a=>a.length))-Math.min(...b)?``:f(a);f=
a=>a.map((b,i)=>[...b].map((_,j)=>n+=a.join`
`.split(eval(`/\\+(?=[-+]{${j}}\\+[^]{${l=b.length+~j}}([|+].{${j}}[|+][^]{${l}}){${i}}\\+[-+]{${j}}\\+)/`)).length>>1),n=0)|n
<textarea rows=8 cols=8 oninput=o.textContent=g(this.value.split`\n`)></textarea><pre id=o>

Accetta input come una matrice di stringhe di uguale lunghezza. Spiegazione: Crea una serie di espressioni regolari che corrispondono a rettangoli di tutte le larghezze e altezze possibili (e alcune larghezze e altezze impossibili, ma questo è il golf per te) e conta quante partite tutte producono. Perché c'è un gruppo di acquisizione nel regexp, splitritorna 2n+1per le npartite, quindi faccio scorrere a destra di 1 per ottenere il numero di partite, in quanto ciò consente di risparmiare un byte rendendo il gruppo non acquisibile.


Hmm, il frammento di codice non funziona per me [Firefox 54.0.1 (32 bit) o ​​Chrome 60.0.3112.90 (64 bit) sia su Windows (64 bit)].
Jonathan Allan,

Lo snippet Non funziona neanche su Safari [Mac (64 bit)].
Mr. Xcoder,

2
Sembra che dobbiamo incollare roba nell'area di testo. È richiesto lo stesso numero di caratteri per riga.
Frenzy Li,

Ah capisco, bel posto @FrenzyLi!
Jonathan Allan,

4

J , 103 95 86 80 76 70 byte

[:+/@,]*/@('-|++'*/@(e.,&'+')~&>]({.,{:)&.>@;|:;{.;{:);._3"$~2+$#:i.@$

Provalo online!

Accetta l'input come una matrice di stringhe con spazi finali (in modo che ogni stringa abbia le stesse dimensioni). Utilizza l' operatore di subarray completo;._3 per scorrere ogni possibile dimensione di subarray superiore a 2 x 2 e conta i sottoarray che sono rettangoli validi. Completa quasi tutti i casi di test all'istante.


1
@FrenzyLi Grazie. La funzione sta ricevendo l'input come un array di stringhe, ma ho codificato ogni array come una stringa piatta rimodellata in un array prima di memorizzarli in ciascuna variabile da utilizzare come argomento per la funzione.
miglia,

Ahh ... Grazie per la tua spiegazione.
Frenzy Li,

@miles nice. quando dici input come array di stringhe, ogni riga della puntura di input 1?
Giona,

@Jonah Le stringhe in J sono solo matrici di caratteri, quindi l'input è in realtà un array di caratteri 2D.
miglia

3

Matematica, 136 134 132 byte

S=Tr@*Flatten;S@Table[1-Sign@S@{d[[{i,j},k;;l]],d[[i;;j,{k,l}]]},{i,($=Length)[d=ImageData@#]},{j,i+1,$@d},{k,w=$@#&@@d},{l,k+1,w}]&

Utilizzo: (per la vecchia versione da 136 byte, ma la nuova versione è sostanzialmente identica)

_

Nota:

  • Questo corre nel tempo O (m 2 n 2 max (m, n)), quindi usa solo piccoli input.
  • Anche se questo dovrebbe funzionare con immagini binarie, apparentemente può funzionare con immagini non binarie. (ma il nero deve essere identicamente zero)
  • La grafica non deve necessariamente essere costruita con blocchi 5x5, i blocchi possono essere più piccoli.
  • @*è nuovo nella versione 10. Nelle versioni precedenti, utilizzare Tr~Composition~Flatteninvece di Tr@*Flatten.

In quale versione di MMA è presente? In 9.0, risponde con"Tr@" cannot be followed by "*Flatten".
Frenzy Li

1
@FrenzyLi 10.0. Sì, @*(abbreviazione di Composition) è nuovo nella versione 10.
user202729

1
Perché non usi semplicemente RectangleCount[]?
MCMastery,

2
@MCMastery Mathematica è famosa per avere molti built-in, ma non questo.
user202729

@ user202729 lol yep, im jk
MCMastery,

2

Gelatina ,  60 53 52 51  50 byte

ÑFQe⁹ṚẆ;W¤
Ḣ,Ṫ
=”+ÇÇ€Ạȧ1ŀ
Zç⁾+-ȧç⁾+|$
Ẇ;"/€Ẇ€Ç€€FS

Un programma completo che accetta un elenco di stringhe (righe di uguale lunghezza) e stampa il conteggio.

Provalo online!
... o per facilitare l'input copia e incolla utilizzare questo programma completo (con un byte in più per dividere le linee)
- si noti che le linee devono contenere spazi finali per il corretto funzionamento del programma.

Come?

ÑFQe⁹ṚẆ;W¤   - Link 1, sidesAreValid?: list of lists, area; list allowedSideCharacters
Ñ            - call the next link (2) as a monad (get the sides in question
             -   note: these sides do not include the corners since the area was modified
             -   to not include the other sides by the first call to link 2 inside link 3.
 F           - flatten into a single list
  Q          - de-duplicate (unique characters)
         ¤   - nilad followed by link(s) as a nilad:
    ⁹        -   right argument (either "+-"                or "+|"               )
     Ṛ       -   reverse        (either "-+"                or "|+"               )
      Ẇ      -   all sublists   (either ["-","+","-+"]      or ["|","+","|+"]     )
        W    -   wrap           (either ["+-"]              or ["+|"]             )
       ;     -   concatenate    (either ["-","+","-+","+-"] or ["|","+","|+","+|"])
   e         - exists in?

Ḣ,Ṫ          - Link 2, topAndTail helper: list
Ḣ            - head (get the first element and modify the list)
  Ṫ          - tail (get the last element and modify the list)
 ,           - pair (the elements together)

=”+ÇÇ€Ạȧ1ŀ   - Link 3, isPartlyValid?: list of lists, area; list allowedSideCharacters
=”+          - equal to '+'? (vectorises across the whole area, 1 if so, 0 otherwise)
   Ç         - call the last link (2) as a monad (gets the values for two edges)
    Ç€       - call the last link (2) as a monad for €ach (...values for the four corners)
      Ạ      - all? (all corners are '+' 1 if so, 0 if not)
        1ŀ   - call link number 1 as a dyad with sideCharacters as the right argument
             -    ...and the modified area on the left
       ȧ     - logical and (both all corners are '+' and the sides in question look right)

Zç⁾+-ȧç⁾+|$  - Link 4, isValidSquare?: list of lists, area
Z            - transpose
 ç⁾+-        - call the last link (3) as a dyad with right argument "+-"
          $  - last two links as a monad:
      ç⁾+|   -   call the last link (3) as a dyad with right argument "+|"
     ȧ       - logical and (1 if so 0 otherwise)

Ẇ;"/€Ẇ€Ç€€FS - Main Link: list of lists of characters, rows
Ẇ            - all sublists (= all non-zero length runs of rows)
   /€        - reduce €ach by:
  "          -   zip with:
 ;           -     concatenation (= all non-zero length vertical edges)
     Ẇ€      - all sublists for €ach (= all possible areas)
       Ç€€   - call the last link (4) as a monad for €ach for €ach (for each area)
          F  - flatten
           S - sum

2

Slip , 32 29 byte

$a([+`-]*`+>[+`|]*`+>){2}$A

Provalo online!

27 byte di codice + 2 byte per i flag ne o. Accetta input nello stesso formato fornito nella domanda (ovvero blocco di linee delimitato da newline).


2

Haskell, 180 167 166 byte

l=length
a%b=[a..b-1]
h c a g b=all(`elem`c)$g<$>[a..b]
f s|(#)<-(!!).(s!!)=sum[1|y<-1%l s,x<-1%l(s!!0),i<-0%y,j<-0%x,h"+|"i(#x)y,h"+-"j(y#)x,h"+|"i(#j)y,h"+-"j(i#)x]

Provalo online!

Passa attraverso tutte le possibili posizioni degli angoli con quattro anelli nidificati e controlla se tutti i caratteri sulle linee tra loro sono costituiti da +-(orizzontale) o +|(verticale).


1

Gelatina , 41 39 34 33 byte

,Z;.ị$⁺€ḟ€"⁾-|Fḟ”+
ẆḊÐfZ€µ⁺€ẎÇÐḟL

Provalo online! oppure Visualizza tutti i casi.

Sulla base della mia risposta in J.

Spiegazione

,Z;.ị$⁺€ḟ€"⁾-|Fḟ”+  Helper. Input: 2d array of characters
 Z                  Transpose
,                   Pair
  ;                   Concatenate with
     $                The tail and head
   .ị                   Select at index 0.5 -> Select at index 0 and 1
                        Jelly uses 1-based modular indexing, so
                        0 means to select the tail
      ⁺€              Repeat on each - This selects the last and first rows,
                      last and first columns, and the 4 corners
           ⁾-|       The string array ['-', '|']
          "          Vectorize
        ḟ€             Filter each
              F      Flatten
                ”+   The character '+'
               ḟ

ẆḊÐfZ€µ⁺€ẎÇÐḟL  Main. Input: 2d array of characters
      µ         Combine into a monad
Ẇ                 Generate all sublists
  Ðf              Filter for the values that are truthy (non-empty)
 Ḋ                  Dequeue
    Z€            Transpose each
       ⁺€       Repeat on each
         Ẏ      Tighten, join all lists on the next depth
          ÇÐḟ   Discard the values where executing the helper returns truthy
             L  Length

Ora finalmente sta iniziando a sentirsi competitivo in breve a 34 byte.
miglia
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.