飞船去哪儿了?


15

基于Zgarb提出的想法

宇宙飞船在规则的3D网格周围移动。网格的单元格在右手坐标系xyz中用整数索引。太空飞船从原点开始,沿x轴正方向指向,z轴正方向向上。

飞船将沿着由非空运动序列定义的轨迹飞行。每个运动要么是F使飞船朝其朝向移动一个单元的(向后)方向,要么是六个旋转之一UDLRlr。这些对应于以下的俯仰,偏航和横滚:

PYR
感谢Zgarb创建该图。

  • Up和D自己将飞船的俯仰改变90度(方向对应于飞船鼻子的运动)。
  • LR左右将飞船的偏航角改变90度。它们只是常规的左转和右转。
  • lr向后是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 )

您应该将飞船的最终位置输出为三个整数xyz。输出可以是三个单独的整数或包含它们的列表或字符串。只要您指定它们,它们的顺序可以一致。

您可以编写程序或函数,通过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)

这种挑战的3D推广这一块,减去交叉部分。
orlp 2016年

为什么2!= 2,3!= -1,4!= 0!= -4,1!= -3
username.ak

@ username.ak我想我不明白这个问题。你指的是什么?
Martin Ender

@马丁布特内尔,我说为什么180度的旋转是不一样的-180,270是不一样的-90等
username.ak

@ username.ak是吗?
Martin Ender

Answers:


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然后替换第二个3$v。以下链接包含此修改。

在线尝试

说明

可以用两个变量来描述船的状态:

  • 位置:3x1矢量
  • 方向:具有累积旋转的3x3矩阵,其中“累积”表示重复的矩阵乘积。

第三个变量将是船舶所面对的方向,但这不是必需的,因为它可以通过初始方向(列向量[] 1;0;0])乘以当前方向来获得。也就是说,方向的第一列。

这两个状态变量保存在堆栈中,并随每个字母更新。每个字母ULlDRr将方向矩阵乘以六个旋转矩阵之一以更新方向。Letter F将当前位置加上方向矩阵的第一列。

六个旋转矩阵的创建如下:首先直接引入;第二和第三是前一个的循环移位;其余三个是其他版本的转置版本。

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.