Mon robot s'est échappé du laboratoire!

13

Mon robot a court-circuité d'une manière ou d'une autre et s'est enfui au hasard quelque part de mon laboratoire!

Heureusement, chaque fois qu'il le fait, sa séquence d'arrêt démarre, ce qui lui donne suffisamment de temps pour se tourner et courir dans le sens de son orientation pendant cinq tours avant de s'éteindre. Ses fonctions de gyroscope et d'accéléromètre relaient toujours les données au laboratoire pendant qu'il est toujours en marche.

Les données viendront toujours sous la forme de cinq ensembles de deux nombres, par exemple.

12:234,-135:47,-68:230,140:324,127,87

Votre mission, les golfeurs est de a) simuler la séquence de course et de virage frénétique du robot en affichant cinq séries de nombres sous la forme a1:d1,a2:d2,a3:d3,a4:d4,a5:d5a(n) est l'angle dans le sens horaire (en degrés) de telle sorte -179<=a<=+180que le robot se détourne de son cap actuel ( au départ, il est à zéro cap avant de s'emballer et de tourner pour la première fois), et d(n) est la distance en pieds qu'il a parcourue avant le changement de cap suivant qui est telle que les 0<=d<=500pieds; et b) Un cap calculé à partir du laboratoire (qui fait également face à un cap de zéro), la distance en pieds (la précision jusqu'à 3 décimales est fortement encouragée, -5 octets si vous le faites) et le cap d'orientation (en degrés) de l'endroit où mon robot est face lorsqu'il s'est éteint.

Exemple simple:

Data: 0:1,45:1,90:1,90:1,90:1
Heading: 0
Distance: 1
Orientation: -45

Les virages et les distances aléatoires ne sont que cela, aléatoires. Aucune valeur définie ne doit être codée en dur, nous devons voir le caractère aléatoire en action dans le code.

Restrictions au caractère aléatoire: pas de références basées sur l'horloge ou la date, nous devons voir une randomréférence native dans le code. Chaque fois que vous exécutez ce code, le caractère aléatoire doit se présenter avec la possibilité d'afficher 1 des 360 angles de virage possibles à chaque tour de virage. Ainsi, le robot peut tourner de -36 degrés à un tour et peut tourner de +157 degrés le suivant, suivi d'un autre tour de +2 degrés par un autre tour de -116 degrés et un dernier tour de +42 degrés au dernier tour. Au moins 360 valeurs distinctes doivent être possibles (entre -179 et +180 degrés inclus) à chaque génération d'angle aléatoire.

Restrictions à la distance parcourue: De même, il y a 501 distances possibles que le robot peut parcourir (entre 0 et 500 pieds inclus), donc je m'attends à ce que l'aléatoire soit également disponible lors de la détermination de la distance de course du robot. Le robot pourrait théoriquement courir 45, 117, 364, 27 et 6 pieds avec chacun de ses tours respectifs ...

Les données qui vous sont fournies seront toujours en valeurs entières ... le robot tournera en plages de degrés entières et fonctionnera en plages de distances entières. Les valeurs de sortie seront cependant des flottants ...

C'est du code-golf. Le code le plus court gagne ... Maintenant, allez chercher mon robot!

