大砲はどこに行くことができますか?


9

前書き

中国のチェスとも呼ばれるxiangqiのゲームは、中国、ベトナム、台湾、その他の東アジア諸国で人気のあるチェスのようなゲームです。xiangqiの両側の色は赤と黒です。シャンチーには、将軍(G)、顧問(A)、象(E)、馬(H)、戦車(R)、大砲(C)、兵士(S)の7つのピースがあります。この課題では、大文字の部分は赤、小文字の部分は黒と見なされます。これらの駒のほとんどは、西洋のチェスとほぼ同等ですが、完全にユニークな駒が1つあります。それは大砲です。

大砲のチェスでルークまたはシャンチーで戦車(xまたはY軸上の任意の数のスペースを移動させる)ような動きが、この方法を攻撃できません。代わりに、X軸またはY軸に沿って(移動と同じように)任意の色(フレンドまたは敵)の1つの部分をジャンプして攻撃し、反対の色の部分に着陸してキャプチャします。すべてのチェスとxiangqiの駒と同様に、大砲は自分の色の駒をキャプチャできません。

たとえば、次の図では、大砲(C)が移動できるスペースはでマークされ*、ジャンプしてキャプチャできるスペースはでマークされてXいます。

....X....
.........
.........
....h....
....*....
****C**aX
....E....
....X....
....g....
....R....

チャレンジ

xiangqiボードとそのボード上の大砲の座標を入力として与えられ、大砲が移動またはジャンプできる座標のリストを出力するプログラムまたは関数を記述します。

すべてのI / Oの形式は柔軟です。

xiangqiボードで使用できる形式には、改行で区切られた文字列、文字列のリスト、またはにないその他の区切り文字を含む文字列が含まれaceghrsACEGHRS.ます。ボードは常にxiangqiボードのサイズである9x10であると想定できます。

ボード自体の内容は、ボード.上の空のポイントを表すいくつかのピリオド()と、ピースを表す文字で構成されます。ピースから文字へのマッピングは次のとおりです。

A -> advisor
C -> cannon
E -> elephant
G -> general
H -> horse
R -> chariot
S -> soldier

大文字は赤い部分を表し、小文字は黒い部分を表します。ここにリストされていない(つまりにないaceghrsACEGHRS.)文字はボードに表示されません。

入力座標の形式は柔軟で、出力座標の形式と一致する必要はありません。たとえば、2つの整数要素、2つのタプル、任意の区切り記号付きの2つの数値、または2つの文字のリストにすることができます。また、0インデックスまたは1インデックスのいずれかになります。ボード上の座標は常に大砲(Cまたはc)に解決されると想定できます。

大砲がジャンプして移動できる座標は、出力の同じリストに表示される必要があります。2つの間の区別は必要ありません。個々の出力座標に使用できるフォーマットは、入力座標のフォーマットと同じです。座標は、改行で区切られたり、リストとして出力されたり、その他の表現になります。特定の順序は必要ありません。順序は決定論的である必要さえありません。

大砲の同じ色(ケース)へのジャンプは無効であり、出力に表示されないことに注意してください。

テストケース

すべてのテストケースがxiangqiの可能性があるわけではないことに注意してください。

Input board
Input coordinate (0-indexed)
List of output coordinates

.........
.........
.........
.........
.........
....C....
.........
.........
.........
.........
(4, 5)
[(0, 5), (1, 5), (2, 5), (3, 5), (5, 5), (6, 5), (7, 5), (8, 5), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 6), (4, 7), (4, 8), (4, 9)]

.........
.....G...
.........
.........
.....e...
.........
.........
h..R.c..S
.....a...   
.........
(5, 7)
[(4, 7), (6, 7), (7, 7), (5, 6), (5, 5), (5, 1)]

..s......
..A...e..
.........
EACCcsh.H
..r......
.....S...
......s..  
....C....
..g......
(2, 3)
[(2, 0), (2, 2), (4, 3), (2, 9)]

