คุณสามารถนับจำนวนสี่เหลี่ยมได้หรือไม่


21

หนึ่งในงานอดิเรกทางคณิตศาสตร์ที่ฉันโปรดปรานคือการวาดกริดสี่เหลี่ยมจากนั้นหาสี่เหลี่ยมทั้งหมดที่มองเห็นได้ในกริดนั้น ที่นี่ใช้คำถามนี้และเสี่ยงสำหรับตัวเอง!

คุณสามารถนับจำนวนสี่เหลี่ยมได้หรือไม่

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

จำนวนรวมของสี่เหลี่ยมจัตุรัสสำหรับ4 x 4 minichess boardนี้เป็นที่แน่นอน

100

คุณถูกต้องหรือไม่

คณิตศาสตร์ที่เกี่ยวข้อง: มีสี่เหลี่ยมกี่รูปบนกระดานหมากรุกขนาด 8 × 8?

ความท้าทาย

เขียนสั้นฟังก์ชั่น / โปรแกรมนับว่าจำนวนรวมของรูปสี่เหลี่ยมมองเห็นได้ในที่ไม่ใช่วงแหวนตาราง / ภาพ

ความท้าทายที่เกี่ยวข้อง: นับสี่เหลี่ยมที่ไม่ซ้ำใคร! , พบจำนวนสี่เหลี่ยมในอาร์เรย์ไบต์ 2D

รูปแบบอินพุต

ฟังก์ชั่นหรือโปรแกรมของคุณสามารถเลือกทำงานกับอินพุตข้อความหรืออินพุตกราฟิก

อินพุตแบบข้อความ

ตารางจะเป็นม. -by- n ( แถวnคอลัมน์) ตาราง ASCII ประกอบด้วยอักขระต่อไปนี้:

  • ช่องว่าง
  • - สำหรับชิ้นส่วนของส่วนของเส้นแนวนอน
  • | สำหรับชิ้นส่วนของส่วนของเส้นแนวตั้งและ
  • + สำหรับมุม

คุณสามารถแนะนำกริด ASCII นี้เป็นอินพุต / อาร์กิวเมนต์สำหรับโปรแกรม / ฟังก์ชันของคุณในรูปแบบของ

  • สตริงเดี่ยวคั่นด้วยการแบ่งบรรทัด
  • สตริงที่ไม่มีบรรทัดใหม่ แต่มีจำนวนเต็มหนึ่งหรือสองตัวที่เข้ารหัสขนาดของกริดหรือ
  • อาร์เรย์ของสตริง

หมายเหตุ: อินพุตแบบข้อความมีอย่างน้อย1แถวและอย่างน้อย1คอลัมน์

อินพุตแบบกราฟิก

อีกทางเลือกหนึ่งกริดจะถูกเข้ารหัสเป็นภาพPNGขาวดำที่มีความกว้าง5 * nพิกเซลและสูง5 * mพิกเซล แต่ละภาพประกอบด้วยบล็อก5 px * 5 pxที่สอดคล้องกับอินพุต ASCII โดย:

  • ช่องว่างจะถูกแปลงเป็นบล็อคสีขาว บล็อกเหล่านี้เรียกว่าบล็อกช่องว่าง
  • ส่วนของเส้นและมุมจะถูกแปลงเป็นบล็อกที่ไม่ใช่สีขาว จุดศูนย์กลางของบล็อกดังกล่าวเป็นสีดำ
  • แก้ไข:หากสองมุม (ในอินพุต ASCII) เชื่อมต่อกันด้วยส่วนของเส้นศูนย์บล็อกที่เกี่ยวข้อง (ในอินพุตกราฟิก) ควรเชื่อมต่อด้วยเส้นสีดำด้วย

ซึ่งหมายความว่าแต่ละบล็อกจะได้รับการแต่งตั้งจากเพียง(คลิกที่นี่เพื่อดูภาพขนาดใหญ่)โปรดละเว้นขอบเขตสีฟ้า

หมายเหตุ: ขอบเขตสีน้ำเงินเป็นเพียงภาพประกอบเท่านั้น อินพุตกราฟิกเป็นอย่างน้อย5 px และสูง5 px คุณสามารถแปลงอินพุตกราฟิกเป็นภาพขาวดำใด ๆ ซึ่งอาจเป็นรูปแบบไฟล์ภาพอื่น ๆ ) หากคุณเลือกที่จะแปลงโปรดระบุในคำตอบ ไม่มีบทลงโทษสำหรับการเปลี่ยนใจ

รูปแบบผลลัพธ์

หากคุณกำลังเขียนโปรแกรมจะต้องแสดงตัวเลขที่ไม่เป็นลบซึ่งระบุจำนวนสี่เหลี่ยมทั้งหมดในอินพุต