PS: En référence à ma "Précision jusqu'à 3 décimales", si vous pouvez fournir le cap (en degrés, jusqu'à un MINIMUM de 3 décimales) et une distance en pieds (également précis aussi pour un MINIMUM de 3 décimales) vous recevra un bonus de -5 octets).

WallyWest
la source
1
@IsmaelMiguel et @OP - Je vais probablement me faire tirer dessus pour cela, mais ne pourriez-vous pas utiliser -180 < a <= +180comme <signe à lui seul moins que mais sans inclure AFAIK ...
George
1
@GeorgeH Vous avez raison, mais ce que WallyWest dit est faux. "-179 <= a <= 180 donne les 360 en-têtes possibles" -> c'est faux car il y a 361 en-têtes. Ou le robot n'est pas autorisé à aller à -180 °?
Ismael Miguel
1
@IsmaelMiguel Il est permis d'aller à -180 degrés, car c'est exactement la même chose que 180.
Poignée de porte
1
C'est faux. + 180º signifie un demi-tour dans le sens horaire. -180º signifie demi-tour dans le sens anti-horaire (ou anti-horaire, comme vous préférez). si la plage est de -179 <= a <= + 180, le robot ne peut pas tourner à 180º dans le sens inverse des aiguilles d'une montre. Pourquoi? Il sera bloqué à -179º! C'est peut-être pour ça qu'il a eu un court-circuit ...
Ismael Miguel
1
@WallyWest Je ne suis pas stupide et je comprends ce que tu veux dire. Je dis simplement que la plage devrait être fixe.
Ismael Miguel

Réponses:

2

Perl 6: 188 184 caractères - 5 = 180 points

$_=((-179..180).pick=>(^501).pick)xx 5;my$o;$/=([+] .map:{unpolar .value,$o+=.key/($!=180/pi)}).polar;say "Data: {.fmt("%d:%d",",")}
Heading: {$1*$!}
Distance: $0
Orientation: {$o*$!}"

Golf avec espace blanc:

$_ = ((-179..180).pick => (^501).pick) xx 5;
my $o;
$/ = ([+] .map: {
    unpolar .value, $o += .key / ($!=180/pi)
}).polar;
say "Data: {.fmt("%d:%d", ",")}
Heading: {$1*$!}
Distance: $0
Orientation: {$o*$!}"

Non golfé:

my &postfix:<°>  = */180*pi; # Deg → Rad
my &postfix:<㎭> = */pi*180; # Rad → Deg

my @data = ((-179..180).pick => (0..500).pick) xx 5;
say "Data: @data.fmt("%d:%d", ",")";

my $cum-angle = 0;
my $complex = [+] @data.map: {unpolar .value, $cum-angle += .key°}
my ($dist, $ang) = $complex.polar;

say "Heading: ",     $ang.㎭;
say "Distance: ",    $dist;
say "Orientation: ", $cum-angle.㎭;

Cela transforme les données en nombres complexes unpolar, met la somme d'entre eux dans $complexet obtient alors les coordonnées polaires comme $dist, $ang.

L'angle cumulé $cum-angleest collecté parce que les angles sont relatifs au robot lorsqu'il se déplace dans le laboratoire et parce que nous avons besoin de l'angle final du robot dans notre sortie.

Exemple de sortie:

Data: -73:230,-144:453,-151:274,-52:232,88:322
Heading: -5.33408558001246
Distance: 378.74631610127
Orientation: -332

Le seul vrai truc que le golf utilise est qu'il utilise (mal) les 3 variables spéciales de Perl 6 à bon escient:

  • $! est utilisé pour les radians ↔ degrés
  • $_contient les données, et tout ce qui ressemble à un solitaire .method()signifie réellement $_.method()(sauf à l'intérieur du map {…}bloc, où $_prend en fait la valeur des paires de nombres qui composent les données)
  • $/contient ce qui est dans la version non golfée ($dist, $ang). $0et $1signifie en fait $/[0], à savoir $dist, et $/[1], à savoir,$ang
Mouq
la source
Agréable! Vous pouvez toujours descendre de 188 à 184 comme ceci:$_=((-179..180).pick=>(^501).pick)xx 5;my$o;$/=([+] .map:{unpolar .value,$o+=.key/($!=180/pi)}).polar;say "Data: {.fmt("%d:%d",",")} Heading: {$1*$!} Distance: $0 Orientation: {$o*$!}"
Mathieu Rodic
@MathieuRodic Oh, belle trouvaille! Merci! Malheureusement, l'espace après .map:est obligatoire
Mouq
Oh, j'avais tort sur l'espace, cool :)
Mouq
10

Rubis, 274 252 249 245 214 211 211 207 204 202 caractères (-5 = 197)

Comment PHP a-t-il battu Ruby en nombre de caractères?! >: O Doit trouver un moyen de jouer au golf plus ...

Edit: j'ai battu la réponse PHP, mais l'utilisateur qui l'a écrit m'a aidé à le faire! Allez le voter; il le mérite :-P

Un autre montage: Gah! Il m'a repassé! Vous êtes un adversaire très digne, @MathieuRodic; félicitations, je dois vous laisser gagner ;-)

P=(M=Math)::PI
puts"Data: #{([x=y=a=0]*5).map{a+=o=rand -179..e=180;x+=M.sin(b=a*P/e)*d=rand 500;y+=d*M.cos b;"#{o}:#{d}"}*?,}
Heading: #{M.atan(y/x)/P*-e+90}
Distance: #{M.hypot x,y}
Orientation: #{a}"

Code non golfé (et version légèrement plus ancienne):

data = Array.new(5) { [rand(-179..180), rand(0..500)] }
puts "Data: #{data.map{|x|"#{x[0]}:#{x[1]}"}.join ?,}"
x, y, a = [0] * 3
data.each do |o, d|
    a += o
    x += Math.sin(a * Math::PI / 180) * d
    y += Math.cos(a * Math::PI / 180) * d
end
puts "Heading: #{Math.atan(y / x) / Math::PI * -180 + 90}
Distance: #{Math.sqrt(x * x + y * y)}
Orientation: #{a}"

Exemple de sortie:

c:\a\ruby>robotgolf
Data: 94:26,175:332,14:390,159:448,-45:20
Heading: 124.52305879195005
Distance: 279.5742334385328
Orientation: 397
Poignée de porte
la source
Comment le robot fait-il face au nord après avoir tourné cinq angles aléatoires?
WallyWest
@WallyWest J'avais l'impression que l'orientation marque l'angle de départ du robot, n'est-ce pas? Je pourrais lui faire marquer l'angle final pour seulement 3 caractères supplémentaires.
Poignée de porte
Non, il est toujours orienté plein nord (cap 0) lors de l'exécution du code ... Puis il tourne, court, tourne, court, tourne, court, tourne, tourne, tourne et tourne ensuite ... avant de s'arrêter. Il devra avoir l'angle final auquel il fait face dans la Orientationsection.
WallyWest
@WallyWest Ah, d'accord, édité. Est-ce que ça va si l'orientation n'est pas dans 0 ... 360, ou devons-nous faire un % 360dessus?
Poignée de porte
Vous pouvez enregistrer 11 caractères en déclarant M=Mathet en P=M::PIremplaçant le code en conséquence - et un caractère de plus en supprimant l'espace après le second puts.
David Herrmann
5

PHP - 238 232 221 212 203 199 caractères

for(;$i<5;$h+=$a=rand(-179,181),$x+=cos($b=$a*$k=M_PI/180)*$l=rand(0,501),$y+=$l*sin($b),$d.=($i++?",":"")."$a:$l");echo"Data: $d
Heading: $h
Distance: ".hypot($x,$y)."
Orientation: ".atan2($y,$x)/$k

(testez-le ici: http://ideone.com/dNZnKX )

Version non golfée:

$k = M_PI / 180;
$h = $x = $y = 0;
$d = "";

for ($i=5; $i--;){
    $h += $a = rand(-179,181);
    $x += ($l = rand(0, 501)) * cos($b = $k * $a);
    $y += $l * sin($b);
    $d .= ($d ? "," : "") . "$a:$l";
}

echo "Data: $d\nHeading: $h\nDistance: " . sqrt($x*$x + $y*$y) ."\nOrientation: " . atan2($y, $x)/$k . "\n";

(testez-le ici: http://ideone.com/1HzWH7 )

Mathieu Rodic
la source
On dirait que Perl nous a battus de justesse tous les deux à la dernière minute. : -O
Poignée de porte
@Doorknob Yup, désolé :)
Mouq
Absolument. Mouq, vous avez en quelque sorte anéanti tous nos efforts avec seulement 188 ...
Mathieu Rodic
3

Python - 264 259 256 258 - 5 = 253 caractères

from math import*;import random as R;r,k,d=R.randint,pi/180,[];h=x=y=0;exec"a,l=r(-179,180),r(0,500);d+=[`a`+':'+`l`];h+=a;x+=l*cos(k*a);y+=l*sin(k*a);"*5;print('Data: %s\nHeading: %d\nDistance: %.3f\nOrientation: %d'%(','.join(d),h,hypot(x,y),atan2(y,x)/k))

(testez-le sur http://ideone.com/FicW6e )

Version non golfée:

from math import *
from random import randrange as r

k = pi / 180
h = x = y = 0
d = []
for i in range(5):
    a = r(-179,181)
    l = r(501)
    d += ['%d:%d' % (a, l)]
    h += a
    x += l * cos(k * a)
    y += l * sin(k * a)

print('Data: %s\nHeading: %d\nDistance: %.3f\nOrientation: %f' % (','.join(d), h, sqrt(x*x+y*y), atan2(y,x)/k))

(testez-le sur http://ideone.com/O3PP7T )

NB: de nombreuses réponses incluent -5 dans leur titre, alors que leur programme ne représente pas la distance avec précision jusqu'à 3 décimales ...

Mathieu Rodic
la source
1

Python 301-5 = 296

from math import*
r=__import__("random").randint
o=x=y=0
s=[]
for i in[0]*5:a=r(-179,180);d=r(0,500);o+=a;o+=180*((o<-179)-(o>180));n=pi*o/180;x+=d*cos(n);y+=d*sin(n);s+=["%d:%d"%(a,d)]
print"Data: "+",".join(s)+"\nHeading: %d"%degrees(atan(y/x))+"\nDistance: %f"%sqrt(x**2+y**2)+"\nOrientation: %d"%o

Rien d'extraordinaire ici, plutôt bavard. C'est un problème pour lequel je ne suis pas heureux que les fonctions trig de python fonctionnent en radians.

> python robot.py
Data: 17:469,110:383,-146:240,-78:493,62:1
Heading: -17
Distance: 405.435748
Orientation: -35
> python robot.py
Data: -119:363,89:217,129:321,10:159,-56:109
Heading: -79
Distance: 130.754395
Orientation: 53
Kaya
la source
0

Python 2 = 376 319 caractères (-5 pour la distance = 314)

import random,math
h=x=y=0
for i in range(5):
    a=random.randint(-179,180)
    d=random.randint(0,500)
    print '%d:%d,'%(a,d),
    h+=a
    if h>180:
        h-=360
    x+=d*math.cos(h)
    y+=d*math.sin(h)
t=math.sqrt(x**2+y**2)
o=math.atan2(y,x)
print
print 'Heading: %d\nDistance: %3f\nOrientation: %d' % (h,t,o)

exemple de sortie

-141:245, 56:355, 145:223, -10:80, -38:253,
Heading: 12
Distance: 559.031404
Orientation: -2
Brian
la source
Python effectue des calculs de trigonométrie avec des radians, pas avec des degrés. Par conséquent, vos calculs sont probablement faux ...
Mathieu Rodic