宇宙船はどこに行くのですか?


15

Zgarbによって提案されたアイデアに基づいています。

宇宙船は通常の3Dグリッドを動き回っています。グリッドのセルには、右手座標系xyzの整数でインデックスが付けられます。宇宙船は原点から始まり、正のxに沿って向きます軸に、正のz軸が上向きになります。

宇宙船は、空ではない一連の動きによって定義される軌道に沿って飛行します。各動きはF、宇宙船がそのセルの向きに沿って1つのセルを移動させる(順方向)、または6つの回転のいずれかですUDLRlr。これらは次のようにピッチ、ヨー、ロールに対応します。

PYR
ダイアグラムを作成してくれたZgarbに感謝します。

  • UpとD自分自身で宇宙船のピッチを90度変更します(方向は宇宙船の機首の動きに対応します)。
  • Lエフトと R ightは、宇宙船のヨーを90度変化させます。彼らはちょうど通常の左と右のターンです。
  • leftとrightは90度のローリング運動で、方向はどの翼が下に動くかを示します。

これらは常に関連する軸が一緒に回転するように、宇宙船に対して相対的に解釈される必要があることに注意してください。

数学的には、宇宙船は最初は位置(0, 0, 0)にあり、(1, 0, 0)ベクトルに沿って(0, 0, 1)上向きに指します。回転は、座標系に適用される次のマトリックスに対応します。

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 )

宇宙船の最終位置を3つの整数xyzとして出力する必要があります。出力は、3つの個別の整数、またはそれらを含むリストまたは文字列です。指定する限り、一貫した順序で並べられます。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

標準規則が適用されます。

テストケース

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)

実施例

UFLrRFLRLRテストケースの中間ステップは次のとおりです。ここで、すべての中間座標と方向ベクトルは、初期のグローバル座標系で与えられます(宇宙船にローカルな座標系とは対照的です):

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)

この課題は、3次元の一般化であるこの1、マイナス交差部。
orlp

なぜ2!= 2、3!= -1、4!= 0!= -4、1!= -3
username.ak

@ username.ak質問を理解していないと思います。何を言ってるの?
マーティンエンダー

Büttner@Martin、Iは、270は-90などと同じではない180度の回転が-180と同じではない理由を言う
username.ak

@ username.akは違いますか?
マーティンエンダー

回答:


3

MATL76 75バイト

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

これは、言語の現在のバージョン(12.1.1)で機能します。

編集(2016年4月4日):関数の動作vは、言語のリリース15.0.0で変更されました。上記のコードを実行するには、最初のコードを削除しv、2番目のコードを置き換え3$vます。次のリンクには、この変更が含まれています。

オンラインで試す

説明

船の状態は、2つの変数の観点から説明できます。

  • 位置:3x1ベクトル
  • 方向:累積回転を伴う3x3マトリックス。ここで、「累積」とは、マトリックス積の繰り返しを意味します。

3番目の変数は船が向いている方向になりますが、これは必要ありません。初期方向(列ベクトル[1;0;0])×現在の。つまり、方向の最初の列。

これらの2つの状態変数はスタックに保持され、各文字で更新されます。各文字ULlDRrは、方向マトリックスに6つの回転マトリックスのいずれかを乗算して、方向を更新します。文字Fは、現在の位置と方向行列の最初の列を追加します。

6つの回転行列は次のように作成されます。最初は直接導入されます。2番目と3番目は前の循環シフトです。残りの3つは他のものの転置バージョンです。

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

オクターブ、175バイト

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

読み取り可能なバージョン:

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

動的フィールド名の素晴らしい使用!
ルイスメンドー

2
「読み取り可能なバージョン[要出典]」;)
trichoplax

0

ES6、265の 259バイト

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]

説明:通常、宇宙船の方向を計算するには、すべての回転を一緒に構成し、次に、移動ごとに結果を単位ベクトルに構成しますF = (1, 0, 0)(または単純に行列の最初の列を抽出します)。たとえば、FFrlFULULF => F + F + r⋅l⋅F + r⋅l⋅U⋅L⋅L⋅L⋅F。行列の乗算は連想的であるため、組み込みの行列の乗算を使用する言語では、必要に応じてr⋅l⋅U⋅L⋅L⋅L乗算しFて項を生成し、それを足し合わせて部分積を計算できます。残念ながら、私にはそんな贅沢はないので、最も安価なオプションは、上記の式の各用語を個別に計算するFことです。そのためには、Fその時点までのすべての回転の発生ごとにリストが必要です。私はこれを使用してreplace$`私はまた、私は、文字列の残りの部分を無視することができるようにリスト内の各用語の開始と終了をマークする必要があります。わずかに未使用:

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