Dikdörtgenlerin sayısını sayabilir misiniz?


21

En sevdiğim matematiksel oyunlardan biri dikdörtgen bir ızgara çizip, o ızgarada görülebilen tüm dikdörtgenleri bulmak. İşte, bu soruyu al ve kendin için girişimde ol!

Dikdörtgenlerin sayısını sayabilir misiniz?

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

Bunun için dikdörtgenler toplam sayısı 4 x 4 minichess kurulu tam olarak

100

Doğru muydun?

İlgili matematik: 8 × 8'lik bir dama tahtası üzerinde kaç tane dikdörtgen var?

Meydan okuma

Toroid olmayan bir ızgaradaki / görüntünün toplam görünür dikdörtgen sayısını sayan en kısa işlevi / programı yazın .

İlgili zorluklar: Eşsiz Dikdörtgenleri sayın! , 2B bayt dizisindeki dikdörtgenlerin sayısını bulun .

Giriş biçimi

İşleviniz veya programınız, metin tabanlı giriş veya grafiksel girişle çalışmayı seçebilir.

Metin Tabanlı Giriş

Izgara , aşağıdaki karakterlerden oluşan bir m- by- n ( m satır, n sütun) ASCII ızgara olacaktır:

  • boşluk,
  • - Yatay çizgi bölümünün parçaları için,
  • | dikey bir çizgi parçasının parçaları için ve
  • + köşeler için.

Bu ASCII ızgarasını, programınıza / işlevinize giriş / bağımsız değişken olarak tanıtabilirsiniz.

  • Satır sonları ile ayrılmış tek bir dize,
  • yeni satırlar içermeyen ancak kılavuzun boyutlarını kodlayan bir veya iki tamsayılı olan bir dize veya
  • dizelerin bir dizi.

Not: Metin tabanlı giriş, en az 1 satır ve en az 1 sütun içerir.

Grafiksel giriş

Alternatif olarak, ızgaralar 5 * n piksel genişliğinde ve 5 * m piksel yüksekliğinde siyah beyaz PNG görüntüleri olarak kodlanır . Her görüntü , ASCII girişine karşılık gelen 5 px * 5 px bloktan oluşur :

  • Boşluklar beyaz bloklara dönüştürülür. Bu bloklara boşluk blokları denir .
  • Çizgi bölümleri ve köşeleri beyaz olmayan bloklara dönüştürülür . Bu tür blokların merkez pikselleri siyahtır.
  • Düzenleme: Eğer iki köşe (ASCII girişinde) bir çizgi segmentine bağlanmışsa, karşılık gelen blok merkezlerinin (grafiksel giriş) siyah bir çizgi ile de bağlanması gerekir.

Bu, her bloğun yalnızca seçilebileceği anlamına gelir Lütfen mavi sınırları dikkate almayın. (Daha büyük resim için buraya tıklayın) .

Not: Mavi sınırlar sadece gösterim amaçlıdır. Grafiksel giriş en az 5 piksel genişliğinde ve 5 piksel yüksekliğindedir. Grafiksel girişi, potansiyel olarak başka görüntü dosyası biçimleri olan herhangi bir tek renkli görüntüye dönüştürebilirsiniz). Dönüştürmeyi seçerseniz, lütfen cevapta belirtin. Dönüşüm cezası yok.

Çıkış biçimi

Bir program yazıyorsanız, girişteki toplam dikdörtgen sayısını belirten negatif olmayan bir sayı göstermelidir.

Bir işlev yazıyorsanız, girişteki toplam dikdörtgen sayısını belirten negatif olmayan bir sayı da döndürmelidir.

Örnek Olaylar

Durum 1, Grafik: Dava 1( 30 piksel x 30 piksel), ASCII: ( 6 satır, 6 sütun)

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

Beklenen çıktı: 3

Durum 2, Grafik: Durum 2( 20 piksel * 20 piksel), ASCII: ( 4 satır, 4 sütun)

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

