Tàu vũ trụ đi đâu?


15

Dựa trên một ý tưởng được đề xuất bởi Zgarb .

Một tàu vũ trụ đang di chuyển xung quanh lưới 3D thông thường. Các ô của lưới được lập chỉ mục với các số nguyên trong hệ tọa độ tay phải, xyz . Tàu vũ trụ bắt đầu từ điểm gốc, chỉ dọc theo trục x dương , với trục z dương hướng lên trên.

Tàu vũ trụ sẽ bay dọc theo một quỹ đạo được xác định bởi một chuỗi các chuyển động không trống. Mỗi chuyển động là F( hoặc hướng về ) làm cho tàu vũ trụ di chuyển một ô theo hướng đối diện của nó, hoặc một trong sáu phép quay UDLRlr. Chúng tương ứng với cao độ, ngáp và lăn như sau:

PYR
Cảm ơn Zgarb đã tạo ra sơ đồ.

  • Up và Dthay đổi độ cao của tàu vũ trụ 90 độ (trong đó hướng tương ứng với chuyển động của mũi tàu vũ trụ).
  • Left và Right thay đổi ngáp của tàu vũ trụ 90 độ. Họ chỉ là rẽ trái và phải thường xuyên.
  • left và right là các chuyển động lăn 90 độ, trong đó hướng cho biết cánh nào di chuyển xuống dưới.

Lưu ý rằng những điều này phải luôn được giải thích liên quan đến tàu vũ trụ để các trục có liên quan xoay cùng với nó.

Theo thuật ngữ toán học, tàu vũ trụ ban đầu ở vị trí (0, 0, 0), chỉ dọc theo (1, 0, 0)vectơ, với (0, 0, 1)hướng lên trên. Các phép quay tương ứng với các ma trận sau được áp dụng cho hệ tọa độ:

U = ( 0  0 -1     D = ( 0  0  1
      0  1  0           0  1  0
      1  0  0 )        -1  0  0 )

L = ( 0 -1  0     R = ( 0  1  0
      1  0  0          -1  0  0
      0  0  1 )         0  0  1 )

l = ( 1  0  0     r = ( 1  0  0
      0  0  1           0  0 -1
      0 -1  0 )         0  1  0 )

Bạn nên xuất vị trí cuối cùng của tàu vũ trụ dưới dạng ba số nguyên x , y , z . Đầu ra có thể là ba số nguyên riêng biệt hoặc một danh sách hoặc chuỗi chứa chúng. Họ có thể theo bất kỳ thứ tự nhất quán miễn là bạn chỉ định nó.

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Luật tiêu chuẩn được áp dụng.

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

F                                                   => (1, 0, 0)
FDDF                                                => (0, 0, 0)
FDDDF                                               => (1, 0, 1)
LrDDlURRrr                                          => (0, 0, 0)
UFLrRFLRLR                                          => (1, 0, 1)
FFrlFULULF                                          => (3, 0, -1)
LLFRLFDFFD                                          => (-2, 0, -2)
FrrLFLFrDLRFrLLFrFrRRFFFLRlFFLFFRFFLFlFFFlUFDFDrFF  => (1, 5, 7)
FUrRLDDlUDDlFlFFFDFrDrLrlUUrFlFFllRLlLlFFLrUFlRlFF  => (8, 2, 2)
FFLrlFLRFFFRFrFFFRFFRrFFFDDLFFURlrRFFFlrRFFlDlFFFU  => (1, 2, -2)
FLULFLFDURDUFFFLUlFlUFLFRrlDRFFFLFUFrFllFULUFFDRFF  => (-3, -2, -3)

Ví dụ làm việc

Dưới đây là các bước trung gian của UFLrRFLRLRtrường hợp thử nghiệm. Ở đây, tất cả các tọa độ trung gian và vectơ chỉ hướng được đưa ra trong hệ tọa độ toàn cầu ban đầu (trái ngược với một cục bộ của tàu vũ trụ):

Cmd.  Position    Forward     Up
      ( 0, 0, 0)  ( 1, 0, 0)  ( 0, 0, 1)
