Căn trên lưới tam giác


18

Các lưới lục giác đã trở thành một vòng xoắn khá phổ biến cho những thách thức về dữ liệu 2 chiều gần đây. Tuy nhiên, dường như các lưới tam giác thú vị không kém phần lớn đã bị bỏ quên cho đến nay. Tôi muốn khắc phục điều đó với một thử thách khá đơn giản.

Đầu tiên, làm thế nào để chúng ta đại diện cho một lưới tam giác? Xem xét ví dụ sau (bỏ qua sơ đồ đúng cho bây giờ):

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Các ô nằm gọn trong một lưới thông thường (sự khác biệt so với lưới thông thường chỉ là các ô được coi là liền kề):

1234567
89abcde
fghijkl
mnopqrs

Bây giờ, như sơ đồ bên phải cho thấy, một lưới tam giác có ba trục chính: một trục ngang và hai đường chéo.

Làm nổi bật những thứ này trong lưới ASCII:

AVAVAVA
VAabcAV
fVAiAVl
mnVAVrs

Các thách thức

Bạn được cung cấp một chuỗi hình chữ nhật đại diện cho lưới hình tam giác (trong đó góc trên cùng bên trái là hình tam giác hướng lên trên). Hầu hết các ô có be ., nhưng chính xác là hai ô sẽ là #, ví dụ:

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

Xác định xem hai cái #có thẳng hàng dọc theo bất kỳ một trong ba trục của lưới hay không (nghĩa là chúng có nằm trên một hàng theo bất kỳ hướng nào trong ba hướng được tô sáng ở trên không). Trong ví dụ này, câu trả lời là "không".

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Đầu vào có thể là một chuỗi đơn được phân tách bằng nguồn cấp dữ liệu hoặc một số ký tự thuận tiện khác hoặc danh sách các chuỗi. Bạn có thể sử dụng bất kỳ hai ký tự ASCII có thể in (nhất quán) thay cho .#.

Đầu ra phải là một truthy giá trị nếu các ô được đánh dấu được liên kết và một falsy giá trị khác.

Luật tiêu chuẩn được áp dụng.

Các trường hợp thử nghiệm

Lưới thật:

.#..#.

#
#

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

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

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

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

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

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

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

Lưới Falsy:

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

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

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

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

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

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

Câu trả lời:


3

Ốc , 40 39 byte

\#{z|=(ul.ul.`,l~a~)(l.a3|.a|d.ea5}.,\#
\# ,, trận đấu '#'
{
  z | ,, Hoặc quay theo bất kỳ hướng octinilear nào, hoặc làm tất cả những thứ khác trước}
  = (,, Nếu xác nhận này thành công, ô bắt đầu là một "tam giác hướng lên"
    ul.ul.`, ,, Đi một ô lên hoặc rời hai lần, bất kỳ số lần.
              ,, Cái này đáng lẽ phải ngắn hơn một byte với ul.`2 hay ul.`2 +? nhưng
              ,, phân tích cú pháp của `là lỗi.
    l ~ a ~ ,, Kiểm tra xem chúng ta đang ở ô trên cùng bên trái bằng cách khớp các giới hạn bên trái và sau đó về phía đông bắc
  )
  (l.a3 | ,, Di chuyển sang trái một lần, sau đó đặt hướng về phía tây bắc; hoặc
    .a | ,, Di chuyển sang phải (hướng ban đầu) một lần, sau đó đặt hướng về phía đông bắc; hoặc là
    d.ea5 ,, Di chuyển xuống một lần, sau đó đặt hướng về phía tây bắc hoặc đông bắc
}
., ,, Phù hợp với bất kỳ số ký tự tùy ý (di chuyển theo hướng hiện tại)
\# ,, trận đấu '#'

2

CJam, 47 byte

Chà, bây giờ có một giải pháp ngắn hơn tôi không còn cảm thấy tồi tệ khi chia sẻ của riêng mình. :) (Chủ yếu để cho thấy rằng điều này không đặc biệt khó khăn, ngay cả khi bạn không có ngôn ngữ khớp mẫu 2D ...)

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

Điều này sử dụng không gian thay thế #và thực sự bất cứ điều gì khác cho ..

Chạy tất cả các trường hợp thử nghiệm trực tuyến.

Tôi thực sự ghét sự trùng lặp P::+Xf|P::-Xf|nhưng cho đến nay tôi vẫn chưa nghĩ ra cách nào để loại bỏ nó.

Giải trình

Đừng đọc tiếp nếu bạn muốn tìm ra giải pháp cho chính mình.

Đầu tiên, phần nhàm chán: lấy hai cặp tọa độ của hai khoảng trắng trong lưới đầu vào:

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.

Bây giờ phần thú vị là làm thế nào để xác định xem các tọa độ đó có được căn chỉnh hay không. Mã của tôi tính toán cả ba trục riêng biệt:

  • Trục ngang là tầm thường. Kiểm tra xem tọa độ dọc có khớp không.
  • Hãy nhìn vào đường chéo phía đông bắc. Trong lưới ASCII, luôn có hai antidiagonals thuộc về mỗi đường chéo ba lưới:

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

    Chúng ta có thể xác định các antidia Cross hiện tại bằng cách thêm xytọa độ:

    01234567
    12345678
    23456789
    

    Vì vậy, chúng tôi muốn 01thuộc về đường chéo tương tự, cũng như 23, và 45và vân vân. Điều đó có nghĩa là, một khi chúng ta có chỉ số chống đường chéo, chúng ta muốn làm tròn đến số lẻ tiếp theo. Nói cách khác, chúng ta lấy bitwise OR với 1. (Chúng ta cũng có thể làm tròn số chẵn tiếp theo theo bit và với -2mã đắt hơn.)

  • Bây giờ các đường chéo phía đông nam:

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

    Để cung cấp cho đường chéo một chỉ số, chúng tôi trừ các xtừ y(số âm thể hiện như chữ cái) phối hợp:

    0abcdefg
    10abcdef
    210abcde
    

    Trong trường hợp này, chúng tôi muốn 01thuộc cùng một đường chéo, cũng như -1, và -2, 23. Vì vậy, một lần nữa, chúng tôi muốn làm tròn số lẻ tiếp theo.

Đây là mã cho điều đó:

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.
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.