rheagaehr
.........
.c.....c.
s.s.s.s.s
.........
.........
S.S.S.S.S
.C.....C.
.........
RHEAGAEHR
(7, 7)
[(2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (8, 7), (7, 0), (7, 3), (7, 4), (7, 5), (7, 6), (7, 8)]

得点

これはなので、最も短い回答(バイト単位)が優先されます。幸せなゴルフ!


3
Xiangqiの場合は+1。中国の会社で働いていたときに同僚から学ぶ機会があったのは素晴らしいゲームです。一般的な感触はちょうどチェスをプレイするようなものです(防衛のための鋭い目を離さないが、積極的にプレー)が、戦術は異なっている(初期のチェスでルークを引き出すために、それの悪いのに対し、早期の戦車を引き出すために、それの良い。)en.wikipedia .org / wiki / Xiangqi
Level River St

@LevelRiverStは、チェスほど技術的ではなく、戦略的な感覚が異なるビデオゲームのように感じます。私はそれが好きです!
noɥʇʎԀʎzɐɹƆ

王がいないように見えるかもしれませんが、可能な以上のピースがあるのでしょうか?
l4m2

回答:


1

ピップ、112 + 1 = 113バイト

入力をコマンドライン引数として受け取ります。2つの座標の後に、ボードの10行が続きます。座標は0ベースです。のような座標を出力し67 77、同じ行のリストと同じ列のリストの間に改行を入れます。-sフラグ用に1バイトが追加されました。

g@>:2P(f:{Ya@bQ'C?X^z;X^AZa@b:'@aR`\.*@\.*`{aR'.s}Ry.`\.*\w *@`s._@>1R`@ *\w\.*`.y_@<v.s@*s}g@ba).ba.(f;J(Zga)b)

オンラインでお試しください!

ややゴルフされていないバージョンの説明

g@>:2
f:{
 Y a@bQ'C ? `[a-z]` `[A-Z]`
 a@b:'@
 aR:`\.*@\.*` {aR'.s}
 aR:y.`\.*\w *@` s._@>1
 aR:`@ *\w\.*`.y _@<v.s
 a@*s
}
P (f g@b a).b
a.(f; J(Zg)@a b)

デフォルトでは、Pipはコマンドライン引数をリストに読み込みますg。また、変数の最初の5つの引数に格納aスルーをe。最初の2つの引数、aおよびbは、大砲の座標です。gボードの行が後に続く座標を含みます。でちょうどボードを得るためにg、我々はにインデックス2以降とアサインバックからそれをスライスgg@>:2)。

次に、関数を定義しますf。この関数は2つの引数を取ります。ボードの行または列を表す文字列と、その文字列内の大砲のインデックスです。これらの引数は、関数内でaおよびとして使用できますb。関数は、大砲が移動またはキャプチャできるスポットを表すすべてのインデックスのリストを返します。

まず、我々かどうかのテストa@bですCc。の場合C[a-z]取得できる部分に正規表現を一致させる必要があります。の場合c、正規表現は[A-Z]です。(ゴルフされたコードは、小文字と大文字のアルファベットの組み込み変数からこれらの正規表現を生成します。)Y適切な正規表現をy変数に追加します。

文字列内の大砲の文字をに変更します@(同じ行/列の他の大砲と区別するため)。

次に、一連の正規表現の置換が行われます。これは、大砲がスペースキャラクターに移動できるすべての場所を変更します。任意の数のピリオドで囲まれた最初の正規表現の\.*@\.*一致@。これらはすべて、大砲が移動できる空のスポットを表します。置換では、コールバック関数{aR'.s}を使用して、すべてのピリオドをスペースに変更します。

次の正規表現は、大砲がキャプチャできる部分と一致します:[a-z]または[A-Z]y前にヤンクされたものに応じて)、その後に\.*\w *@(ピリオド、文字、スペース、および@)が続きます。これはh..R @(大砲がであった場合C)のような文字列に一致します。コールバック関数s._@>1は、最初の文字を切り取って、スペースを付加します。

3番目の正規表現も同様ですが、大砲の前ではなく、大砲の後にあるキャプチャ可能な部分と一致します。

最後に、関数はを返しa@*s、find-all演算子を使用して、すべてのスペースのインデックスのリストを取得します。

f次に、大砲の行と大砲の列を呼び出します。行の文字列はg@bで、文字列内の大砲のインデックスはaです。この関数は列番号のリストを返し、それぞれに行番号を追加しますb。リストが印刷されるとき、-sフラグは座標ペアの間にスペースを置きます。

列を取得するには、我々が使用Z転置にIP演算子をg選択し、インデックスa、およびJ文字列に文字の結果リストOIN。この文字列内の大砲のインデックスはbです。関数は行番号のリストを返しますa。各行番号の前に列番号を付加します。このリストはプログラムの最後の式であり、自動印刷されます。

(誰かが疑問に思っている場合のために、式セパレーター;Jバイナリではなく単項演算子として解析することを強制するためにそこにあります。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.