หากคุณกำลังเขียนฟังก์ชั่นมันก็ควรจะส่งกลับจำนวนที่ไม่ใช่เชิงลบที่ระบุจำนวนรวมของรูปสี่เหลี่ยมผืนผ้าในการป้อนข้อมูล

ตัวอย่างคดี

กรณีที่ 1,กราฟิก: กรณีที่ 1( 30 px * 30 px), ASCII: ( 6แถว, 6คอลัมน์)

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

ผลลัพธ์ที่คาดหวัง: 3

กรณีที่ 2,กราฟิก: กรณีที่ 2( 20 px * 20พิกเซล), ASCII: ( 4แถว4คอลัมน์)

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

ผลลัพธ์ที่คาดหวัง: 6

กรณีที่ 3,กราฟิก: กรณีที่ 3( 55 px * 40 px), ASCII: ( 8แถว11แถว)

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

ผลลัพธ์ที่คาดหวัง: 9

กรณี 4,กราฟิก: กรณีที่ 4( 120 px * 65 px), ASCII: ( 13แถว24 คอล )

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

ผลลัพธ์ที่คาดหวัง: 243

เคส 5,กราฟิก: กรณีที่ 5( 5 px * 5 px. ใช่, มันอยู่ที่นั่น!), ASCII: แค่เว้นวรรค

ผลลัพธ์ที่คาดหวัง: 0

กรณี 6,กราฟิก: กรณีที่ 6( 35 px * 20 px), ASCII: ( 4แถว, 7คอลัมน์)

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

ผลลัพธ์ที่คาดหวัง: 5

สมมติฐาน

เพื่อให้ชีวิตง่ายขึ้นคุณรับประกันได้ว่า:

  • โดยไม่เป็นแบบ Toroidalกริดจะไม่พันตัวในแนวนอนหรือแนวตั้ง
  • ไม่มีปลายหลวมเป็นเช่น หรือ+--- +- -+ส่วนของเส้นตรงทั้งหมดมีสองด้าน
  • สองบรรทัดที่ตรงกับ+ต้องตัดกันที่จุดนั้น
  • คุณไม่ต้องกังวลกับอินพุตที่ไม่ถูกต้อง

ใช้กฎกับช่องโหว่มาตรฐาน โปรดรักษาสี่เหลี่ยมเป็นสี่เหลี่ยม คุณสามารถลบช่องว่างต่อท้ายในแต่ละแถวของตาราง

นี่คือเพื่อให้รายการของคุณสั้นที่สุด โซลูชั่นข้อความและกราฟิกจะแข่งขันกัน

ลีดเดอร์บอร์ด


อนุญาตบิตแมปขาวดำหรือไม่
user202729

@ user202729 ใช่ หากคุณเลือกที่จะทำงานกับภาพที่ไม่ใช่ PNG โปรดระบุในคำตอบ
Frenzy Li

คือนี้การป้อนข้อมูลที่ถูกต้อง? (มุมมุมสี่เหลี่ยมผืนผ้าสัมผัสกับเส้นขอบของสี่เหลี่ยมที่มีขนาดใหญ่ขึ้น) หากเป็นเช่นนั้นให้พิจารณาเพิ่มเป็นกรณีทดสอบ
Zgarb

@Zgarb เป็นอินพุตที่ถูกต้อง ฉันจะแก้ไขโพสต์ด้วย
Frenzy Li

มีเหตุผลที่คุณใส่ผลลัพธ์ที่คาดหวังไว้ในสปอยเลอร์หรือไม่? ดูเหมือนว่าจะทำให้การยืนยันรหัสของคุณน่ารำคาญขึ้นเล็กน้อย
FryAmTheEggman

คำตอบ:


4

Grime , 31 28 ไบต์

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

ลองออนไลน์!

รับอินพุตในรูปแบบ ASCII

คำอธิบาย

ไวยากรณ์ของ Grime นั้นใกล้เคียงกับนิพจน์ทั่วไปมาก แต่ละบรรทัดจะกำหนดรูปแบบที่อาจหรืออาจจะไม่ตรงกับรูปสี่เหลี่ยมผืนผ้าของตัวละคร Tจับคู่สี่เหลี่ยมผืนผ้าที่มีแถวบนและคอลัมน์ซ้ายที่ถูกต้อง

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

แถวที่สองคือ "โปรแกรมหลัก"

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>

รับอินพุตเป็นอาร์เรย์ของสตริงที่มีความยาวเท่ากัน คำอธิบาย: สร้างชุดของนิพจน์ทั่วไปที่ตรงกับสี่เหลี่ยมของความกว้างและความสูงที่เป็นไปได้ทั้งหมด (และความกว้างและความสูงที่เป็นไปไม่ได้ แต่เป็นโค้ดกอล์ฟสำหรับคุณ) และนับจำนวนที่ตรงกันทั้งหมดที่พวกเขาสร้าง เนื่องจากมีกลุ่มการจับภาพใน regexp ให้splitผลตอบแทน2n+1สำหรับการnแข่งขันดังนั้นฉันเลื่อนไป 1 ครั้งเพื่อรับจำนวนการแข่งขันเนื่องจากจะช่วยประหยัดไบต์ในการทำให้กลุ่มไม่จับภาพ


