Bạn có thể đếm số lượng hình chữ nhật?


21

Một trong những trò tiêu khiển toán học yêu thích của tôi là vẽ một lưới hình chữ nhật, sau đó tìm tất cả các hình chữ nhật có thể nhìn thấy trong lưới đó. Ở đây, đưa câu hỏi này, và mạo hiểm cho chính mình!

Bạn có thể đếm số lượng hình chữ nhật?

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

Tổng số hình chữ nhật này 4 x 4 bảng minichess là chính xác

100

Bạn đã đúng chưa?

Toán học liên quan: Có bao nhiêu hình chữ nhật trên một bàn cờ 8 × 8?

Các thách thức

Viết hàm / chương trình ngắn nhất đếm tổng số hình chữ nhật có thể nhìn thấy trên lưới / hình ảnh không hình xuyến .

Những thách thức liên quan: Đếm các hình chữ nhật độc đáo! , Tìm số lượng hình chữ nhật trong một mảng byte 2D .

Định dạng đầu vào

Chức năng hoặc chương trình của bạn có thể chọn làm việc với đầu vào dựa trên văn bản hoặc đầu vào đồ họa.

Nhập liệu dựa trên văn bản

Lưới sẽ là một lưới ASCII m -by- n ( m hàng, n cột) bao gồm các ký tự sau:

  • không gian,
  • - cho các phần của một đoạn đường ngang,
  • | cho các phần của một đoạn thẳng đứng và
  • + cho các góc.

Bạn có thể giới thiệu lưới ASCII này làm đầu vào / đối số cho chương trình / hàm của mình dưới dạng

  • một chuỗi được giới hạn bởi các ngắt dòng,
  • một chuỗi không có dòng mới nhưng với một hoặc hai số nguyên mã hóa kích thước của lưới hoặc
  • một mảng các chuỗi.

Lưu ý: Đầu vào dựa trên văn bản chứa ít nhất 1 hàng và ít nhất 1 cột.

Đầu vào đồ họa

Ngoài ra, các lưới được mã hóa dưới dạng hình ảnh PNG đen trắng rộng 5 * n pixel và cao 5 * m pixel. Mỗi hình ảnh bao gồm các khối 5 px * 5 px tương ứng với đầu vào ASCII theo:

  • Không gian được chuyển đổi thành các khối màu trắng. Các khối này được gọi là các khối khoảng trắng .
  • Các đoạn và góc được chuyển đổi thành các khối không phải khoảng trắng. Pixel trung tâm của các khối như vậy là màu đen.
  • Chỉnh sửa: Nếu hai góc (trong đầu vào ASCII) được kết nối bởi một đoạn đường, thì các tâm khối tương ứng (trong đầu vào đồ họa) cũng phải được kết nối bằng một đường màu đen.

Điều này có nghĩa là mỗi khối chỉ có thể được chọn từ Hãy bỏ qua các ranh giới màu xanh. (Bấm vào đây để hình ảnh lớn hơn) .

Lưu ý: Các ranh giới màu xanh chỉ dành cho mục đích minh họa. Đầu vào đồ họa rộng tối thiểu 5 px và cao 5 px. Bạn có thể chuyển đổi đầu vào đồ họa thành bất kỳ hình ảnh đơn sắc nào, có khả năng ở các định dạng tệp hình ảnh khác). Nếu bạn chọn chuyển đổi, vui lòng ghi rõ trong câu trả lời. Không có hình phạt để chuyển đổi.

Định dạng đầu ra

Nếu bạn đang viết một chương trình, nó phải hiển thị một số không âm cho biết tổng số hình chữ nhật trong đầu vào.

Nếu bạn đang viết một hàm, nó cũng sẽ trả về một số không âm cho biết tổng số hình chữ nhật trong đầu vào.

Ví dụ trường hợp

Trường hợp 1, Đồ họa: Trường hợp 1( 30 px * 30 px), ASCII: ( 6 hàng, 6 cols)

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

Sản lượng dự kiến: 3

Trường hợp 2, Đồ họa: Trường hợp 2( 20 px * 20 px), ASCII: ( 4 hàng, 4 cols)

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

Sản lượng dự kiến: 6

