Chuyển động trên lưới lục giác


15

Đưa ra một đầu vào của một loạt các ký tự đại diện cho các chuyển động trên lưới lục giác, xuất ra tọa độ cuối cùng của "con trỏ".

Các hình lục giác của chúng ta sẽ được đánh số như vậy (hãy tưởng tượng một lưới hình chữ nhật với mỗi cột số lẻ được dịch chuyển xuống một chút):

  _____         _____         _____         _____
 /     \       /     \       /     \       /     \
/ -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  \
\       /     \       /     \       /     \       /
 \_____/       \_____/       \_____/       \_____/

Con trỏ bắt đầu từ (0, 0).

Các hướng dẫn bạn phải hỗ trợ như sau:

  • q: di chuyển lên trái
  • w: đi lên
  • e: di chuyển lên phải
  • a: di chuyển xuống bên trái
  • s: đi xuống
  • d: di chuyển xuống bên phải
  • r: xoay lưới theo chiều kim đồng hồ
  • R: xoay lưới ngược chiều kim đồng hồ

Các lệnh xoay xoay toàn bộ lưới trong khi giữ con trỏ ở cùng tọa độ. (Tại sao qweasd? Chúng khớp với các hướng độc đáo trên bàn phím QWERTY.)

Để giúp hình dung điều này, đây là những gì các lệnh di chuyển sẽ làm, giả sử con trỏ bắt đầu ở giữa:

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

Sau khi xoay theo chiều kim đồng hồ ( r), các lệnh được ánh xạ lại (hãy tưởng tượng nó như xoay toàn bộ lưới hex nhưng vẫn giữ "w" như lên, v.v., tương đương như sau):

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

Tương tự như vậy, xoay ngược chiều kim đồng ( R) sau đó sẽ trở lại lưới điện lại bình thường, và xoay ngược chiều kim đồng một lần nữa sẽ "remap" qwedsađể aqweds.

Đầu vào phải được cung cấp dưới dạng một chuỗi và đầu ra có thể là một chuỗi đơn được nối bởi bất kỳ ký tự không phải số nào (ví dụ 1 2hoặc 3,4) hoặc một mảng các số nguyên.

Vì đây là , mã ngắn nhất tính bằng byte sẽ thắng.

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

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

Câu trả lời:


2

Bình thường, 81 byte

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

Đầu ra là một danh sách các số nguyên biểu thị tọa độ.

Giải pháp của tôi thực sự rất nhàm chán; nó chỉ tìm kiếm ký tự được nhập vào trong một mảng (và qwedsa), sau đó truy cập hai mảng đại diện cho những thay đổi tương ứng trong tọa độ. Ví dụ, nếu đầu vào là w, thì chúng ta nhận được 1 (vì nó là ký tự thứ hai trong mảng). Sau đó chúng ta thêm A[1]vào x(trong đó Alà mảng cho những thay đổi trong xđối với các đầu vào khác nhau) và B[1]đến y(nơi Blà những thay đổi cho y). rRđạt được bằng cách chỉ xoay qwedsamảng.

Tôi chắc rằng ai đó có thể làm tốt hơn nhiều khi sử dụng Pyth. Tôi sẽ tiếp tục cố gắng để đánh golf câu trả lời của tôi mặc dù!

Bạn có thể thử nó ở đây .


12

Võng mạc , 353 339 178 175 150 130 129 117 byte

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

Đầu ra là đơn nhất, cách nhau bởi một dấu hai chấm. Điều đó có nghĩa là bạn sẽ không thực sự nhìn thấy các số 0 trong đầu ra (mặc dù sự hiện diện của dấu hai chấm sẽ cho bạn biết tọa độ nào trong hai tọa độ bằng 0, nếu chỉ có một).

Hãy thử trực tuyến!

Điều này thực sự thú vị và cuối cùng là ngắn đáng ngạc nhiên. :)

Giải trình

