Basé sur une idée suggérée par Zgarb .
Un vaisseau spatial se déplace autour d'une grille 3D régulière. Les cellules de la grille sont indexées avec des entiers dans un système de coordonnées droitier, xyz . Le vaisseau spatial commence à l'origine, pointant le long de l' axe x positif , l' axe z positif pointant vers le haut.
Le vaisseau spatial volera le long d'une trajectoire définie par une séquence de mouvements non vide. Chaque mouvement se fait soit F
( ou vers l' intérieur) ce qui fait que le vaisseau spatial se déplace d'une cellule dans la direction de son orientation, ou l'une des six rotations UDLRlr
. Cela correspond au tangage, au lacet et au roulis comme suit:
Merci à Zgarb d'avoir créé le diagramme.
U
p etD
propre modifient l'inclinaison du vaisseau spatial de 90 degrés (où la direction correspond au mouvement du nez du vaisseau spatial).L
eft etR
ight modifient le lacet du vaisseau spatial de 90 degrés. Ce ne sont que des virages à gauche et à droite réguliers.l
eft etr
ight sont des mouvements de roulement à 90 degrés, où la direction indique quelle aile se déplace vers le bas.
Notez que ceux-ci doivent toujours être interprétés par rapport au vaisseau spatial afin que les axes concernés tournent avec lui.
En termes mathématiques, le vaisseau spatial est initialement en position (0, 0, 0)
, pointant le long du (1, 0, 0)
vecteur, (0, 0, 1)
pointant vers le haut. Les rotations correspondent aux matrices suivantes appliquées au système de coordonnées:
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 )
Vous devez afficher la position finale du vaisseau spatial sous la forme de trois entiers x , y , z . La sortie peut être trois entiers distincts ou une liste ou une chaîne les contenant. Ils peuvent être dans n'importe quel ordre cohérent tant que vous le spécifiez.
Vous pouvez écrire un programme ou une fonction, en prenant une entrée via STDIN (ou l'alternative la plus proche), un argument de ligne de commande ou un argument de fonction et en sortant le résultat via STDOUT (ou l'alternative la plus proche), la valeur de retour de la fonction ou le paramètre de la fonction (out).
Les règles de code-golf standard s'appliquent.
Cas de test
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)
Exemple travaillé
Voici les étapes intermédiaires du UFLrRFLRLR
cas de test. Ici, toutes les coordonnées intermédiaires et les vecteurs de direction sont donnés dans le système de coordonnées global initial (par opposition à un local du vaisseau spatial):
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)
Réponses:
MATL ,
7675 octetsCela fonctionne dans la version actuelle (12.1.1) de la langue.
Edit (4 avril 2016): Le comportement de la fonction
v
a changé dans la version 15.0.0 du langage. Pour exécuter le code ci-dessus, supprimez le premierv
et remplacez le second3$v
. Le lien suivant inclut cette modification.Essayez-le en ligne !
Explication
L'état du navire peut être décrit en fonction de deux variables:
Une troisième variable serait la direction dans laquelle le navire fait face, mais ce n'est pas nécessaire, car elle peut être obtenue en tant que direction initiale (vecteur de colonne [
1;0;0]
) multiplié par l'orientation actuelle; c'est-à-dire la première colonne de l'orientation.Ces deux variables d'état sont conservées dans la pile et sont mises à jour avec chaque lettre. Chacune des lettres
ULlDRr
multiplie la matrice d'orientation par l'une des six matrices de rotation pour mettre à jour l'orientation. La lettreF
ajoute la position actuelle plus la première colonne de la matrice d'orientation.Les six matrices de rotation sont créées comme suit: la première est introduite directement; les deuxième et troisième sont des décalages circulaires du précédent; et les trois autres sont des versions transposées des autres.
la source
Octave, 175 octets
Version lisible:
la source
ES6,
265259 octetsExplication: Normalement, pour calculer la direction du vaisseau spatial, vous composeriez toutes les rotations ensemble, puis pour chaque mouvement, vous composeriez le résultat vers le vecteur unitaire
F = (1, 0, 0)
(ou plus simplement extraire la première colonne de la matrice). Par exemple,FFrlFULULF => F + F + r⋅l⋅F + r⋅l⋅U⋅L⋅L⋅L⋅F
. Comme la multiplication matricielle est associative, les langages avec multiplication matricielle intégrée peuvent évidemment calculer le produit partiel aur⋅l⋅U⋅L⋅L⋅L
fur et à mesure, en multipliant parF
autant que nécessaire pour produire les termes qui sont ensuite additionnés. Malheureusement, je n'ai pas ce luxe, donc l'option la moins chère est de calculer chaque terme dans l'expression ci-dessus séparément, en commençant parF
et en revenant. Pour cela, j'ai besoin d'une liste pour chacune des occurrencesF
de toutes les rotations jusqu'à ce point. Je le fais en utilisantreplace
avec$`
donc je dois également marquer le début et la fin de chaque terme dans la liste afin que je puisse ignorer le reste de la chaîne. Légèrement non golfé:la source