Trường hợp 3, Đồ họa: Trường hợp 3( 55 px * 40 px), ASCII: ( 8 hàng, 11 cols)

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

Sản lượng dự kiến: 9

Trường hợp 4, Đồ họa: Trường hợp 4( 120 px * 65 px), ASCII: ( 13 hàng, 24 cols)

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

Sản lượng dự kiến: 243

Trường hợp 5, đồ họa: Trường hợp 5( 5 px * 5 . Px Vâng, đó có!), ASCII: Chỉ cần một không gian duy nhất.

Sản lượng dự kiến: 0

Trường hợp 6, Đồ họa: Trường hợp 6( 35 px * 20 px), ASCII: ( 4 hàng, 7 cols)

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

Sản lượng dự kiến: 5

Giả định

Để làm cho cuộc sống dễ dàng hơn, bạn được đảm bảo rằng:

  • Bằng cách không hình xuyến , lưới không bao bọc theo chiều ngang hoặc chiều dọc.
  • Không có kết thúc lỏng lẻo, ví dụ +--- hoặc +- -+. Tất cả các phân khúc dòng có hai đầu.
  • Hai đường gặp nhau +phải giao nhau tại điểm đó.
  • Bạn không phải lo lắng về đầu vào không hợp lệ.

Quy tắc chống lại sơ hở tiêu chuẩn áp dụng. Hãy coi hình vuông là hình chữ nhật. Tùy chọn, bạn có thể loại bỏ các khoảng trắng ở mỗi hàng của lưới.

Đây là , vì vậy hãy làm cho mục nhập của bạn càng ngắn càng tốt. Các giải pháp dựa trên văn bản và đồ họa sẽ cạnh tranh với nhau.

Bảng xếp hạng


Là bitmap đơn sắc được phép?
dùng202729

@ user202729 Có. Nếu bạn chọn làm việc với hình ảnh không phải là PNG, vui lòng chỉ định điều đó trong câu trả lời.
Frenzy Li

này một đầu vào hợp lệ? (Góc hình chữ nhật chạm đường viền của hình chữ nhật lớn hơn.) Nếu vậy, hãy xem xét thêm nó làm trường hợp thử nghiệm.
Zgarb

@Zgarb Đó là đầu vào hợp lệ. Tôi cũng sẽ chỉnh sửa bài viết.
Frenzy Li

Có một lý do bạn đặt các đầu ra dự kiến ​​trong spoilers? Có vẻ như nó chỉ làm cho việc xác minh mã của bạn hơi khó chịu hơn.
FryAmTheEggman

Câu trả lời:


4

Grime , 31 28 byte

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

Hãy thử trực tuyến!

Đưa đầu vào ở định dạng ASCII.

Giải trình

Cú pháp của Grime rất gần với các biểu thức thông thường. Mỗi dòng xác định một mẫu có thể hoặc không khớp với hình chữ nhật của các ký tự. Tkhớp với một hình chữ nhật có hàng trên cùng và cột bên trái trông hợp lệ.

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

Hàng thứ hai là "chương trình chính".

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>

Lấy đầu vào là một chuỗi các chuỗi có độ dài bằng nhau. Giải thích: Tạo một loạt các biểu thức chính quy khớp với hình chữ nhật của tất cả các chiều rộng và chiều cao có thể (và một số chiều rộng và chiều cao không thể, nhưng đó là mã golf cho bạn) và đếm xem có bao nhiêu trận đấu mà chúng tạo ra. Bởi vì có một nhóm bắt giữ trong regrec, splittrả về 2n+1các nkết quả trùng khớp, vì vậy tôi phải thay đổi 1 để có được số lượng các trận đấu, vì điều đó giúp tiết kiệm một byte qua việc làm cho nhóm không bị bắt.


Hmm, đoạn mã không hoạt động đối với tôi [Firefox 54.0.1 (32 bit) hoặc Chrome 60.0.3112.90 (64 bit) cả trên Windows (64 bit)].
Jonathan Allan

Đoạn mã Nó không hoạt động trên Safari hoặc [Mac (64 bit)].
Ông Xcoder

2
Có vẻ như chúng ta phải dán các thứ vào vùng văn bản. Cùng một số ký tự trên mỗi dòng là bắt buộc.
Frenzy Li