U     ( 0, 0, 0)  ( 0, 0, 1)  (-1, 0, 0)
F     ( 0, 0, 1)  ( 0, 0, 1)  (-1, 0, 0)
L     ( 0, 0, 1)  ( 0, 1, 0)  (-1, 0, 0)
r     ( 0, 0, 1)  ( 0, 1, 0)  ( 0, 0, 1)
R     ( 0, 0, 1)  ( 1, 0, 0)  ( 0, 0, 1)
F     ( 1, 0, 1)  ( 1, 0, 0)  ( 0, 0, 1)
L     ( 1, 0, 1)  ( 0, 1, 0)  ( 0, 0, 1)
R     ( 1, 0, 1)  ( 1, 0, 0)  ( 0, 0, 1)
L     ( 1, 0, 1)  ( 0, 1, 0)  ( 0, 0, 1)
R     ( 1, 0, 1)  ( 1, 0, 0)  ( 0, 0, 1)

Thử thách này là một khái quát 3D của cái này , trừ phần giao nhau.
orlp

Tại sao 2! = 2, 3! = -1, 4! = 0! = -4, 1! = -3
tên người

@ username.ak Tôi không nghĩ mình hiểu câu hỏi. bạn đang đề cập gì tới?
Martin Ender

@Martin Büttner, tôi nói tại sao xoay 180 độ không giống với -180, 270 không giống với -90, v.v.
tên người

@ tên người dùng.ak có phải không?
Martin Ender

Câu trả lời:


3

MATL , 76 75 byte

FFF!3Xyj"FFT_FTFv4BvtFT_YStTF_YS3:"3$y!]6$Xh@'ULlDRr'4#mt?X)Y*}xxt1Z)b+w]]x

Điều này hoạt động trong phiên bản hiện tại (12.1.1) của ngôn ngữ.

Chỉnh sửa (ngày 4 tháng 4 năm 2016): Hành vi của chức năng vđã thay đổi trong bản phát hành 15.0.0 của ngôn ngữ. Để làm cho mã trên chạy, loại bỏ cái đầu tiên vvà thay thế cái thứ hai 3$v. Các liên kết sau đây bao gồm sửa đổi này.

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

Giải trình

Trạng thái của con tàu có thể được mô tả theo hai biến:

  • vị trí: vector 3x1
  • định hướng: ma trận 3x3 với vòng quay tích lũy , trong đó "tích lũy" có nghĩa là sản phẩm ma trận lặp lại.

Biến thứ ba sẽ là hướng mà con tàu đang đối mặt, nhưng điều đó không cần thiết, bởi vì nó có thể được lấy làm hướng ban đầu (vectơ cột [ 1;0;0]) nhân với hướng hiện tại; đó là, cột đầu tiên của định hướng.

Hai biến trạng thái này được giữ trên ngăn xếp và được cập nhật với mỗi chữ cái. Mỗi chữ cái ULlDRrnhân ma trận định hướng với một trong sáu ma trận xoay để cập nhật hướng. Thư Fthêm vị trí hiện tại cộng với cột đầu tiên của ma trận định hướng.

Sáu ma trận xoay được tạo ra như sau: đầu tiên được giới thiệu trực tiếp; thứ hai và thứ ba là dịch chuyển tròn của cái trước; và ba phần còn lại là phiên bản chuyển đổi của những cái khác.

FFF!             % 3x1 vector [0;0;0]: initial position
3Xy              % 3x3 identity matrix: initial orientation
j                % input string
"                % for-each character in that string
  FFT_FTFv4Bv    %   rotation matrix for U: defined directly
  tFT_YS         %   rotation matrix for L: U circularly shifted to the left
  tTF_YS         %   rotation matrix for l: L circularly shifted down
  3:"            %   repeat three times
    3$y!         %     copy third matrix from top and transpose
  ]              %   end loop. This creates rotation matrices for D, R, r
  6$Xh           %   pack the 6 matrices in a cell array
  @              %   push current character from the input string
  'ULlDRr'4#m    %   this gives an index 0 for F, 1 for U, 2 for L, ..., 6 for r
  t?             %   if non-zero: update orientation
    X)           %     pick corresponding rotation matrix
    Y*           %     matrix product
  }              %   else: update position
    xx           %     delete twice (index and rotation matrix are not used here)
    t1Z)         %     duplicate orientation matrix and take its first column
    b+           %     move position vector to top and add
    w            %     swap the two top-most elements in stack
  ]              %   end if
]                % end for-each
x                % delete orientation matrix
                 % implicitly display position vector

