六角形グリッド上の動き


15

六角形のグリッド上の動きを表す一連の文字の入力が与えられた場合、「ポインター」の最終座標を出力します。

六角形には次のように番号が付けられます(すべての奇数列が少し下にシフトした長方形のグリッドを想像してください):

  _____         _____         _____         _____
 /     \       /     \       /     \       /     \
/ -3,-2 \_____/ -1,-2 \_____/  1,-2 \_____/  3,-2 \
\       /     \       /     \       /     \       /
 \_____/ -2,-1 \_____/  0,-1 \_____/  2,-1 \_____/
 /     \       /     \       /     \       /     \
/ -3,-1 \_____/ -1,-1 \_____/  1,-1 \_____/  3,-1 \
\       /     \       /     \       /     \       /
 \_____/ -2,0  \_____/  0,0  \_____/  2,0  \_____/
 /     \       /     \       /     \       /     \
/ -3,0  \_____/ -1,0  \_____/  1,0  \_____/  3,0  \
\       /     \       /     \       /     \       /
 \_____/ -2,1  \_____/  0,1  \_____/  2,1  \_____/
 /     \       /     \       /     \       /     \
/ -3,1  \_____/ -1,1  \_____/  1,1  \_____/  3,1  \
\       /     \       /     \       /     \       /
 \_____/       \_____/       \_____/       \_____/

ポインターは(0、0)から始まります。

サポートする必要がある指示は次のとおりです。

  • q:左上に移動
  • w:上に移動
  • e:右上に移動
  • a:左下に移動
  • s: 下に移動
  • d:右下に移動
  • r:グリッドを時計回りに回転
  • R:グリッドを反時計回りに回転

回転コマンドは、ポインターを同じ座標に保ちながらグリッド全体を回転します。(なぜqweasdですか?QWERTYキーボードの指示とうまく一致します。)

これを視覚化するために、ポインタが中央から始まると仮定した場合の移動コマンドの動作を次に示します。

         _____
        /     \
  _____/   w   \_____
 /     \       /     \
/   q   \_____/   e   \
\       /     \       /
 \_____/       \_____/
 /     \       /     \
/   a   \_____/   d   \
\       /     \       /
 \_____/   s   \_____/
       \       /
        \_____/

時計回りに回転(r)した後、コマンドは再マッピングされます(16進グリッド全体を回転させながら、「w」を上げたままにするなど、次と同等です):

         _____
        /     \
  _____/   e   \_____
 /     \       /     \
/   w   \_____/   d   \
\       /     \       /
 \_____/       \_____/
 /     \       /     \
/   q   \_____/   s   \
\       /     \       /
 \_____/   a   \_____/
       \       /
        \_____/

同様に、Rその後反時計回りに回転()するとグリッドが通常に戻り、再び反時計回りに回転するとに「リマップ」さqwedsaaqwedsます。

入力は単一の文字列として指定する必要があり、出力は非数値文字(例:1 2または3,4)で結合された単一の文字列、または整数の配列のいずれかです。

これがあるので、バイト単位での最短コードが勝ちます。

テストケース:

In                         Out
---------------------------------
edeqaaaswwdqqs             -2, 0
dddddddddd                 10, 5
wswseaeadqdq               0, 0
<empty string>             0, 0
esaaqrweesrqrq             -1, 0
wrwrwrwrw                  -1, 0
RRssrrrs                   -1, -1
aRRRRwddrqrrqqq            -1, -4
rrrrrrrrrrrrRRRRRRrrrrrrq  -1, -1
rrRrRrrRrrrrRRrRrRR        0, 0

回答:


2

Pyth、81バイト

J_K1=Y"qwedsa"A,ZZFNz=kxYN ?<kZ=Y?<x\rNZ.>Y1.<Y1A,+G@[JZ1KZJ)k+H@[J_2JK2K)k;,G/H2

出力は、座標を表す整数のリストです。