อืมข้อมูลโค้ดไม่ทำงานสำหรับฉัน [Firefox 54.0.1 (32 บิต) หรือ Chrome 60.0.3112.90 (64 บิต) ทั้งบน Windows (64 บิต)]
Jonathan Allan

ตัวอย่างข้อมูลใช้งานไม่ได้กับ Safari ทั้ง [Mac (64 บิต)]
Mr. Xcoder

2
ดูเหมือนว่าเราจะต้องวางสิ่งต่างๆลงในพื้นที่ข้อความ จำเป็นต้องมีจำนวนอักขระต่อบรรทัด
Frenzy Li

อ่าฉันเห็นแล้วจุดที่ดี @FrenzyLi!
Jonathan Allan

4

J , 103 95 86 80 76 70 ไบต์

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

ลองออนไลน์!

รับอินพุตเป็นอาร์เรย์ของสตริงที่มีช่องว่างต่อท้าย (เพื่อให้แต่ละสตริงมีขนาดเท่ากัน) ใช้โอเปอเรเตอร์ย่อยแบบเต็ม;._3เพื่อทำซ้ำในทุกขนาดย่อยที่เป็นไปได้ที่มีขนาดใหญ่กว่า 2 x 2 และนับจำนวน subarrays ที่เป็นรูปสี่เหลี่ยมผืนผ้าที่ถูกต้อง เสร็จสิ้นทุกกรณีทดสอบเกือบจะในทันที


1
@FrenzyLi ขอบคุณ ฟังก์ชั่นได้รับอินพุตเป็นอาร์เรย์ของสตริง แต่ฉันเข้ารหัสแต่ละอาร์เรย์เป็นสตริงแบนที่เปลี่ยนเป็นอาร์เรย์ก่อนที่ฉันจะเก็บไว้ในตัวแปรแต่ละตัวเพื่อใช้เป็นอาร์กิวเมนต์สำหรับฟังก์ชัน
ไมล์

อ่า ... ขอบคุณสำหรับคำอธิบายของคุณ
Frenzy Li

@miles ดี เมื่อคุณพูดอินพุตเป็นอาร์เรย์ของสตริงแต่ละบรรทัดของอินพุต 1 ต่อยจะถูก?
โยนาห์

@Jonah Strings ใน J เป็นเพียงอาร์เรย์ของ chars ดังนั้นอินพุตจึงเป็นอาร์เรย์ 2d ที่แท้จริง
ไมล์

3

Mathematica, 136 134 132 bytes

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สูงสุด (m, n)) ดังนั้นให้ใช้อินพุตเล็ก ๆ เท่านั้น
  • แม้ว่าสิ่งนี้ควรจะทำงานกับอิมเมจไบนารี แต่ก็สามารถทำงานกับอิมเมจที่ไม่ใช่ไบนารี (แต่สีดำต้องเป็นศูนย์เหมือนกัน)
  • กราฟิกไม่จำเป็นต้องสร้างขึ้นด้วยบล็อก 5x5 บล็อกอาจมีขนาดเล็กลง
  • @*เป็นของใหม่ในรุ่น 10 ในรุ่นเก่าใช้แทนTr~Composition~FlattenTr@*Flatten

MMAรุ่นนี้มีอะไรบ้าง? ใน 9.0 มันตอบสนองด้วย"Tr@" cannot be followed by "*Flatten".
Frenzy Li

1
@FrenzyLi 10.0 ใช่@*(ย่อมาจากComposition) เป็นของใหม่ในรุ่น 10
user202729

1
ทำไมคุณไม่เพียงแค่ใช้RectangleCount[]?
MCMastery

2
@MCMastery Mathematica มีชื่อเสียงในด้านการมีอยู่มากมาย แต่ไม่ใช่อันนี้
user202729

@ user202729 lol yep, 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

สลิป , 32 29 ไบต์

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

ลองออนไลน์!

27 ไบต์ของรหัส + 2 ไบต์สำหรับnและoธง ใช้อินพุตในรูปแบบเดียวกันที่ระบุไว้ในคำถาม (เช่นบล็อกของบรรทัดที่คั่นด้วยบรรทัดใหม่)


2

Haskell, 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]

ลองออนไลน์!

ผ่านตำแหน่งมุมที่เป็นไปได้ทั้งหมดด้วยลูปซ้อนกันสี่ลูปและตรวจสอบว่าตัวอักษรทั้งหมดในบรรทัดระหว่างนั้นประกอบด้วย+-(แนวนอน) หรือ+|(แนวตั้ง)


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.