Một số nền tảng đầu tiên. Có một số hệ tọa độ để mô tả lưới lục giác. Một trong những yêu cầu sử dụng tọa độ bù. Điều đó về cơ bản giống như tọa độ lưới hình chữ nhật, ngoại trừ một trục "chao đảo" một chút. Cụ thể, câu hỏi yêu cầu bố cục "lẻ-q" được hiển thị trên trang được liên kết. Hệ thống tọa độ này hơi khó chịu khi làm việc, bởi vì cách tọa độ thay đổi trong quá trình di chuyển không chỉ phụ thuộc vào hướng di chuyển mà còn phụ thuộc vào vị trí hiện tại.

Một hệ tọa độ khác sử dụng tọa độ trục. Về cơ bản, nó tưởng tượng hexgrid như một lát chéo qua một thể tích hình khối và sử dụng hai trong số các trục (ví dụ x và z) để tìm vị trí trên mặt phẳng 2D. Trên lưới hex, điều đó có nghĩa là hai trục tạo thành một góc 60 (hoặc 120) độ. Hệ thống này ít trực quan hơn một chút nhưng dễ làm việc hơn, vì mọi hướng tương ứng với một vectơ "delta" cố định. (Để được giải thích rõ hơn về cách đến hệ thống tọa độ này, hãy kiểm tra liên kết và các sơ đồ và hình ảnh động đáng yêu ở đó.)

Vì vậy, đây là những gì chúng ta sẽ làm: chúng ta tính toán chuyển động theo tọa độ trục (chăm sóc xoay như được đề xuất trong thử thách, bằng cách ánh xạ lại ý nghĩa của các lệnh) và khi hoàn thành, chúng ta chuyển đổi trục sang bù lẻ-q tọa độ.

Sáu di chuyển ánh xạ tới các vectơ delta sau trong tọa độ trục (xz):

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

Đợi đã, đây là Retina, chúng ta sẽ phải làm việc với những con số đơn nguyên. Làm thế nào để chúng ta làm việc với số unary âm? Ý tưởng là sử dụng hai chữ số khác nhau. Một đại diện +1và đại diện khác -1. Điều đó có nghĩa là bất kể chúng ta muốn thêm hay bớt 1vị trí hiện tại, chúng ta luôn có thể làm như vậy bằng cách thêm một chữ số. Khi chúng ta hoàn thành, chúng ta thu gọn kết quả thành độ lớn của nó (của chữ số tương ứng) bằng cách hủy các chữ số cân bằng. Sau đó, chúng tôi tìm ra dấu hiệu dựa trên chữ số còn lại và thay thế tất cả các chữ số bằng 1.

Kế hoạch là xây dựng các thành phần trục x và z ở bên trái và bên phải của một :(như một dấu phân cách), ở phía trước của đầu vào. wssẽ thêm vào phía bên tay phải. qdsẽ thêm vào phía bên trái, easẽ thêm vào cả hai bên. Vì wsđã ở phía bên phải của :(sẽ đi phía trước), nên chúng ta sẽ sử dụng chúng tương ứng là các chữ số -1+1chữ số.

Chúng ta hãy đi qua mã.

R
5$*r

Chúng tôi bắt đầu bằng cách biến mỗi Rthành năm rs. Tất nhiên, một lần rẽ trái giống như năm lượt rẽ phải trên lưới hex và bằng cách đó, chúng ta có thể nhân đôi rất nhiều trong bước ánh xạ lại.

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

Đây là giai đoạn chuyển ngữ làm quay sáu lệnh, nếu chúng được tìm thấy sau lệnh đầu tiên r(do đó xử lý lệnh đầu tiên r). wdcần phải được trốn thoát để ngăn chúng mở rộng thành các lớp nhân vật. Việc ochèn tập hợp nguồn vào tập hợp đích sẽ lưu một bó byte cho các tác vụ xoay vòng này. Do đó, ánh xạ ký tự là:

