Основано на идее, предложенной Згарбом .
Космический корабль движется вокруг обычной трехмерной сетки. Ячейки сетки индексируются целыми числами в правой системе координат xyz . Космический корабль начинается в начале координат, указывая вдоль положительной оси x , с положительным z ось направлена вверх.
Космический корабль будет лететь по траектории, определяемой непустой последовательностью движений. Каждое движение либо F
( или вперед) заставляет космический корабль двигаться на одну клетку в направлении, обращенном к нему, либо на одно из шести вращений UDLRlr
. Они соответствуют тангажу, рысканию и крену следующим образом:
Спасибо Згарбу за создание диаграммы.
U
p иD
собственной изменяют угол наклона космического корабля на 90 градусов (где направление соответствует движению носа космического корабля).L
Eft и ightR
изменяют угол наклона космического корабля на 90 градусов. Они просто обычные левый и правый повороты.l
eft и ightr
- 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 (или ближайшую альтернативу), возвращаемое значение функции или параметр функции (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)
Ответы:
MATL ,
7675 байтЭто работает в текущей версии (12.1.1) языка.
Изменить (4 апреля 2016 г.): Поведение функции
v
изменилось в выпуске 15.0.0 языка. Чтобы запустить приведенный выше код, удалите первоеv
и замените второе3$v
. Следующая ссылка включает в себя эту модификацию.Попробуйте онлайн !
объяснение
Состояние корабля можно описать с помощью двух переменных:
Третья переменная - это направление, в котором стоит корабль, но в этом нет необходимости, поскольку его можно получить как начальное направление (вектор столбца [
1;0;0]
), умноженное на текущую ориентацию; то есть первый столбец ориентации.Эти две переменные состояния хранятся в стеке и обновляются с каждой буквой. Каждая из букв
ULlDRr
умножает матрицу ориентации на одну из шести матриц вращения, чтобы обновить ориентацию. ПисьмоF
добавляет текущую позицию плюс первый столбец матрицы ориентации.Шесть матриц вращения создаются следующим образом: первая вводится напрямую; второе и третье - круговые сдвиги предыдущего; а остальные три являются транспонированными версиями других.
источник
Октава, 175 байт
Читаемая версия:
источник
ES6,
265259 байтОбъяснение: Обычно, чтобы рассчитать направление космического корабля, вы должны составить все повороты вместе, а затем для каждого движения вы будете составлять результат для единичного вектора
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
с,$`
поэтому мне также нужно отметить начало и конец каждого термина в списке, чтобы я мог игнорировать остальные строки. Слегка разгульныйисточник