Prenez une grille à 2 dimensions et dessinez dessus un certain nombre de segments de lignes pour représenter les miroirs. Maintenant, choisissez un point pour placer un laser théorique et un angle pour définir la direction vers laquelle il pointe. La question qui se pose est la suivante: si vous suivez le trajet du faisceau laser sur une certaine distance, à quel point de coordonnées vous trouvez-vous?
Exemple:
Dans cette image, L
est l'emplacement du laser, t
est l' angle de ce (mesuré à partir de l'axe X positif), M1
, M2
et M3
sont tous les miroirs de segment de ligne, et E
est le point situé sur le trajet du faisceau laser après D = d1 + d2 + d3 + d4
unités, à partir de L
.
Objectif
Ecrire le programme le plus court (en octets) que les résultats E
donnés L
, t
, D
et une liste de miroirs.
(Utilisez http://mothereff.in/byte-counter pour compter les octets.)
Format d'entrée
L'entrée viendra de stdin au format:
Lx Ly t D M1x1 M1y1 M1x2 M1y2 M2x1 M2y1 M2x2 M2y2 ...
- Toutes les valeurs seront flottants pour cette regex:
[-+]?[0-9]*\.?[0-9]+
. - Il y a toujours exactement un espace entre chaque numéro.
- Exiger des guillemets autour de l'entrée est autorisé.
t
est en degrés, mais pas nécessairement dans la[0, 360)
gamme. (Si vous préférez, vous pouvez utiliser des radians, dites simplement cela dans votre réponse.)D
peut être négatif, faisant effectivement pivoter le laser à 180 degrés.D
peut aussi être 0.- Il peut y avoir arbitrairement beaucoup de miroirs (dont aucun du tout).
- L'ordre des miroirs ne devrait pas avoir d'importance.
- Vous pouvez supposer que l'entrée viendra en multiples de 4 chiffres. par exemple
Lx Ly t
ouLx Ly t D M1x1
sont invalides et ne seront pas testés. Aucune entrée n'est également invalide.
La mise en page ci-dessus peut être entrée en tant que:
1 1 430 17 4.8 6.3 6.2 5.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
(Notez que l'image a été dessinée à main levée et que ces valeurs ne sont que des approximations. Les valeurs d'entrée de Martin Büttner:
1 1 430 17 4.8 5.3 6.2 4.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
donnera plus de collisions bien qu'elles ne correspondent pas à l'esquisse.)
Format de sortie
La sortie devrait aller à stdout au format:
Ex Ey
Ce sont aussi des flotteurs et peuvent être sous forme exponentielle.
Remarques
- Les miroirs peuvent se croiser.
- Les deux côtés des miroirs sont réfléchissants.
- Le faisceau peut heurter plusieurs fois le même miroir.
- Le faisceau continue pour toujours.
Cas non définis
Vous pouvez supposer que les cas où
- le laser démarre sur un segment de droite en miroir
- le faisceau laser atteint l'extrémité d'un miroir
- le faisceau laser frappe l'intersection entre deux miroirs
ne sont pas définis et ne seront pas testés. Votre programme peut faire n'importe quoi si cela se produit, y compris une erreur.
Prime
Juste pour le plaisir, je vais attribuer 200 points de prime à la soumission la plus votée qui produit une représentation graphique du problème (vous pouvez même écrire un script interactif). Ces bonus ne doivent pas nécessairement être joués et peuvent être indulgents avec la manière dont les entrées et les sorties sont gérées. Ils sont distincts des soumissions golfées mais les deux doivent être soumis dans la même réponse .
Remarque: soumettre uniquement une réponse en prime suffit, vous ne serez pas la réponse acceptée. Pour être accepté, vous devez suivre exactement les spécifications d'entrée / sortie (par exemple, la sortie implique uniquement Ex Ey
, pas les images), et être le plus court.
Réponses:
Ruby, 327 octets
(défiler vers le bas)
Mathematica, réponse bonus
Je vais seulement pour la soumission graphique pour le moment. Je pourrais porter ça à Ruby plus tard et jouer au golf si j'en ai envie.
Vous pouvez l'appeler comme
Cela vous donnera une animation dans Mathematica et exportera également un fichier GIF (celui du haut pour cette entrée). J'ai légèrement développé l'exemple des PO pour cela, pour le rendre un peu plus intéressant.
Plus d'exemples
Un tube avec des parois légèrement divergentes mais une extrémité fermée:
Un triangle équilatéral et une direction initiale presque parallèle à l’un des côtés.
Un de plus:
Ruby, réponse au golf
Il s’agit essentiellement d’une traduction directe de la solution Mathematica en Ruby, ainsi que de la pratique du golf et de la vérification du respect des critères d’entrée / sortie.
la source
Python 3 (
421C 390C, 366C)Utilisez
builtin.complex
comme vecteur 2D. AlorsAfin de battre la solution 368C Ruby, j'ai trouvé une méthode assez compacte pour calculer la réflexion ponctuelle le long d'un miroir. Et aussi utilisé une algèbre complexe pour réduire plus de caractères. Ceux-ci peuvent être facilement trouvés dans le code non-golfé.
Voici la version golfée.
Ungolfed
Bonus: HTML, Coffeescript, ajustement et calcul en temps réel
C’est-à-dire que vous faites glisser les points de fin (ou les miroirs), puis la piste est rendue. Il prend également en charge deux types d'entrées, celle décrite dans la question et celle utilisée par @Martin Büttner.
La mise à l'échelle est également ajustée automatiquement.
Pour l'instant, il n'y a pas d'animation. Peut-être que je l'améliorerai plus tard. Cependant, en faisant glisser les points blancs, vous pouvez voir un autre type d'animation. Essayez-le en ligne ici vous-même, c'est drôle!
L'ensemble du projet peut être trouvé ici
Mise à jour
Ici, je fournis un cas intéressant:
Et le résultat est:
la source
HTML JavaScript,
10 543,947889J'ai corrigé un bogue et je me suis assuré que la sortie répond à la spécification de la question. La page Web ci-dessous contient la version avec golf et la version avec bonus graphique. J'ai aussi corrigé un bug signalé par @Ray qui enregistrait 58 caractères. (Merci Ray.) Vous pouvez également exécuter le code de jeu dans une console JavaScript. (J'utilise maintenant un laser vert de 2 mW.)
Code de golf
Contribution
Sortie
Vous pouvez le tester ici: http://goo.gl/wKgIKD
Explication
Le code de la page Web est commenté. Fondamentalement, je calcule l'intersection du laser avec chaque miroir en supposant que le laser et les miroirs sont infiniment longs. Ensuite, je vérifie si l'intersection est comprise dans la longueur finie du miroir et du laser. Ensuite, je prends l'intersection la plus proche, déplace le laser à ce point et continue jusqu'à ce que le laser manque tous les miroirs.
Projet très amusant. Merci d'avoir posé cette question!
Code lisible
la source
0 0 0.4 100 1 1 1 -1 1 -1 -1 -1 -1 -1 -1 1 -1 1 1 1
.Python - 765
Bon challenge. C'est ma solution qui reçoit les entrées de stdin et les sorties sur stdout. En utilisant l'exemple de @Martin Büttner:
Voici le code golfé:
Et voici le code non-golfé avec un chiffre bonus
la source
sys.argv
n'est pas stdin.Matlab (388)
Terrain
Concepts
Points de réflexion
Pour calculer les points de réflexion, nous devons fondamentalement intersecter deux lignes droites. L'un avec le point p0 et le vecteur v, l'autre entre les deux points p1, p2. Donc l'équation à résoudre est (s, t sont des paramètres): p0 + t v = s p1 + (1-s) * p2.
Le paramètre s est alors une coordonnée barycentrique du miroir donc si 0
En miroir
La mise en miroir de v est assez simple. Supposons que || v || = || n || = 1 où n est le vecteur normal du miroir actuel. Ensuite, vous pouvez simplement utiliser la formule v: = v-2 ** n où <,> est le produit scalaire.
Validité de l'étape
Lors du calcul du miroir 'valide' le plus proche, nous devons considérer certains critères le rendant valide. Tout d'abord, le point d'interception du miroir doit se situer entre les deux extrémités, il doit donc être 0
Programme
Un peu de golf (388)
la source