aqweds
saqweds

nơi cuối cùng strong hàng thứ hai có thể đơn giản được bỏ qua.

)`r(.*)
$1

Điều này loại bỏ chuỗi đầu tiên rkhỏi chuỗi, vì nó đã được xử lý (tôi ước tôi đã thực hiện các giới hạn thay thế ...). Điều này )cũng cho Retina chạy tất cả các giai đoạn cho đến giai đoạn này trong một vòng lặp cho đến khi chuỗi ngừng thay đổi. Ở các lần lặp lại tiếp theo, giai đoạn đầu tiên là không có op vì không còn Rs và giai đoạn thứ hai sẽ áp dụng một phép quay khác miễn là rcòn lại s trong chuỗi.

Khi chúng ta hoàn thành, chúng ta đã ánh xạ tất cả các lệnh theo hướng chúng tương ứng trên lưới không được bảo vệ và có thể bắt đầu xử lý chúng. Tất nhiên chuyển động này chỉ là một tổng của các vectơ delta đó và các khoản tiền là giao hoán, vì vậy chúng ta không thực sự xử lý chúng theo cách nào mà các phép quay đã bị loại bỏ.

^
:

Chèn dấu phân cách tọa độ ở phía trước.

Bây giờ chúng tôi không thực sự cần phải xử lý sw. Chúng là chữ số của chúng tôi +1-1chúng đã ở phía chính xác :nên cuối cùng chúng sẽ rơi ra theo yêu cầu. Chúng ta có thể thực hiện một sự đơn giản hóa khác: ađơn giản s + qew + d. Hãy làm điều đó:

a
sq
e
wd

Một lần nữa, những người swsẽ bỏ học. Tất cả chúng ta cần phải làm là di chuyển những qs và ds vào phía trước và biến chúng thành ws và ss bản thân. Chúng tôi làm điều đó với hai vòng riêng biệt:

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

Vậy là xong. Thời gian chuyển đổi từ tọa độ trục sang tọa độ bù. Cho rằng chúng ta cần thu gọn các chữ số. Tuy nhiên, bây giờ chúng tôi chỉ quan tâm đến phía bên tay trái. Do cách chúng tôi xử lý các qs và ds, chúng tôi biết rằng tất cả các ss ở phía bên trái sẽ xuất hiện trước bất kỳ ws nào , vì vậy chúng tôi chỉ cần kiểm tra một cặp để thu gọn chúng:

+`sw

Bây giờ chuyển đổi thực tế. Đây là mã giả, được lấy từ liên kết ở trên:

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

Phải, vì vậy phía bên trái đã chính xác. Phía bên tay phải cần thuật ngữ điều chỉnh (x - (x&1)) / 2mặc dù. Lấy &1giống như modulo 2. Về cơ bản, phân tích này là x/2, phân chia số nguyên, được làm tròn về phía âm vô cực. Vì vậy, đối với số dương x, chúng ta cộng một nửa số chữ số (làm tròn xuống) và đối với số âm x, chúng ta trừ đi một nửa số chữ số (làm tròn lên). Điều này có thể được thể hiện một cách đáng ngạc nhiên chính xác trong regex:

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

Do sự tham lam, cho chẵn x, nhóm 1 sẽ khớp chính xác một nửa chữ số, \1nửa còn lại và chúng ta có thể bỏ qua w?. Chúng tôi chèn một nửa sau :(đó là x/2). Nếu xlà chẵn thì chúng ta cần phân biệt dương và âm. Nếu xlà dương, thì w?sẽ không bao giờ khớp, vì vậy hai nhóm vẫn sẽ phải khớp cùng một số chữ số. Điều đó không có vấn đề gì nếu lần đầu tiên sbị bỏ qua, vì vậy chúng tôi làm tròn xuống. Nếu xlà âm và lẻ, thì kết quả khớp có thể là với \1(một nửa số xđược làm tròn xuống) và tùy chọn đó w. Vì cả hai đều đi vào nhóm 2, chúng tôi sẽ viết x/2với cường độ được làm tròn (theo yêu cầu).

