ยานอวกาศไปไหน


15

ขึ้นอยู่กับความคิดที่แนะนำโดยZgarb

ยานอวกาศกำลังเคลื่อนที่รอบกริด 3D ปกติ เซลล์ของตารางที่มีการจัดทำดัชนีที่มีจำนวนเต็มในมือขวาระบบพิกัดxyz ยานอวกาศเริ่มต้นที่จุดกำเนิดโดยชี้ไปตามแกนxบวกโดยที่แกนzบวกชี้ขึ้น

ยานอวกาศจะบินไปตามเส้นทางที่กำหนดโดยลำดับการเคลื่อนที่ที่ไม่ว่างเปล่า การเคลื่อนไหวแต่ละอย่างใดอย่างหนึ่งF(orward) UDLRlrซึ่งทำให้ยานอวกาศย้ายเซลล์หนึ่งในทิศทางที่หันหน้าไปทางของตนหรือหนึ่งในหกของการหมุน สิ่งเหล่านี้สอดคล้องกับ pitch, yaw และ roll ดังนี้:

PYR
ขอบคุณ Zgarb ที่สร้างไดอะแกรม

  • UและDเปลี่ยนระดับของยานอวกาศ 90 องศา (ซึ่งทิศทางนั้นสอดคล้องกับการเคลื่อนไหวของจมูกของยานอวกาศ)
  • Left and Right เปลี่ยนความเอียงของยานอวกาศ 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 )

คุณควรส่งออกตำแหน่งสุดท้ายของยานอวกาศสามจำนวนเต็มx , Y , Z ผลลัพธ์อาจเป็นจำนวนเต็มสามจำนวนที่แยกกันหรือรายการหรือสตริงที่มีอยู่ อาจอยู่ในลำดับที่สอดคล้องกันตราบใดที่คุณระบุ

คุณสามารถเขียนโปรแกรมหรือฟังก์ชั่น, รับอินพุตผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด), อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ฟังก์ชันและส่งผลลัพธ์ผ่าน STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

ใช้กฎมาตรฐานของ

กรณีทดสอบ

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 มิติของสิ่งนี้ลบส่วนที่ตัดกัน
orlp

ทำไม 2! = 2, 3! = -1, 4! = 0! = -4, 1! = -3
ชื่อผู้ใช้

@ username.ak ฉันไม่คิดว่าฉันเข้าใจคำถาม คุณหมายถึงอะไร
Martin Ender

@ มาร์ตินBüttnerฉันพูดว่าทำไมการหมุน 180 องศาไม่เหมือนกับ -180, 270 ไม่เหมือนกับ -90 เป็นต้น
username.ak

@ username.ak ใช่ไหม?
Martin Ender

คำตอบ:


3

MATL , 76 75 ไบต์

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

ใช้ได้กับภาษาปัจจุบัน (12.1.1)

แก้ไข (4 เมษายน 2016): พฤติกรรมของฟังก์ชั่นvมีการเปลี่ยนแปลงในรุ่น 15.0.0 ของภาษา เพื่อให้รหัสระยะข้างต้นลบครั้งแรกและแทนที่สองv 3$vลิงค์ต่อไปนี้มีการดัดแปลงนี้

ลองออนไลน์ !

คำอธิบาย

สถานะของเรือสามารถอธิบายได้ในแง่ของตัวแปรสองตัว:

  • ตำแหน่ง: 3x1 เวกเตอร์
  • การวางแนว: เมทริกซ์ 3x3 พร้อมการหมุนแบบสะสมโดยที่ "สะสม" หมายถึงผลิตภัณฑ์เมทริกซ์ซ้ำ

ตัวแปรที่สามจะเป็นทิศทางที่เรือเผชิญ แต่ไม่จำเป็นเพราะมันสามารถรับได้ในทิศทางเริ่มต้น (เวกเตอร์คอลัมน์ [ 1;0;0]) คูณการวางแนวปัจจุบัน นั่นคือคอลัมน์แรกของการวางแนว

ตัวแปรสถานะทั้งสองนี้จะถูกเก็บไว้ในสแต็กและได้รับการอัพเดตด้วยตัวอักษรแต่ละตัว ตัวอักษรแต่ละตัวULlDRrคูณเมทริกซ์ปฐมนิเทศโดยเมทริกซ์การหมุนหนึ่งในหกตัวเพื่ออัพเดทการวางแนว ตัวอักษร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

ใช้ชื่อฟิลด์แบบไดนามิกได้อย่างดี!
Luis Mendo

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ด้วย$`ดังนั้นฉันยังต้องทำเครื่องหมายจุดเริ่มต้นและจุดสิ้นสุดของแต่ละคำในรายการเพื่อให้ฉันสามารถละเว้นส่วนที่เหลือของสตริง ungolfed เล็กน้อย:

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.