私の解決策は実際には退屈です。配列(qwedsa)で入力された文字を検索し、座標のそれぞれの変化を表す2つの配列にアクセスします。たとえば、入力がの場合、w1が得られます(配列の2番目の文字であるため)。その後、我々は、追加A[1]するx(ここAで、変更のための配列でありx、異なる入力に対して内)B[1]yBの変更であるがy)。rそしてRだけ回転させることによって達成されるqwedsaアレイ。

誰かがPythを使えばもっと良くできると確信しています。私は私の答えをゴルフしようとし続けます!

ここで試してみることができます


12

網膜353 339 178 175 150 130 129 117バイト

R
5$*r
T`aq\we\ds`so`r.+
)`r(.*)
$1
^
:
a
sq
e
wd
+`(.+)q
w$1
+`(.+)d
s$1
+`sw

(.*)(\1w?):
$0$2
+`sw|ws

w+
-$0
\w
1

出力は、コロンで区切られた単項形式です。これは、出力にゼロが実際に表示されないことを意味します(ただし、コロンが存在すると、2つの座標のどちらかが1つしかない場合はゼロになります)。

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

これは本当に楽しかったし、驚くほど短かった。:)

説明

最初にいくつかの背景。六角形のグリッドを記述するための座標系がいくつかあります。求められたものはオフセット座標を使用します。これは、1つの軸が少し「ゆらぐ」ことを除いて、基本的には長方形のグリッド座標に似ています。特に、質問はリンクされたページに表示される「odd-q」レイアウトを要求します。移動中に座標がどのように変化するかは、移動の方向だけでなく現在の位置にも依存するため、この座標系を使用するのは少し面倒です。

別の座標系は軸座標を使用します。それは基本的に、hexgridを立方体のボリュームを通る斜めのスライスとして想像し、2つの軸(xとz)を使用して2D平面上の位置を見つけることです。16進グリッドでは、2つの軸が60(または120)度の角度を形成することを意味します。このシステムは少し直感的ではありませんが、すべての方向が固定の「デルタ」ベクトルに対応しているため、操作がはるかに簡単です。(この座標系に到達する方法のより良い説明については、リンクとそこの素敵な図とアニメーションをチェックしてください。)

それで、ここでやることは次のとおりです。軸座標で運動を計算し(課題で提案されているように、コマンドの意味を再マッピングすることで回転に注意します)、完了したら軸を奇数qオフセットに変換します座標。

6つの移動は、(xz)軸座標の次のデルタベクトルにマップします。

q => (-1,  0)
w => ( 0, -1)
e => ( 1, -1)
d => ( 1,  0)
s => ( 0,  1)
a => (-1,  1)

待ってください、これはRetinaです。単項の数値を処理する必要があります。負の単項数をどのように処理しますか?考え方は、2つの異なる数字を使用することです。1つはを表し+1、もう1つはを表し-1ます。つまり1、現在の位置に加算するか減算するかに関係なく、数字を追加することでいつでも行うことができます。完了したら、バランスの取れた数字をキャンセルすることで、結果を(対応する数字の)大きさに縮小します。次に、残りの数字に基づいて符号を計算し、すべての数字をに置き換えます1

計画では:、入力の前に、軸のxおよびzコンポーネントを(セパレータとして)aの左右に構築します。wそしてs右側に追加されます。qそしてd左側に追加され、そしてeそしてa両側に追加します。以来wsの正しい側にすでにある:(前になります)、我々としてそれらを使用します-1+1、それぞれの数字を。

コードを見ていきましょう。

R
5$*r

それぞれRを5 r秒に変えることから始めます。もちろん、1回の左ターンは、16進グリッドでの5回の右ターンと同じであり、そうすることで、再マッピング手順で多くの複製を行うことができます。