+`sw|ws

Bây giờ chúng tôi thu gọn các chữ số ở phía bên tay phải. Lần này, chúng tôi không biết thứ tự của sw, vì vậy chúng tôi cần tính đến cả hai cặp.

w+
-$0

Cả hai phần bây giờ được giảm xuống một chữ số lặp lại (hoặc không có gì). Nếu chữ số đó là w, chúng tôi chèn một dấu trừ ở phía trước.

\w
1

Và cuối cùng chúng ta biến cả thành wsthành một chữ số unary hợp lý duy nhất. (Tôi cho rằng tôi có thể lưu một byte bằng cách sử dụng whoặc sdưới dạng chữ số đơn, nhưng điều đó có vẻ hơi căng.)


10
(Am Tôi là người duy nhất đã thấy câu trả lời này đưa ra trên trang trang web chính và thắm thiết hy vọng nó được viết trong hexagony?)
Addison Crump

9
@FlagAsSpam Nhu cầu của cộng đồng này đang tăng lên nghiêm trọng khi có thể làm 8 người thất vọng (và đếm) bằng cách giải quyết một thách thức liên quan đến số nguyên và lưới lục giác có chữ ký với ngôn ngữ chỉ có thể xử lý đầu vào của nó thông qua các biểu thức. ;)
Martin Ender

1

Python (3.5) 193 185 182 byte

Tôi cũng tính toán tọa độ trục và chuyển đổi ở cuối.

Tôi thêm một số tối ưu hóa theo giải pháp @Martin Büttner: Tôi thay thế R bằng r * 5, nó không thay đổi số byte. Nhưng với thay đổi này, chúng tôi có thể thay thế thử nghiệm thứ hai elif j=='r'chỉ bằngelse

Giải pháp cho rằng chúng ta không thể có các ký tự không hợp lệ trong đầu vào.

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)

Ung dung

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"

Sử dụng

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

0

Mẻ, 708 636 586 569 byte

Tôi đã sử dụng gấp đôi tọa độ y vì nó làm cho phép toán đơn giản hơn. Tôi không chắc chắn tôi đã tính đến việc xoay vòng theo cách lý tưởng nhất, nhưng nó sẽ đếm số rs.

Chỉnh sửa: Đã lưu 72 byte bằng cách cải thiện việc xử lý Rs. Đã lưu 60 byte bằng cách tối ưu hóa các set/abáo cáo của tôi . Lưu 17 byte với một số tối ưu hóa nhỏ.

@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 byte

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

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

Giải thích chung:

Chúng tôi bắt đầu với một chuỗi "qwedsa"và tọa độ [0,0], và lặp qua các ký tự của đầu vào.
Nếu đó là "r" hoặc "R", chúng ta sẽ xoay chuỗi này sang trái hoặc phải tương ứng.
Nếu không, chúng ta lấy chỉ mục dựa trên 0 trong chuỗi này và ánh xạ nó như sau:

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

xy

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

k

x= =mTôin(k,mộtbS(k-5))-1
y= =(0k(mod3))+2(k>3)-1

yxx

y= =y+x-x(mod2)2

Mã giải thích:

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

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để chuỗi nén không nằm trong từ điển? ) Để hiểu tại sao .•F?äM•"qwedsa".


-1

Python 3, 227 byte

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

Tôi đang sử dụng Python 3.5.0b3trên MacOS và trong khi tôi gặp lỗi trong 5 và 6, do làm tròn số, phần còn lại là chính xác. (Kể từ khi cố định qua Chỉnh sửa). Bạn đang sử dụng phiên bản Python nào?
Austin Hastings

1
@AustinHastings Tôi đang dùng Python 3 trên Debian không ổn định.
Doorknob
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.