Beklenen çıktı: 6

Durum 3, Grafik: 3. Durum( 55 piksel * 40 piksel), ASCII: ( 8 satır, 11 sütun)

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

Beklenen çıktı: 9

Durum 4, Grafik: 4. Durum( 120 piksel * 65 piksel), ASCII: ( 13 satır, 24 sütun)

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

Beklenen çıktı: 243

Durum 5, Grafik: Durum 5( 5 px * 5 px. Evet, işte orada!), ASCII: Sadece tek bir boşluk.

Beklenen çıktı: 0

Durum 6, Grafik: Durum 6( 35 piksel x 20 piksel), ASCII: ( 4 satır, 7 sütun)

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

Beklenen çıktı: 5

Varsayımlar

Hayatı kolaylaştırmak için, aşağıdakileri garanti ediyoruz:

  • Davranarak olmayan toroidal bir ızgara yatay ya da dikey ya da sarılmaz.
  • Gevşek uç yoktur, örneğin +--- veya +- -+. Tüm çizgi parçalarının iki ucu vardır.
  • Karşılaşan iki çizgi, bu +noktada birbiriyle kesişmelidir.
  • Geçersiz girişler için endişelenmenize gerek yok.

Standart boşluklara karşı kurallar uygulanır. Lütfen karelere dikdörtgenler gibi davranın. İsteğe bağlı olarak, kılavuzun her satırındaki sondaki boşlukları kaldırabilirsiniz.

Bu , bu yüzden girişinizi mümkün olduğunca kısa yapın. Metin tabanlı ve grafiksel çözümler birlikte rekabet edecek.

Liderler Sıralaması


Tek renkli bitmap'e izin verilir mi?
user202729

@ user202729 Evet. PNG olmayan resimlerle çalışmayı seçerseniz, lütfen cevabı belirtiniz.
Frenzy Li

bu geçerli bir giriş? (Dikdörtgen köşesi daha büyük dikdörtgenin kenarına dokunur.) Öyleyse, onu bir test durumu olarak eklemeyi düşünün.
Zgarb

@Zgarb Geçerli bir giriştir. Ben de yazıyı düzenleyeceğim.
Frenzy Li

Beklenen çıktıları spoilerde koymanızın bir nedeni var mı? Sadece kodunuzu biraz daha sinir bozucu doğrulayarak yapar gibi görünüyor.
FryAmTheEggman

Yanıtlar:


4

Grime , 31 28 bayt

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

Çevrimiçi deneyin!

ASCII formatında girdi alır.

açıklama

Grime'nin sözdizimi normal ifadelere çok yakın. Her satır bir karakter dikdörtgeniyle eşleşebilecek veya eşleşmeyecek bir deseni tanımlar. Tüst satır ve sol sütun geçerli görünen bir dikdörtgenle eşleşiyor.

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

İkinci satır "ana program" dır.

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 bayt

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>

Girdiyi eşit uzunlukta bir dizge dizisi olarak alır. Açıklama: Tüm olası genişlik ve yükseklikteki (ve bazı imkansız genişlik ve yüksekliklerin dikdörtgenlerini eşleşen, ancak bu sizin için golf kodu) bir dizi normal ifade oluşturur ve bunların hepsinin kaç tane eşleştirdiğini sayar. Regexp'de bir yakalama grubu olduğu için, eşleşmeler için splitgeri döner , bu nedenle grubu yakalamayan bir bayttan kurtardığı için eşleşme sayısını almak için 1'e doğru kaydırırım.2n+1n