T`aq\we\ds`so`r.+

これは、6つのコマンドが最初のコマンドの後に見つかった場合r(最初のコマンドを処理するr)、それらを回転させる音訳段階です。wまた、d文字クラスに展開されないようにエスケープする必要があります。はo、ソースセットをターゲットセットに挿入し、これらのローテーションタスクのために大量のバイトを保存します。したがって、文字マッピングは次のとおりです。

aqweds
saqweds

s2番目の行の最後は単純に無視できます。

)`r(.*)
$1

これはr処理されているため、最初の文字列を削除します(置換制限を既に実装していたことを望みます...)。また)、文字列が変化しなくなるまで、これまでのすべてのステージをループで実行するようにRetinaに指示します。後続の反復では、Rs がもうないため、最初のステージはノーオペレーションでありr、文字列にsが残っている限り、2番目のステージは別の回転を適用します。

完了したら、すべてのコマンドを、回転していないグリッド上の対応する方向にマッピングし、それらの処理を開始できます。もちろん、この動きはそれらのデルタベクトルの合計であり、合計は可換であるため、回転が除去されたので、それらを処理する順序は実際には関係ありません。

^
:

前面に座標区切り記号を挿入します。

今、私たちは本当に処理する必要はありませんsw。それらは私たち+1-1数字であり、すでに正しい側にある:ので、最終的には必要に応じてドロップアウトします。別の単純化を行うことができます:ais s + qおよびand eですw + d。そうしよう:

a
sq
e
wd

ここでも、それらswちょうどドロップアウトします。私たちがする必要があるのは、それらqdsを前面に移動し、それらをws sに変えることsだけです。2つの別々のループでそれを行います。

+`(.+)q
w$1
+`(.+)d
s$1

これで完了です。軸座標からオフセット座標への変換の時間。そのためには、数字を折りたたむ必要があります。ただし、今のところは左側のみを考慮します。qsとdsの処理方法によりs、左側のすべてのs がすべてのsの前に表示されることがわかっているwため、それらを折りたたむために1つのペアのみをチェックする必要があります。

+`sw

今、実際の変換。上記のリンクから取得した擬似コードは次のとおりです。

# convert cube to odd-q offset
col = x
row = z + (x - (x&1)) / 2

そのため、左側はすでに正しいです。(x - (x&1)) / 2ただし、右側には修正項が必要です。取得&1はモジュロ2と同じです。これは基本的にx/2、整数の除算として解析され、負の無限大に向かって丸められます。したがって、正のx場合、桁数の半分を切り捨て(切り捨て)、負の場合x、桁数の半分を減算(切り上げ)します。これは、正規表現で驚くほど簡潔に表現できます。

(.*)(\1w?):
$0$2

貪欲さのため、偶数の場合x、グループ1は正確に半分の数字と一致し\1、残りの半分は無視されw?ます。その半分を:(つまりx/2)の後に挿入します。x偶数であれば、正と負を区別する必要があります。xが正の場合、w?一致しないため、2つのグループは同じ桁数に一致する必要があります。最初のものsが単にスキップされれば問題ないので、切り捨てます。xが負で奇数の場合、可能な一致は\1x切り捨ての半分)とそのオプションですw。これらは両方ともgroupに分類されるため、必要に応じて端数を切り上げて2記述x/2します。

+`sw|ws

次に、右側の数字を折りたたみます。今回はsand の順序がわからないため、w両方のペアを考慮する必要があります。

w+
-$0

両方の部分が1つの繰り返される数字に削減されました(または何もありません)。その数字がの場合w、マイナス記号を前に挿入します。

\w
1

そして最後に、我々は両方に回すws、単一の合理的な単項桁に。(wまたはsを単項数字として使用することでバイトを節約できると思いますが、それは少しストレッチのようです。)


10
(この答えがメインサイトのページに表示され、ヘキサゴニーで書かれていることを心から願っていたのは私だけですか?)
アディソンクランプ

