三角网格上的对齐


18

六边形网格最近已成为应对二维数据挑战的一种相当流行的方法。但是,到目前为止,似乎同样忽略了同样有趣的三角形网格。我想通过一个非常简单的挑战来纠正这一问题。

首先,我们如何表示三角形网格?考虑以下示例(暂时忽略正确的图表):

在此处输入图片说明 在此处输入图片说明

单元整齐地落在常规网格上(与常规网格的区别仅在于哪些单元被视为相邻单元):

1234567
89abcde
fghijkl
mnopqrs

现在,如右图所示,三角形网格具有三个主轴:水平轴和两个对角轴。

在ASCII网格中突出显示这些内容:

AVAVAVA
VAabcAV
fVAiAVl
mnVAVrs

挑战

您将获得一个代表三角形网格的矩形字符串(其中左上角是一个向上的三角形)。大部分带有be的单元格.,但只有两个单元格是#,例如:

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

确定两者#是否沿网格的三个轴中的任何一个对齐(即,它们是否沿上面突出显示的三个方向中的任何一个方向位于一行上)。对于此示例,答案为“否”。

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行参数或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

输入可以是由换行符或其他方便字符分隔的单个字符串,也可以是字符串列表。您可以使用任意两个(一致的)可打印ASCII字符代替.#

输出应该是一个truthy如果突出显示的细胞对准值和falsy否则值。

适用标准规则。

测试用例

真实网格:

.#..#.

#
#

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

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

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

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

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

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

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

伪造的网格:

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

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

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

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

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

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

Answers:


3

蜗牛40 39字节

\#{z|=(ul.ul.`,l~a~)(l.a3|.a|d.ea5}.,\#
\# ,, 比赛 '#'
{
  z | ,,要么沿任何八度方向旋转,要么在}之前执行所有其他操作
  =(,,如果此断言成功,则起始单元格为“向上指向三角形”
    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网格中,总是存在两个反对角线,它们分别属于每个三网格对角线:

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

    我们可以通过将xy坐标相加来确定当前的对角线:

    01234567
    12345678
    23456789
    

    因此,我们会想01属于同一个对角线,以及23,和45等。这就是说,一旦有了反对角线索引,我们就需要四舍五入到下一个奇数。换句话说,我们对进行按位“或”运算1。(我们也可以按位AND向下舍入到下一个偶数,-2但这在代码中更昂贵。)

  • 现在东南对角线:

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

    为了给对角线的指数,我们减去xy坐标(代表负数字母):

    0abcdefg
    10abcdef
    210abcde
    

    在这种情况下,我们希望01属于同一对角线,以及-1-2,或23。再一次,我们要四舍五入到下一个奇数。

这是该代码:

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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.