Ke mana pesawat ruang angkasa pergi?

15

Berdasarkan ide yang disarankan oleh Zgarb .

Pesawat ruang angkasa bergerak di sekitar kisi 3D biasa. Sel-sel grid diindeks dengan bilangan bulat dalam sistem koordinat tangan kanan, xyz . Pesawat ruang angkasa dimulai pada titik asal, menunjuk sepanjang sumbu x positif , dengan sumbu z positif mengarah ke atas.

Pesawat ruang angkasa akan terbang di sepanjang lintasan yang ditentukan oleh urutan gerakan yang tidak kosong. Setiap gerakan adalah salah satu F(atau ke depan) yang membuat pesawat ruang angkasa bergerak satu sel ke arah yang menghadapnya, atau salah satu dari enam rotasi UDLRlr. Ini sesuai dengan pitch, yaw and roll sebagai berikut:

PYR
Terima kasih kepada Zgarb untuk membuat diagram.

  • Up dan Dmiliki sendiri perubahan nada pesawat ruang angkasa sebanyak 90 derajat (di mana arahnya sesuai dengan pergerakan hidung pesawat ruang angkasa).
  • LEFT dan EIGHT Rmengubah yaw pesawat ruang angkasa sebesar 90 derajat. Mereka belok kiri dan kanan biasa.
  • lEt dan Eight radalah gerakan menggulung 90 derajat, di mana arahnya menunjukkan sayap mana yang bergerak ke bawah.

Perhatikan bahwa ini harus selalu ditafsirkan relatif terhadap pesawat ruang angkasa sehingga sumbu yang relevan berputar bersama dengannya.

Dalam istilah matematika, pesawat ruang angkasa pada awalnya berada di posisi (0, 0, 0), menunjuk sepanjang (1, 0, 0)vektor, dengan (0, 0, 1)menunjuk ke atas. Rotasi sesuai dengan matriks berikut yang diterapkan pada sistem koordinat:

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 )

Anda harus menampilkan posisi akhir dari pesawat ruang angkasa sebagai tiga bilangan bulat x , y , z . Output mungkin tiga bilangan bulat terpisah atau daftar atau string yang mengandung mereka. Mereka mungkin berada dalam urutan yang konsisten selama Anda menentukannya.

Anda dapat menulis sebuah program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi dan mengeluarkan hasilnya melalui STDOUT (atau alternatif terdekat), nilai pengembalian fungsi atau parameter function (out).

Aturan standar berlaku.

Uji Kasus

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)

Contoh yang berhasil

Berikut adalah langkah-langkah lanjutan dari UFLrRFLRLRtest case. Di sini, semua koordinat menengah dan vektor arah diberikan dalam sistem koordinat global awal (sebagai lawan dari satu lokal ke pesawat ruang angkasa):

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)
Martin Ender
sumber
Tantangan ini adalah generalisasi 3D yang satu ini , minus bagian persimpangan.
orlp
Mengapa 2! = 2, 3! = -1, 4! = 0! = -4, 1! = -3
username.ak
@ username.ak Saya rasa saya tidak mengerti pertanyaannya. Apa yang anda maksudkan?
Martin Ender
@ Martin Büttner, saya katakan mengapa rotasi 180 derajat tidak sama dengan -180, 270 tidak sama dengan -90 dll
username.ak
@ username.ak bukan?
Martin Ender

Jawaban:

3

MATL , 76 75 byte

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

Ini berfungsi dalam versi bahasa saat ini (12.1.1).

Sunting (4 April 2016): Perilaku fungsi vtelah berubah dalam rilis 15.0.0 bahasa. Untuk membuat kode di atas berjalan, hapus yang pertama vdan ganti yang kedua 3$v. Tautan berikut mencakup modifikasi ini.

Cobalah online !

Penjelasan

Keadaan kapal dapat dijelaskan dalam dua variabel:

  • posisi: vektor 3x1
  • orientasi: 3x3 matriks dengan rotasi akumulasi , di mana "akumulasi" berarti produk matriks berulang.

Variabel ketiga adalah arah di mana kapal menghadap, tetapi itu tidak diperlukan, karena dapat diperoleh sebagai arah awal (vektor kolom [1;0;0] ) dikalikan orientasi saat ini; yaitu, kolom pertama dari orientasi.

Dua variabel status ini disimpan di tumpukan, dan diperbarui dengan setiap huruf. Setiap huruf ULlDRrmengalikan matriks orientasi dengan salah satu dari enam matriks rotasi untuk memperbarui orientasi. SuratF menambahkan posisi saat ini ditambah kolom pertama dari matriks orientasi.

Enam matriks rotasi dibuat sebagai berikut: pertama diperkenalkan secara langsung; kedua dan ketiga adalah pergeseran melingkar dari yang sebelumnya; dan tiga sisanya adalah versi transparan dari yang lain.

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
Luis Mendo
sumber
1

Oktaf, 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

Versi yang dapat dibaca:

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
Rainer P.
sumber
Penggunaan nama bidang dinamis yang bagus!
Luis Mendo
2
"Versi yang dapat dibaca [rujukan?]";)
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]

Penjelasan: Biasanya untuk menghitung arah pesawat ruang angkasa Anda akan menyusun semua rotasi bersama-sama, dan kemudian untuk setiap gerakan Anda akan menyusun hasilnya ke vektor satuan F = (1, 0, 0)(atau lebih sederhana ekstrak kolom pertama dari matriks). Misalnya FFrlFULULF => F + F + r⋅l⋅F + r⋅l⋅U⋅L⋅L⋅L⋅F,. Karena perkalian matriks adalah asosiatif, bahasa dengan perkalian matriks bawaan jelas dapat menghitung produk parsial r⋅l⋅U⋅L⋅L⋅Lseiring berjalannya waktu, dikalikan dengan Fseperlunya untuk menghasilkan istilah yang kemudian ditambahkan bersama. Sayangnya saya tidak memiliki kemewahan itu, jadi opsi termurah adalah menghitung setiap istilah dalam ungkapan di atas secara terpisah, dimulai dengan jadi saya juga perlu menandai awal dan akhir setiap istilah dalam daftar sehingga saya dapat mengabaikan sisanya. dari string. Sedikit tidak berbulu:F dan bekerja kembali. Untuk itu, saya perlu daftar untuk setiap kemunculan Fsemua rotasi hingga saat itu. Saya melakukan ini menggunakanreplace$`

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
Neil
sumber