Czy potrafisz policzyć liczbę prostokątów?


21

Jedną z moich ulubionych matematycznych rozrywek jest narysowanie prostokątnej siatki, a następnie znalezienie wszystkich prostokątów widocznych na tej siatce. Proszę, odpowiedz na to pytanie i zaryzykuj dla siebie!

Czy potrafisz policzyć liczbę prostokątów?

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

Całkowita liczba prostokątów dla tej planszy do gry w mini-gry 4 x 4 jest dokładnie

100

Czy miałeś rację?

Powiązana matematyka: ile prostokątów jest na szachownicy 8 × 8?

Wyzwanie

Napisz najkrótszą funkcję / program, który zlicza całkowitą liczbę widocznych prostokątów na nie-toroidalnej siatce / obrazie .

Powiązane wyzwania: Policz unikalne prostokąty! , Znajdź liczbę prostokątów w tablicy bajtów 2D .

Format wejściowy

Twoja funkcja lub program może współpracować z wprowadzaniem tekstowym lub graficznym.

Wprowadzanie tekstu

Kratownica będzie M -by- N ( m rzędów n kolumn ASCII) siatkę składającą się z następujących postaci:

  • spacje,
  • - dla części poziomego odcinka linii,
  • | dla części pionowego odcinka linii oraz
  • + na zakręty.

Możesz wprowadzić tę siatkę ASCII jako dane wejściowe / argument do swojego programu / funkcji w postaci

  • pojedynczy ciąg rozdzielany podziałami linii,
  • ciąg bez znaków nowej linii, ale z jedną lub dwiema liczbami całkowitymi kodującymi wymiary siatki, lub
  • tablica ciągów.

Uwaga: Dane tekstowe zawierają co najmniej 1 wiersz i co najmniej 1 kolumnę.

Dane graficzne

Alternatywnie, siatki są kodowane jako czarno-białe obrazy PNG o szerokości 5 * n pikseli i wysokości 5 * m pikseli. Każdy obraz składa się z bloków 5 pikseli * 5 pikseli, które odpowiadają wprowadzeniu ASCII przez:

  • Spacje są konwertowane na białe bloki. Te bloki nazywane są blokami białych znaków .
  • Segmenty linii i narożniki są przekształcane w niewyspecjalizowanych bloków -whitespace. Środkowy piksel takich bloków jest czarny.
  • Edycja: Jeśli dwa rogi (na wejściu ASCII) są połączone segmentem linii, odpowiednie środki bloków (na wejściu graficznym) również powinny być połączone czarną linią.

Oznacza to, że każdy blok można wybrać tylko z Zignoruj ​​niebieskie granice. (Kliknij tutaj, aby powiększyć obraz) .

Uwaga: Niebieskie granice służą wyłącznie celom ilustracyjnym. Dane graficzne mają co najmniej 5 pikseli szerokości i 5 pikseli wysokości. Możesz przekonwertować dane graficzne na dowolny obraz monochromatyczny, potencjalnie inny format pliku obrazu. Jeśli zdecydujesz się na konwersję, podaj w odpowiedzi. Nie ma kary za nawrócenie.

Format wyjściowy

Jeśli piszesz program, musi on wyświetlać nieujemną liczbę wskazującą całkowitą liczbę prostokątów na wejściu.

Jeśli piszesz funkcję, powinna również zwrócić nieujemną liczbę wskazującą całkowitą liczbę prostokątów na wejściu.

Przykłady przypadków

Przypadek 1, grafika: Przypadek 1( 30 px * 30 px), ASCII: ( 6 rzędów, 6 kol.)

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

Oczekiwany wynik: 3

Przypadek 2, grafika: Przypadek 2( 20 pikseli * 20 pikseli), ASCII: ( 4 rzędy, 4 kolumny)

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

Oczekiwany wynik: 6

Przypadek 3, grafika: Przypadek 3( 55 pikseli * 40 pikseli), ASCII: ( 8 rzędów, 11 kol.)

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

Oczekiwany wynik: 9

Przypadek 4, grafika: Przypadek 4( 120 pikseli * 65 pikseli), ASCII: ( 13 wierszy, 24 kolumny)

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

Oczekiwany wynik: 243

Przypadek 5, grafika: Przypadek 5( 5 pikseli * 5 pikseli. Tak, jest tam!), ASCII: Tylko jedna spacja.

Oczekiwany wynik: 0

Przypadek 6, grafika: Przypadek 6( 35 pikseli * 20 pikseli), ASCII: ( 4 rzędy, 7 kolumn)

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

Oczekiwany wynik: 5

Założenia

Aby ułatwić Ci życie, masz gwarancję, że:

  • Ponieważ nie jest toroidalna , siatka nie zawija się ani w poziomie, ani w pionie.
  • Nie ma luźnych końcówek, np . +---Lub +- -+. Wszystkie segmenty linii mają dwa końce.
  • Dwie linie, które się spotykają, +muszą się przecinać w tym punkcie.
  • Nie musisz się martwić o nieprawidłowe dane wejściowe.

Obowiązują zasady dotyczące standardowych luk. Traktuj kwadraty jak prostokąty. Opcjonalnie możesz usunąć końcowe spacje w każdym rzędzie siatki.

To jest , więc , aby Twój wpis był jak najkrótszy. Rozwiązania tekstowe i graficzne będą ze sobą konkurować.

Tabela liderów


Czy dozwolona jest monochromatyczna mapa bitowa?
user202729,

@ user202729 Tak. Jeśli zdecydujesz się na pracę z obrazami innymi niż PNG, podaj to w odpowiedzi.
Frenzy Li,