9
@FlagAsSpamこのコミュニティの要求は、正規表現を介してのみ入力を処理できる言語で、符号付き整数と六角形グリッドを含む課題を解決することにより、8人を失望させる(そしてカウントする)ことができる場合、深刻に増加しています。;)
マーティン・エンダー

1

パイソン(3.5)193 185 182バイト

また、軸座標で計算し、最後に変換します。

@MartinBüttnerのソリューションに従って最適化を追加します。Rをr * 5に置き換えますが、バイトカウントは変更されません。しかし、この変更elif j=='r'により、2番目のテストを次のように置き換えることができます。else

このソリューションでは、入力に無効な文字を含めることはできないと想定しています。

def f(i):
 x=y=0;u=-1,0,-1,1,0,1,1,0,1,-1,0,-1;v='dewqas'
 for j in i.replace('R','r'*5):
  w=v.find(j)*2
  if-1<w:x+=u[w];y+=u[w+1]
  else:u=u[2:]+u[:2]
 print(-x,-x-y+(x-(x%2))/2)

非ゴルフ

def f(i):
  x=y=0
  u=-1,0,-1,1,0,1,1,0,1,-1,0,-1    # operations list xd,yd,xe,ye...
  v='dewqas'                       # letters list in clockwise order 
  i.replace('R','r'*5)             # replace 'R' by 5*'r'
  for j in i:
    w=v.find(j)*2                  # extract letter index
    if-1<w:
      x+=u[w]                      # apply operations
      y+=u[w+1]
    else:
      u=u[2:]+u[:2]                # rotate clockwise the operation string
  print(-x,-x-y+(x-(x%2))/2)       # convert coordinates axial to "odd-q"

使用法

>>> f('wrwrwrwrw')
-1 0.0
>>> f('dddddddddd')
10 5.0
>>> f('edeqaaaswwdqqs')
-2 0.0

0

バッチ、708の 636 586 569バイト

数学が簡単になったため、2倍のy座標を使用しました。最も理想的な方法で回転を考慮したかどうかはわかりませんが、rs の数を数えるのに勝ります。

編集:の処理を改善して72バイトを保存しました R s。set/aステートメントを最適化して60バイトを節約しました。いくつかのマイナーな最適化で17バイトを保存しました。

@echo off
set m=%1
set/ay=x=0
set r=r
set g=goto l
:l
set/a"z=y>>1
if "%m%"=="" echo %x% %z%&exit/b
set c=%m:~0,1%
set m=%m:~1%
goto %r:rrrrrr=%%c%
:a
:rq
:rrw
:rrre
:rrrrd
:rrrrrs
set/ax-=2
:w
:re
:rrd
:rrrs
:rrrra
:rrrrrq
set/ax+=1,y-=1
%g%
:q
:rw
:rre
:rrrd
:rrrrs
:rrrrra
set/ay-=2
%g%
:s
:ra
:rrq
:rrrw
:rrrre
:rrrrrd
set/ax-=2
:e
:rd
:rrs
:rrra
:rrrrq
:rrrrrw
set/ax+=+1,y+=1
%g%
:d
:rs
:rra
:rrrq
:rrrrw
:rrrrre
set/ay+=2
%g%
:r
:rr
:rrr
:rrrr
:rrrrr
:rrrrrr
if %c%==R set c=rrrrr
set r=%c%%r%
%g%

0

05AB1E、60 バイト

