三角形グリッド上の位置合わせ


18

六角形のグリッドは、最近2次元データに関する課題でかなり人気のあるひねりになりました。ただし、これまで同様に興味深い三角形のグリッドはほとんど無視されてきたようです。かなり単純な挑戦でそれを修正したいと思います。

まず、三角形のグリッドをどのように表現しますか?次の例を考えてみてください(今は正しい図を無視してください):

ここに画像の説明を入力してください ここに画像の説明を入力してください

セルはきちんと規則的なグリッドに落ちます(規則的なグリッドとの違いは、どのセルが隣接していると見なされるかだけです):

1234567
89abcde
fghijkl
mnopqrs

さて、右の図が示すように、三角形のグリッドには3つの主軸があります。水平軸と2つの対角軸です。

ASCIIグリッドでこれらを強調表示します。

AVAVAVA
VAabcAV
fVAiAVl
mnVAVrs

チャレンジ

三角形のグリッド(左上隅が上向きの三角形)を表す長方形の文字列が与えられます。ほとんどのセルはbe .ですが、正確に2つのセルはになります#。例:

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

2つ#がグリッドの3つの軸のいずれかに沿って配置されているかどうか(つまり、上で強調表示されている3つの方向のいずれかの単一行にあるかどうか)を決定します。この例では、答えは「いいえ」です。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

入力は、改行またはその他の便利な文字で区切られた単一の文字列、または文字列のリストです。.およびの代わりに、任意の2つの(一貫した)印刷可能なASCII文字を使用でき#ます。

ハイライトされたセルが整列している場合、出力は真実の値である必要があり、そうでない場合は偽の値である必要があります。

標準の規則が適用されます。

テストケース

真のグリッド:

.#..#.

#
#

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

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

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

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

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

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

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

偽のグリッド:

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

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

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

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

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

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

回答:


3

カタツムリ40 39バイト

\#{z|=(ul.ul.`,l~a~)(l.a3|.a|d.ea5}.,\#
\#、一致する「#」
{
  z | 、
  =(,,このアサーションが成功した場合、開始セルは「上向きの三角形」です
    ul.ul.` 、、、 1つのセルを2回、または2回、任意の回数移動します。
              、、これはul.`2、またはul.`2 +で1バイト短くなっているはずです。だが
              、、 `の解析にはバグがあります。
    l〜a〜,,範囲外を左に、次に北東に一致させて、左上のセルにいることを確認します
  )
  (l.a3 | ,,一度左に移動してから、方向を北西に設定します;または
    .a | 、、右(最初の方向)に1回移動し、方向を北東に設定します。または
    d.ea5 ,,一度下に移動してから、方向を北西または北東に設定します
}
。、、、任意の数の任意の文字に一致(現在の方向に移動)
\#、一致する「#」

2

CJam、47バイト

さて、より短い解決策があるので、自分自身を共有するのが悪くなることはもうありません。:)(主に、2Dパターンマッチング言語を持っていなくても、これは特に難しいことではないことを示すために...)

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

これはの代わりにスペースを使用し#、実際にはを使用します.

すべてのテストケースをオンラインで実行します。

私は複製が本当に嫌いですP::+Xf|P::-Xf|が、今のところそれを取り除くために何も思いつきません。

説明

自分で解決策を見つけたい場合は、読み進めないでください。

まず、退屈な部分:入力グリッドの2つのスペースの2つの座標ペアを取得します。

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.

ここで興味深いのは、これらの座標が揃っているかどうかを判断する方法です。私のコードは、3つの軸すべてを個別に計算します。

  • 横軸は簡単です。垂直座標が一致するかどうかを確認します。
  • 北東の対角線を見てみましょう。ASCIIグリッドには、各3グリッド対角に属する2つの対角線が常にあります。

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

    私たちは、合算して、現在のantidiagonalを識別することができますxし、y座標を:

    01234567
    12345678
    23456789
    

    我々はしたいと思いますので、01だけでなく、同じ対角に属している23、と45のように。つまり、対角線上のインデックスができたら、次の奇数に切り上げます。つまり、ビット単位のORを使用し1ます。(ビット単位のANDで次の偶数に切り捨てることもできます-2が、コードの方が高価です。)

  • 南東の対角線:

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

    対角線にインデックスを付与するために、我々は、減算xからy(文字として負の数を表す)座標:

    0abcdefg
    10abcdef
    210abcde
    

    この場合、and とor と同様に、andと同じ対角線に属したい0と思います。したがって、もう一度、次の奇数に切り上げます。1-1-223

そのためのコードは次のとおりです。

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.