Czy to jest poprawne wejście? (Narożnik prostokąta dotyka granicy większego prostokąta.) Jeśli tak, rozważ dodanie go jako przypadku testowego.
Zgarb

@Zgarb To poprawne wejście. Zmienię też post.
Frenzy Li,

Czy istnieje powód, dla którego umieściłeś oczekiwane wyniki w spoilerach? Wygląda na to, że weryfikacja kodu jest nieco bardziej irytująca.
FryAmTheEggman

Odpowiedzi:


4

Grime , 31 28 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe w formacie ASCII.

Wyjaśnienie

Składnia Grime'a jest bardzo zbliżona do wyrażeń regularnych. Każda linia określa wzór, który może, ale nie musi, pasować do prostokąta znaków. Tpasuje do prostokąta, którego górny rząd i lewa kolumna wyglądają na prawidłowe.

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

Drugi rząd to „program główny”.

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 bajtów

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>

Pobiera dane wejściowe jako tablicę ciągów o równej długości. Objaśnienie: Tworzy serię wyrażeń regularnych, które pasują do prostokątów o wszystkich możliwych szerokościach i wysokościach (i niektórych niemożliwych szerokościach i wysokościach, ale dla ciebie to kod golfowy) i zlicza, ile pasują wszystkie one. Ponieważ nie jest to grupa przechwytywania w regexp, splitpowraca 2n+1do nmeczów, więc przesunięcie w prawo o 1, aby uzyskać liczbę meczów, jak zapisuje bajt ponad dokonywania grupie bez przechwytywanie.


Hmm, fragment kodu nie działa dla mnie [Firefox 54.0.1 (32-bitowy) lub Chrome 60.0.3112.90 (64-bitowy) oba w systemie Windows (64-bitowym)].
Jonathan Allan,

Fragment Nie działa również w przeglądarce Safari [Mac (64-bitowy)].
Pan Xcoder,

2
Wygląda na to, że musimy wkleić elementy w polu tekstowym. Wymagana jest taka sama liczba znaków w wierszu.
Frenzy Li,

Ach, widzę, dobre miejsce @FrenzyLi!
Jonathan Allan,

4

J , 103 95 86 80 76 70 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe jako tablicę ciągów ze spacjami końcowymi (tak, aby każdy ciąg był tego samego rozmiaru). Używa operatora pełnej podtablicy ;._3do iteracji po każdym możliwym rozmiarze podtablicy większym niż 2 x 2 i zlicza podtablice, które są poprawnymi prostokątami. Prawie natychmiast wykonuje wszystkie przypadki testowe.


1
@FrenzyLi Thanks. Funkcja odbiera dane wejściowe jako tablicę ciągów, ale zakodowałem każdą tablicę jako płaski ciąg przekształcony w tablicę, zanim zapisałem je w każdej zmiennej, która ma być wykorzystana jako argument funkcji.
mile

Ahh ... Dziękuję za wyjaśnienie.
Frenzy Li,

@miles nice. kiedy mówisz input jako tablicę ciągów, czy każdy wiersz wejściowego 1 żądło?
Jonasz

@Jonah Strings in J to po prostu tablice znaków, więc dane wejściowe to tak naprawdę tablica znaków 2d.
mile

3

Mathematica, 136 134 132 bajtów

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}]&

Użycie: (dla starej 136-bajtowej wersji, ale nowa wersja jest w zasadzie identyczna)

_

Uwaga:

  • Działa to w czasie O (m 2 n 2 max (m, n)), więc używaj tylko małych danych wejściowych.
  • Chociaż ma to działać z obrazami binarnymi, najwyraźniej może działać z obrazami niebinarnymi. (ale czarny musi być identycznie zero)
  • Grafika niekoniecznie musi być zbudowana z bloków 5x5, bloki mogą być mniejsze.
  • @*jest nowy w wersji 10. W starszych wersjach użyj Tr~Composition~Flattenzamiast Tr@*Flatten.

W jakiej wersji MMA to jest? W wersji 9.0 odpowiada"Tr@" cannot be followed by "*Flatten".
Frenzy Li

1
@FrenzyLi 10.0. Tak, @*(skrót od Composition) jest nowy w wersji 10.
user202729,

1
Dlaczego po prostu nie używasz RectangleCount[]?
MCMastery

2
@MCMastery Mathematica słynie z wielu wbudowanych, ale nie tego.
user202729,

@ user202729 lol yep, im jk
MCMastery

2

Galareta ,  60 53 52 51  50 bajtów

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

Pełny program akceptujący listę ciągów (wiersze o równej długości) i drukujący liczbę.

Wypróbuj online!
... lub na łatwość kopiowania i wklejania wykorzystane doświadczenia to pełny program (z dodatkowym bajt do linii Split)
- Należy pamiętać, że linie mają obowiązek zawierać spacje dla programu funkcjonować poprawnie chociaż.

W jaki sposób?

Ñ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

Poślizg , 32 29 bajtów

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

Wypróbuj online!

27 bajtów kodu + 2 bajty dla flag ni o. Pobiera dane wejściowe w tym samym formacie, który podano w pytaniu (tj. Blok linii rozdzielany znakiem nowej linii).


2

Haskell, 180 167 166 bajtów

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]

Wypróbuj online!

Przejdź przez wszystkie możliwe pozycje narożne za pomocą czterech zagnieżdżonych pętli i sprawdź, czy wszystkie znaki na liniach między nimi składają się z +-(poziomej) lub +|(pionowej).


1

Galaretka , 41 39 34 33 bajtów

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

Wypróbuj online! lub Wyświetl wszystkie skrzynki.

Na podstawie mojej odpowiedzi w J.

Wyjaśnienie

,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

Teraz zaczyna być konkurencyjny, bo ma 34 bajty.
mile
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.