การจัดแนวบนกริดแบบสามเหลี่ยม


18

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

ก่อนอื่นเราจะแสดงตารางสามเหลี่ยมได้อย่างไร ลองพิจารณาตัวอย่างต่อไปนี้ (ไม่สนใจไดอะแกรมที่เหมาะสม)

ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

เซลล์ตกลงอย่างเรียบร้อยบนกริดปกติ (ความแตกต่างของกริดปกติเป็นเพียงเซลล์ที่ถูกพิจารณาว่าติดกัน):

1234567
89abcde
fghijkl
mnopqrs

ในขณะที่แผนภาพด้านขวาแสดงให้เห็นว่าตารางสามเหลี่ยมมีสามแกนหลัก ได้แก่ แนวนอนและแนวทแยงสองเส้น

ไฮไลต์สิ่งเหล่านี้ในตาราง ASCII:

AVAVAVA
VAabcAV
fVAiAVl
mnVAVrs

ความท้าทาย

คุณได้รับสตริงรูปสี่เหลี่ยมผืนผ้าที่แสดงถึงรูปสามเหลี่ยม (ซึ่งมุมบนซ้ายเป็นรูปสามเหลี่ยมชี้ขึ้น) เซลล์ส่วนใหญ่ที่มีค่าเป็น.แต่จะมีเซลล์สองเซลล์#เช่น:

....#
.#...
.....

ตรวจสอบว่าทั้งสอง#ถูกจัดตำแหน่งตามแนวแกนใด ๆ ในสามแกนของตารางหรือไม่ (เช่นว่าพวกเขานอนบนแถวเดียวในทิศทางใดก็ได้ที่เน้นด้านบน) สำหรับตัวอย่างนี้คำตอบคือ "ไม่"

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

อินพุตอาจเป็นสตริงเดี่ยวที่คั่นด้วย linefeeds หรืออักขระที่สะดวกอื่น ๆ หรือรายการสตริง คุณอาจจะใช้สอง (สอดคล้อง) ตัวอักขระ ASCII ในสถานที่และ.#

เอาท์พุทควรจะเป็นtruthyค่าถ้าเซลล์ที่ไฮไลต์มีความสอดคล้องและfalsyคุ้มค่าเป็นอย่างอื่น

ใช้กฎมาตรฐานของ

กรณีทดสอบ

Truthy grids:

.#..#.

#
#

...........
...#.......
...........
...........
...........
.......#...
...........

...........
.......#...
...........
...........
...........
...#.......
...........

.#.........
...........
...........
...........
...........
.......#...
...........

...........
...#.......
...........
...........
...........
...........
.......#...

.........#.
...........
...........
...........
...........
...#.......
...........

...........
.......#...
...........
...........
...........
...........
...#.......

...........
.#.....#...
...........
...........
...........

กริดที่เป็นเท็จ:

#.....
.....#

.....#
#.....

...#.......
...........
...........
...........
...........
.......#...
...........

...........
...#.......
...........
...........
...........
...........
.........#.

.......#...
...........
...........
...........
...........
...#.......
...........

...........
.......#...
...........
...........
...........
...........
.#.........

คำตอบ:


3

หอยทาก , 40 39 ไบต์

\#{z|=(ul.ul.`,l~a~)(l.a3|.a|d.ea5}.,\#
\# ,, การจับคู่ '#'
{
  z | ,, ไม่ว่าจะหันไปทางทิศทาง octinilear หรือทำสิ่งอื่นทั้งหมดก่อน}
  = (,, หากการยืนยันนี้สำเร็จเซลล์เริ่มต้นคือ "สามเหลี่ยมชี้ขึ้น"
    ul.ul.`, ,, ไปหนึ่งเซลล์ขึ้นหรือออกสองครั้งจำนวนครั้งใด ๆ
              ,, สิ่งนี้ควรสั้นลงหนึ่งไบต์ด้วย ul.`2 หรือ ul.`2 +? แต่
              ,, การแยกวิเคราะห์ `เป็นบั๊กกี้
    l ~ a ~ ,, ตรวจสอบว่าเราอยู่ในเซลล์ด้านบนซ้ายโดยจับคู่นอกขอบเขตกับด้านซ้ายและตะวันออกเฉียงเหนือ
  )
  (l.a3 | ,, เลื่อนไปทางซ้ายหนึ่งครั้งจากนั้นตั้งค่าทิศทางเป็นทิศตะวันตกเฉียงเหนือหรือ
    .a | ,, เลื่อนไปทางขวา (ทิศทางเริ่มต้น) หนึ่งครั้งจากนั้นตั้งค่าทิศทางเป็นตะวันออกเฉียงเหนือ หรือ
    d.ea5 ,, เลื่อนลงหนึ่งครั้งจากนั้นกำหนดทิศทางเป็นทิศตะวันตกเฉียงเหนือหรือตะวันออกเฉียงเหนือ
}
.,, จับคู่ตัวอักษรใด ๆ ตามจำนวนที่กำหนด (เคลื่อนที่ในทิศทางปัจจุบัน)
\# ,, การจับคู่ '#'