Hmm, kod pasajı benim için çalışmıyor [Firefox 54.0.1 (32bit) veya Chrome 60.0.3112.90 (64bit) hem Windows'ta (64bit)].
Jonathan Allan,

Snippet Safari'de de çalışmıyor [Mac (64bit)].
Bay Xcoder

2
Metin alanlarına bir şeyler yapıştırmamız gerekecek gibi görünüyor. Satır başına aynı sayıda karakter gerekir.
Frenzy Li

Ah Anladım, @FrenzyLi iyi nokta!
Jonathan Allan

4

J , 103 95 86 80 76 70 bayt

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

Çevrimiçi deneyin!

Girdiyi, boşlukları olan bir dizi dizisi olarak alır (böylece her dize aynı boyutta olur). 2 x 2'den büyük olan her olası alt dizi boyutunu yinelemek için tam alt dizi operatörünü kullanır ve ;._3geçerli dikdörtgenler olan alt dizileri sayar. Tüm test durumlarını neredeyse anında tamamlar.


1
@FrenzyLi Teşekkürler. İşlev girişi bir dizi dizisi olarak alıyor, ancak her diziyi işlev için bağımsız değişken olarak kullanılmak üzere her değişkende saklamadan önce bir diziye yeniden şekillendirilen düz bir dize olarak kodladım.
mil

Ahh ... Açıkladığınız için teşekkür ederim.
Frenzy Li

@miles güzel. dizge dizisi olarak girdi deyince girdi 1 dizisinin her satırı mı?
Jonah

J'deki @Jonah Strings sadece karakter dizileridir, bu nedenle giriş aslında 2d karakter dizisidir.
mil,

3

Mathematica, 136 134 132 bayt

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

Kullanımı: (eski 136 bayt sürümü için, ancak yeni sürüm temelde aynıdır)

_

Not:

  • Bu O zamanında çalışır (m 2 n 2 maks (m, n)), bu nedenle sadece küçük girişleri kullanın.
  • Bunun ikili görüntülerle çalışması gerekiyorsa da, görünüşe göre ikili olmayan görüntülerle çalışabilir. (ancak siyah aynı sıfır olmalıdır)
  • Grafikler mutlaka 5x5 bloklarla oluşturulmaz, bloklar daha küçük olabilir.
  • @*10. sürümde yeni. Eski sürümlerde Tr~Composition~Flattenyerine kullanın Tr@*Flatten.

Bu hangi MMA sürümünde ? 9.0'da cevap veriyor"Tr@" cannot be followed by "*Flatten".
Frenzy Li

1
@FrenzyLi 10.0. Evet, @*(kısa yol için Composition) 10. sürümde yeni.
user202729

1
Neden sadece kullanmıyorsun RectangleCount[]?
MCMastery,

2
@MCMastery Mathematica, birçok yerleşik sisteme sahip olmasıyla ünlüdür, ancak bunu değil.
user202729

@ user202729 lol yep, im jk
MCMastery

2

Jöle ,  60 53 52 51  50 bayt

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

Dizelerin bir listesini (eşit uzunluktaki satırlar) kabul eden ve sayımı yazdıran tam bir program

Çevrimiçi deneyin!
... veya kopyalayıp yapıştırma kolaylığı için bu tam programıkullanın(satırları bölmek için fazladan bir baytla)
- satırların programın doğru çalışması için izleyen boşluklar içermesi gerektiğini unutmayın.

Nasıl?

Ñ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

Kayma , 32 29 bayt

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

Çevrimiçi deneyin!

Kod + 2 27 byte için bayt nve obayrakları. Girdiyi soruda verilenle aynı formatta alır (yani, yeni satırlarla ayrılmış satır bloğu).


2

Haskell, 180 167 166 bayt

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]

Çevrimiçi deneyin!

Dört iç içe döngü ile tüm olası köşe konumlarından geçin ve aralarındaki çizgilerdeki tüm karakterlerin +-(yatay) veya +|(dikey) olup olmadığını kontrol edin .


1

Jelly , 41 39 34 33 bayt

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

Çevrimiçi deneyin!veya Tüm davaları görüntüle.

Benim dayalı cevap J.

açıklama

,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

Şimdi nihayet 34 baytta rekabetçi bir şekilde kısa hissetmeye başlıyor.
mil:
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.