.•F?äM•U2Å0IvXy'rQiÀUëy'RQiÁUëykÐ5α‚ßsD3%_s3›·+‚<+]Ć`DÉ-2÷+‚

オンラインで試すたり、すべてのテストケースを確認してください

説明:

一般的な説明:

文字列"qwedsa"と座標[0,0]で始まり、入力の文字をループします。
「r」または「R」の場合、この文字列をそれぞれ左または右に回転させます。
そうでない場合は、この文字列で0から始まるインデックスを取得し、次のようにマッピングします。

q → 0 → [-1,  0]
w → 1 → [ 0, -1]
e → 2 → [ 1, -1]
d → 3 → [ 1,  0]
s → 4 → [ 0,  1]
a → 5 → [-1,  1]

インデックスの数字を次のように変換する必要があります バツ そして y 座標:

 x   indices     y   indices
-1 ← 0;5        -1 ← 1;2
 0 ← 1;4         0 ← 0;3
 1 ← 2;3         1 ← 4;5

これを行うには、インデックスを変換します k 次のように:

バツ=mnkabsk51
y=0kモッド3+2k>31

そして、ループ全体の後、オフセットを修正する必要があります y-に基づく座標 バツ-座標、私たちはこのようにします(バツ 同じまま):

y=y+バツバツモッド22

コードの説明:

.•FM         # Push compressed string "qwedsa"
       U        # Pop and store it in variable `X`
2Å0             # Push list [0,0]
                # (many 3-byte alternatives for this: `00S`; `т¦S`; `0D‚`; `1¾‰`; etc.)
   Iv           # Loop over each character `y` of the input:
     X          #  Push string `X`
      y'rQi    '#  If `y` equals "r":
           À    #   Rotate string `X` once towards the left
            U   #   And pop and store it as new value for `X`
      ëy'RQi   '#  Else-if `y` equals "R":
            ÁU  #   Do the same, but rotate right instead
      ë         #  Else:
       yk       #   Get the 0-based index of `y` in the string `X`
         Ð      #   Triplicate this index
          5α    #   Take the absolute difference with 5
            ‚ß  #   Pair it with the original index, and pop and push the minimum
                #   (maps 0→[0,5]→0; 1→[1,4]→1; 2→[2,3]→2;
                #         3→[3,2]→2; 4→[4,1]→1; 5→[5,0]→0)
         sD     #   Swap to get the original index again, and duplicate it
           3%   #   Take modulo 3
             _  #   And check if it's equals to 0 (1 if truthy; 0 if falsey)
          s3   #   Swap to take the index again, and check if it's larger than 
                #   (again, 1 if truthy; 0 if falsey)
             ·  #   Double this
          +     #   And add both checks together
                #   (maps 0→1+0→1; 1→0+0→0; 2→0+0→0;
                #         3→1+0→1; 4→0+2→2; 5→0+2→2)
               #   Pair both mapped values together
          <     #   Decrease both by 1, so it becomes: 0→-1; 1→0; 2→1
           +    #   And add it to the current coordinates
    ]           # After the loop with inner if-else statements:
     Ć          # Enclose the coordinate, appending its own head: [x,y] becomes [x,y,x]
      `         # Push all three values separated to the stack
       D        # Duplicate this x
        É       # Check if its odd (1 if truthy; 0 if falsey)
         -      # Subtract it from the duplicated x
          2÷    # Integer-divide it by 2
            +   # Add it to y
               # And pair it with the original x again
                # (after which the result is output implicitly)

この05AB1E鉱山の先端を参照してください(セクション圧縮文字列の辞書の一部ではないにどのように?理由を理解すること.•F?äM•です"qwedsa"


-1

Python 3、227バイト

def G(s):
 q='qwedsa'
 d=[-1,0,1,1,0,-1,-1,-2,-1,1,2,1]
 X=Y=0
 for c in s:
  if c in q:
   n = q.find(c)
   X += d[n]
   Y += d[n+6]
  if c == 'r':
   q = q[1:]+q[0]
  if c == 'R':
   q = q[5]+q[0:5]
 print(X, int((Y-X%2)/2))

私はPython 3.5.0b3MacOSで使用していますが、丸めのために5と6でエラーが発生しましたが、残りは正しかったです。(編集により修正されたため)。使用しているPythonのバージョンは何ですか?
オースティンヘイスティングス

1
@AustinHastings Debian不安定版のPython 3を使用しています。
ドアノブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.