1

Octave, 175 byte

function p=s(i)m.U=[0,0,-1;0,1,0;1,0,0];m.D=m.U';m.L=[0,-1,0;1,0,0;0,0,1];m.R=m.L';m.l=flip(flip(m.L),2);m.r=m.l';a=m.F=eye(3);p=[0;0;0];for c=i p+=(a*=m.(c))*[c=='F';0;0];end

Phiên bản dễ đọc:

function p=s(i)
  m.U=[0,0,-1;0,1,0;1,0,0];
  m.D=m.U';
  m.L=[0,-1,0;1,0,0;0,0,1];
  m.R=m.L';
  m.l=flip(flip(m.L),2);
  m.r=m.l';
  a=m.F=eye(3);
  p=[0;0;0];
  for c=i p+=(a*=m.(c))*[c=='F';0;0];
end

Sử dụng tốt tên trường năng động!
Luis Mendo

2
"Phiên bản có thể đọc được [cần dẫn nguồn]";)
trichoplax

0

ES6, 265 259 byte

s=>[...s.replace(/F/g,"f$`s")].reverse().map(e=>d={U:(x,y,z)=>[-z,y,x],D:(x,y,z)=>[z,y,-x],L:(x,y,z)=>[-y,x,z],R:(x,y,z)=>[y,-x,z],r:(x,y,z)=>[x,-z,y],l:(x,y,z)=>[x,z,-y],F:(...d)=>d,f:(x,y,z)=>[a+=x,b+=y,c+=z]),s:_=>[1,0,0]}[e](...d),d=[1,0,a=b=c=0])&&[a,b,c]

Giải thích: Thông thường để tính hướng của tàu vũ trụ, bạn sẽ kết hợp tất cả các phép quay với nhau, và sau đó cho mỗi lần di chuyển, bạn sẽ kết quả kết quả với vectơ đơn vị F = (1, 0, 0)(hoặc đơn giản hơn là trích xuất cột đầu tiên của ma trận). Ví dụ , FFrlFULULF => F + F + r⋅l⋅F + r⋅l⋅U⋅L⋅L⋅L⋅F. Vì phép nhân ma trận là kết hợp, các ngôn ngữ có phép nhân ma trận tích hợp rõ ràng có thể tính toán sản phẩm một phần r⋅l⋅U⋅L⋅L⋅Lkhi chúng đi cùng, nhân với Fkhi cần thiết để tạo ra các thuật ngữ sau đó được thêm vào với nhau. Thật không may, tôi không có sự xa xỉ đó, vì vậy, lựa chọn rẻ nhất là tính riêng từng thuật ngữ trong biểu thức trên, bắt đầu Fvà làm việc trở lại. Đối với điều đó, tôi cần một danh sách cho mỗi lần xuất hiện Fcủa tất cả các phép quay cho đến thời điểm đó. Tôi làm điều này bằng cách sử dụngreplacevới $`vì vậy tôi cũng cần phải đánh dấu sự bắt đầu và kết thúc mỗi học kỳ trong danh sách để tôi có thể bỏ qua phần còn lại của chuỗi. Hơi vô dụng:

s=>[... // split the string into separate operations
    s.replace(/F/g,"f$`s")] // For each 'F', wrap the operations up to that point
  .reverse() // Play all the operations in reverse order
  .map(e=>d= // Update the direction for each operation
    { // set of operations
      U:(x,y,z)=>[-z,y,x], // Up
      D:(x,y,z)=>[z,y,-x], // Down
      L:(x,y,z)=>[-y,x,z], // Left turn
      R:(x,y,z)=>[y,-x,z], // Right turn
      r:(x,y,z)=>[x,-z,y], // right roll
      l:(x,y,z)=>[x,z,-y], // left roll
      F:(...d)=>d, // does nothing, `s` and `f` do the work now
      f:(x,y,z)=>[a+=x,b+=y,c+=z], // do the move
      s:_=>[1,0,0] // back to start
    }[e](...d), // apply the operation to the current direction
    d=[1,0,a=b=c=0] // initialise variables
  )&&[a,b,c] // return result
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.