長方形の数を数えられますか?


21

私のお気に入りの数学的な楽しみの1つは、長方形のグリッドを描画し、そのグリッドに表示されているすべての長方形を見つけることです。ここで、この質問に答えて、自分で冒険しましょう!

長方形の数を数えられますか?

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

この4 x 4 ミニチェスボードの長方形の総数は正確に

100

正解でしたか?

関連する数学: 8x8チェッカーボードにはいくつの長方形がありますか?

チャレンジ

非トロイダルグリッド/イメージ上の可視矩形の総数をカウントする最短の関数/プログラムを記述します。

関連する課題: ユニークな長方形を数える!2Dバイト配列で長方形の数を見つけます

入力フォーマット

関数またはプログラムは、テキストベースの入力またはグラフィカルな入力のどちらで動作するかを選択できます。

テキストベースの入力

グリッドはなりM行列n個M個の行、N列)以下の文字からなるASCIIグリッドを:

  • スペース、
  • - 水平線分の一部の場合、
  • | 垂直線分の一部、および
  • + コーナー用。

このASCIIグリッドは、プログラム/関数への入力/引数として次の形式で導入できます。

  • 改行で区切られた単一の文字列、
  • 改行はないが、グリッドの次元をエンコードする1つまたは2つの整数を持つ文字列、または
  • 文字列の配列。

注: テキストベースの入力が少なくとも含まれている1行と少なくとも1列。

グラフィカル入力

または、グリッドは幅5 * nピクセル、高さ5 * mピクセルの白黒PNG画像としてエンコードされます。各画像は5 px * 5 pxのブロックで構成され、ASCII入力に対応します。

  • スペースは白いブロックに変換されます。これらのブロックは、空白ブロックと呼ばれます。
  • 線分と角は空白ブロックに変換されます。このようなブロックの中心ピクセルは黒です。
  • 編集:(ASCII入力の)2つの角が線分で接続されている場合、対応するブロックの中心(グラフィカル入力の)も黒い線で接続する必要があります。

つまり、各ブロックは青い境界線は無視してください。 (拡大画像についてはここをクリック)からのみ選択できます。

注: 青い境界線は、説明のみを目的としています。グラフィカル入力は、少なくともある5ワイドpxと5のPX高いです。グラフィカル入力を、他の画像ファイル形式の可能性があるモノクロ画像に変換できます。変換を選択した場合は、回答で指定してください。変換に対するペナルティはありません。

出力フォーマット

プログラムを作成する場合、入力内の長方形の総数を示す負でない数を表示する必要があります。

関数を作成している場合、入力内の長方形の総数を示す負でない数も返す必要があります。

事例

ケース1、グラフィック:事例130 px * 30 px)、ASCII:(6行、6列)

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

期待される出力: 3

ケース2、グラフィック:事例220 px * 20 px)、ASCII:(4行、4列)

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

期待される出力: 6

ケース3、グラフィック:事例355 px * 40 px)、ASCII:(8行、11列)

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

期待される出力: 9

ケース4、グラフィック:事例4120 px * 65 px)、ASCII:(13行、24列)

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

期待される出力: 243

ケース5、グラフィック:事例55ピクセル* 5。PXはい、それはですが!)、ASCII:ちょうど単一のスペース。

期待される出力: 0

ケース6、グラフィック:事例635 px * 20 px)、ASCII:(4行、7列)

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

期待される出力: 5

仮定

生活を楽にするために、次のことが保証されます。

  • であることによって非トロイダル、グリッドは、水平または垂直方向のいずれか折り返されません。
  • 不良が終了、ありません例えば +---または+- -+。すべての線分には2つの端があります。
  • で交わる2本の線は+、その点で互いに交差する必要があります。
  • 無効な入力について心配する必要はありません。

標準的な抜け穴に対するルールが適用されます。正方形を長方形として扱ってください。オプションで、グリッドの各行の末尾のスペースを削除できます。

これはなので、エントリはできるだけ短くしてください。テキストベースのソリューションとグラフィカルなソリューションが競合します。

リーダーボード


モノクロのビットマップは許可されていますか?
user202729

@ user202729はい。PNG以外の画像を使用する場合は、回答でそのことを指定してください。
フレンジーリー

、これは有効な入力?(長方形の角は、より大きな長方形の境界に接しています。)その場合、テストケースとして追加することを検討してください。
-Zgarb

@Zgarb有効な入力です。投稿も編集します。
フレンジーリー