2

CJam, 47 ไบต์

ตอนนี้มีวิธีแก้ปัญหาที่สั้นกว่าฉันไม่รู้สึกไม่ดีที่จะแบ่งปันตัวเองอีกต่อไป :) (ส่วนใหญ่จะแสดงว่านี่ไม่ใช่เรื่องยากโดยเฉพาะแม้ว่าคุณจะไม่มีภาษาที่ตรงกับรูปแบบ 2D ... )

qN%:eeee::f+:~{S&},2f<:P0f=P::+Xf|P::-Xf|]::=:|

นี่ใช้ช่องว่างแทน#และมีประโยชน์อย่างอื่น.และสิ่งอื่นจริงๆ

เรียกใช้กรณีทดสอบทั้งหมดทางออนไลน์

ฉันเกลียดการลอกเลียนแบบจริงๆ P::+Xf|P::-Xf|แต่จนถึงตอนนี้ฉันยังไม่ได้ทำอะไรเลยเพื่อกำจัดมัน

คำอธิบาย

อย่าอ่านต่อไปหากคุณต้องการหาวิธีแก้ปัญหาด้วยตัวคุณเอง

ขั้นแรกให้ส่วนที่น่าเบื่อ: รับสองคู่พิกัดของสองช่องว่างในตารางอินพุต:

qN%   e# Read input and split into lines.
:ee   e# Enumerate the characters in each line. I.e. turn each character 'x into a pair
      e# [N 'x] where N is its horizontal 0-based index.
ee    e# Enumerate the lines themselves, turning each line [...] into [M [...]] where M
      e# is its vertical 0-based index.
::f+  e# This distributes the vertical index over the individual lines, by prepending it
      e# to each pair in that line. So now we've got a 2-D array, where each character 'x
      e# has been turned into [M N 'x].
:~    e# Flatten the outermost dimension, so that we have a flat list of characters with
      e# their coordinates.
{S&}, e# Filter only those lists that contain a space.
2f<   e# Truncate the two results to only their first two elements.
:P    e# Store the result in P.

ตอนนี้ส่วนที่น่าสนใจคือวิธีการตรวจสอบว่าพิกัดเหล่านั้นอยู่ในแนวเดียวกันหรือไม่ รหัสของฉันคำนวณทั้งสามแกนแยกกัน:

  • แกนแนวนอนนั้นเล็กน้อย ตรวจสอบว่าพิกัดแนวตั้งตรงกันหรือไม่
  • ลองดูที่เส้นทแยงมุมตะวันออกเฉียงเหนือ ในตาราง ASCII จะมี antidiagonals สองอันที่เป็นของเส้นทแยงมุมสามตารางแต่ละเส้นเสมอ:

    ....AV..
    ...AV...
    ..AV....
    

    เราสามารถระบุ antidiagonal ปัจจุบันโดยการเพิ่มxและyพิกัด:

    01234567
    12345678
    23456789
    

    ดังนั้นเราจึงต้องการ0และ1จะเป็นเส้นทแยงมุมเดียวกันเช่นเดียวกับ2และ3และ4และ5และอื่น ๆ นั่นหมายความว่าเมื่อเรามีดัชนีต้านเส้นทแยงมุมแล้วเราต้องการปัดเศษขึ้นเป็นเลขคี่ถัดไป ในคำอื่น ๆ ที่เราใช้เวลา OR 1ระดับบิตด้วย (เราสามารถปัดเศษให้เป็นเลขคู่ถัดไปได้ด้วยค่าบิตและด้วย-2แต่นั่นแพงกว่าในโค้ด)

  • ตอนนี้เส้นทแยงมุมทิศตะวันออกเฉียงใต้:

    .VA.....
    ..VA....
    ...VA...
    

    เพื่อที่จะให้เส้นทแยงมุมดัชนีเราลบxจากyการประสานงาน (แทนตัวเลขที่ติดลบเป็นตัวอักษร):

    0abcdefg
    10abcdef
    210abcde
    

    ในกรณีนี้เราต้องการ0และ1จะเป็นเส้นทแยงมุมเดียวกันเช่นเดียวกับ-1และ-2หรือและ2 3ดังนั้นอีกครั้งเราต้องการปัดเศษให้เป็นเลขคี่ถัดไป

นี่คือรหัสสำหรับที่:

0f=  e# The coordinates are still on the stack. Replace each with its vertical coordinate
     e# to check for the horizontal axis.
P    e# Push the coordinates again.
::+  e# Sum each pair to get an anti-diagonal index.
Xf|  e# OR each index with 1 to round up to the next odd number.
P    e# Push the coordinates again.
::-  e# In each pair, subtract the horizontal coordinate from the vertical, to
     e# get a diagonal index.
Xf|  e# OR each index with 1.
]    e# Wrap all three index pairs in an array.
::=  e# Check equality for each pair.
:|   e# Fold bitwise OR over the results to check if at least one pair of indices
     e# was equal.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.