À tôi hiểu rồi, điểm tốt @FrenzyLi!
Jonathan Allan

4

J , 103 95 86 80 76 70 byte

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

Hãy thử trực tuyến!

Đưa đầu vào dưới dạng một chuỗi các chuỗi có dấu cách (để mỗi chuỗi có cùng kích thước). Sử dụng toán tử subarray đầy đủ;._3 để lặp lại trên mọi kích thước subarray có thể lớn hơn 2 x 2 và đếm các tập hợp con là hình chữ nhật hợp lệ. Hoàn thành tất cả các trường hợp thử nghiệm gần như ngay lập tức.


1
@FrenzyLi Cảm ơn. Hàm đang nhận đầu vào dưới dạng một chuỗi các chuỗi, nhưng tôi đã mã hóa từng mảng dưới dạng một chuỗi phẳng được định hình lại thành một mảng trước khi tôi lưu trữ chúng trong mỗi biến để làm đối số cho hàm.
dặm

À ... Cảm ơn bạn đã giải thích.
Frenzy Li

@miles đẹp. Khi bạn nói đầu vào là mảng của chuỗi, mỗi dòng của đầu vào 1 sting?
Giô-na

@Jonah Chuỗi trong J chỉ là mảng ký tự, vì vậy đầu vào thực sự là một mảng 2 ký tự.
dặm

3

Toán học, 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}]&

Cách sử dụng: (đối với phiên bản 136 byte cũ, nhưng phiên bản mới về cơ bản là giống hệt nhau)

_

Chú thích:

  • Điều này chạy trong thời gian O (m 2 n 2 max (m, n)), vì vậy chỉ sử dụng đầu vào nhỏ.
  • Mặc dù điều này được cho là hoạt động với hình ảnh nhị phân, nhưng rõ ràng nó có thể hoạt động với hình ảnh không nhị phân. (nhưng màu đen phải bằng 0)
  • Đồ họa không nhất thiết phải được xây dựng với các khối 5x5, các khối có thể nhỏ hơn.
  • @*là phiên bản mới trong phiên bản 10. Trong các phiên bản cũ hơn, hãy sử dụng Tr~Composition~Flattenthay vì Tr@*Flatten.

Phiên bản MMA này thuộc phiên bản nào ? Trong 9.0, nó trả lời với"Tr@" cannot be followed by "*Flatten".
Frenzy Li

1
@FrenzyLi 10.0. Có, @*(viết tắt cho Composition) là mới trong phiên bản 10.
user202729

1
Tại sao bạn không sử dụng RectangleCount[]?
MCM Abbey

2
@MCM Abbey Mathematica nổi tiếng vì có rất nhiều tích hợp, nhưng không phải cái này.
dùng202729

@ user202729 lol yep, im jk
MCM Abbey

2

Thạch ,  60 53 52 51  50 byte

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

Một chương trình đầy đủ chấp nhận một danh sách các chuỗi (các hàng có độ dài bằng nhau) và in số đếm.

Hãy thử trực tuyến!
... hoặc để dễ sao chép và dán đầu vào, hãy sử dụngchương trình đầy đủ này (có thêm một byte để phân chia dòng)
- lưu ý rằng các dòng được yêu cầu để chứa các khoảng trắng theo sau để chương trình hoạt động chính xác.

Làm sao?

Ñ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

Trượt , 32 29 byte

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

Hãy thử trực tuyến!

27 byte mã + 2 byte cho nocờ. Đưa đầu vào theo cùng định dạng được cung cấp trong câu hỏi (nghĩa là khối dòng được phân tách bằng dòng mới).


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]

Hãy thử trực tuyến!

Đi qua tất cả các vị trí góc có thể với bốn vòng lặp lồng nhau và kiểm tra xem tất cả các ký tự trên các đường giữa chúng bao gồm +-(ngang) hay +|(dọc).


1

Thạch , 41 39 34 33 byte

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

Hãy thử trực tuyến! hoặc là Xem tất cả các trường hợp.

Dựa trên câu trả lời của tôi trong J.

Giải trình

,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

Bây giờ cuối cùng nó bắt đầu cảm thấy cạnh tranh ngắn ở mức 34 byte.
dặm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.