予想されるアウトプットをネタバレに入れる理由はありますか?コードの検証が少し面倒になるだけのようです。
FryAmTheEggman

回答:


4

グライム31 28バイト

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

オンラインでお試しください!

ASCII形式で入力を取ります。

説明

グライムの構文は、正規表現に非常に近いものです。各行は、文字の長方形に一致する場合と一致しない場合があるパターンを定義します。 T上の行と左の列が有効に見える長方形に一致します。

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

2行目は「メインプログラム」です。

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バイト

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>

入力を等しい長さの文字列の配列として受け取ります。説明:すべての可能な幅と高さ(およびいくつかの不可能な幅と高さですが、それはあなたのためのコードゴルフです)の長方形に一致する一連の正規表現を作成し、それらがすべて一致する数をカウントします。正規表現にキャプチャグループがあるため、一致をsplit返す2n+1ためn、1を右にシフトして一致の数を取得します。これにより、グループをキャプチャせずに1バイト節約できます。


うーん、コードスニペットは動作しません[Firefox 54.0.1(32bit)またはChrome 60.0.3112.90(64bit)両方ともWindows(64bit)]。
ジョナサンアラン

スニペット[Mac(64bit)]でもSafariでは機能しません。
ミスターXcoder

2
テキスト領域に何かを貼り付ける必要があるようです。行ごとに同じ文字数が必要です。
フレンジーリー

ああ、良いスポット@FrenzyLi!
ジョナサンアラン

4

J103 95 86 80 76 70バイト

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

オンラインでお試しください!

入力を末尾のスペースを含む文字列の配列として受け取ります(したがって、各文字列は同じサイズになります)。完全なサブ配列演算子;._3を使用して、2 x 2より大きいすべての可能なサブ配列サイズを反復処理し、有効な長方形であるサブ配列をカウントします。すべてのテストケースをほぼ瞬時に完了します。


1
@FrenzyLiありがとう。関数は入力を文字列の配列として受け取りますが、関数の引数として使用する各変数に格納する前に、各配列をフラットな文字列として配列にエンコードしてエンコードしました。
マイル

ああ...説明ありがとうございます。
フレンジーリー

@miles nice。入力を文字列の配列として言うとき、入力の各行は1に刺されていますか?
ジョナ

Jの@Jonah文字列は単なる文字の配列なので、入力は実際には2Dの文字配列です。
マイル

3

Mathematica、136 134 132バイト

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

使用法:(古い136バイトバージョンの場合、新しいバージョンは基本的に同じです)

_

注意:

  • これは時間O(m 2 n 2 max(m、n))で実行されるため、小さな入力のみを使用します。
  • これはバイナリ画像で動作するはずですが、明らかに非バイナリ画像でも動作します。(ただし、黒は同じゼロでなければなりません)
  • グラフィックは必ずしも5x5ブロックで構成されているわけではなく、ブロックを小さくすることができます。
  • @*はバージョン10の新機能です。古いバージョンでは、のTr~Composition~Flatten代わりに使用しますTr@*Flatten

これはMMAのどのバージョンですか?9.0では、それはで応答"Tr@" cannot be followed by "*Flatten".
フレンジーリー

1
@FrenzyLi 10.0。はい、@*(の省略形Composition)はバージョン10で新しく追加されました。
user20272917

1
使ってみませんRectangleCount[]か?
MCMastery

2
@MCMastery Mathematicaは多くの組み込み機能を持つことで有名ですが、これはありません。
user202729

@ user202729 lolはい、im jk
MCMastery

2

ゼリー 60 53 52 51  50 バイト

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

文字列(等しい長さの行)のリストを受け入れ、カウントを出力する完全なプログラム。

オンラインでお試しください!
...または、コピーと貼り付けの入力を簡単にするために、この完全なプログラムを使用します(行を分割するための余分なバイトを使用)
-プログラムが正しく機能するためには、行の末尾にスペースを含める必要があることに注意してください

どうやって?

Ñ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

ハスケル、180の 167 166バイト

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]

オンラインでお試しください!

4つのネストされたループを使用してすべての可能なコーナー位置を調べ、それらの間の行のすべての文字が+-(水平)または+|(垂直)で構成されているかどうかを確認します。


1

ゼリー41 39 34 33バイト

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

オンラインでお試しください!またはすべてのケースを表示します。

J での私の回答に基づく

説明

,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

ついに34バイトで競争力のある不足を感じ始めました。
マイル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.