¡Mi robot ha escapado del laboratorio!

13

¡Mi robot ha hecho un cortocircuito de alguna manera y se alejó al azar de mi laboratorio!

Afortunadamente, cada vez que hace esto, se inicia su secuencia de apagado, dándole el tiempo suficiente para girar al azar y correr en la dirección que enfrenta durante cinco rondas antes de que se apague. Sus funciones de giroscopio y acelerómetro aún transmiten los datos al laboratorio mientras aún está encendido.

Los datos siempre vendrán en forma de cinco conjuntos de dos números, por ejemplo.

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

Su misión, los golfistas, es a) simular la frenética carrera y la secuencia de giro del robot mostrando cinco conjuntos de números en forma de a1:d1,a2:d2,a3:d3,a4:d4,a5:d5donde a(n) es el ángulo en el sentido de las agujas del reloj (en grados) de modo -179<=a<=+180que el robot gire desde su rumbo actual ( inicialmente está en rumbo cero antes de que se vuelva loco y gire por primera vez), y d(n) es la distancia en pies que ha corrido antes del siguiente cambio de rumbo que es tal que 0<=d<=500pies; y b) un rumbo calculado del laboratorio (que también enfrenta un rumbo de cero), la distancia en pies (se recomienda una precisión de hasta 3 decimales, -5 bytes si lo hace) y el rumbo de orientación (en grados) de dónde está mi robot cuando se apaga.

Ejemplo fácil:

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

Los giros y distancias al azar son solo eso, al azar. No se deben codificar los valores establecidos, debemos ver la aleatoriedad en acción dentro del código.

Restricciones a la aleatoriedad: sin referencias basadas en reloj o fecha, necesitamos ver una randomreferencia nativa dentro del código. Cada vez que ejecute este código, la aleatoriedad debe presentarse con la posibilidad de mostrar 1 de 360 ​​ángulos posibles de giro con cada vuelta. Entonces, el robot puede girar -36 grados en una vuelta y puede girar +157 grados en la siguiente, seguido de otra vuelta de +2 grados por otra vuelta de -116 grados y una vuelta final de +42 grados en la vuelta final. Deben ser posibles al menos 360 valores distintos (entre -179 y +180 grados inclusive) con cada generación de ángulo aleatorio.

Restricciones a la carrera de distancia: de manera similar, hay 501 distancias posibles que el robot puede correr (entre 0 y 500 pies inclusive), por lo que espero que la aleatoriedad también esté disponible al determinar la distancia de carrera del robot. El robot podría correr teóricamente 45, 117, 364, 27 y 6 pies con cada una de sus rondas respectivas ...

Los datos que se le proporcionen siempre estarán en valores enteros ... el robot girará en rangos enteros de grados y se ejecutará en rangos enteros de distancia. Sin embargo, los valores de salida serán flotantes ...

Este es el código de golf. El código más corto gana ... ¡Ahora ve a buscar mi robot!

PD: En referencia a mi "Precisión de hasta 3 lugares decimales", si puede proporcionar el rumbo (en grados, a un MÍNIMO de 3 lugares decimales) y una distancia en pies (también precisa también a un mínimo de 3 lugares decimales) obtendrá un bono de -5 bytes).

WallyWest
fuente
1
@IsmaelMiguel y @OP: probablemente me dispararán por esto, pero ¿no podría usarlo -180 < a <= +180como el <signo por sí solo significa menos pero no incluye AFAIK ...
George
1
@GeorgeH Tienes razón, pero lo que WallyWest dice es incorrecto. "-179 <= a <= 180 da como resultado los 360 encabezados enteros posibles" -> esto está mal porque hay 361 encabezados. ¿O el robot no puede ir a -180º?
Ismael Miguel
1
@IsmaelMiguel Se permite subir -180 grados, porque eso es exactamente lo mismo que 180.
Pomo de la puerta
1
Eso está mal. + 180º significa media vuelta en sentido horario. -180º significa media vuelta en sentido antihorario (o en sentido antihorario, como prefiera). si el rango es -179 <= a <= + 180, el robot no puede girar 180º en sentido antihorario. ¿Por qué? ¡Se quedará atrapado a -179º! Tal vez por eso tuvo un corto circuito ...
Ismael Miguel
1
@WallyWest No soy estúpido y entiendo lo que quieres decir. Solo digo que el rango debería ser fijo.
Ismael Miguel

Respuestas:

2

Perl 6: 188 184 caracteres - 5 = 180 puntos

$_=((-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 con espacios en blanco:

$_ = ((-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*$!}"

Sin 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.㎭;

Esto convierte los datos en números complejos con unpolar, pone la suma de ellos $complexy luego obtiene las coordenadas polares como$dist , $ang.

El ángulo acumulativo $cum-angle se recopila porque los ángulos son relativos al robot a medida que se mueve a través del laboratorio y porque necesitamos el ángulo final del robot en nuestra salida.

Salida de muestra:

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

El único truco real que usa el golf es que (mal) usa las 3 variables especiales de Perl 6 con buenos resultados:

  • $! se usa para radianes ↔ grados
  • $_contiene los datos, y cualquier cosa que parezca un solitario .method()realmente significa $_.method()(excepto dentro del map {…}bloque, donde$_ realmente toma el valor de los pares de números que componen los datos)
  • $/contiene lo que hay en la versión sin golf ($dist, $ang). $0y en $1realidad significa $/[0], es decir $dist, y $/[1], es decir,$ang
Mouq
fuente
¡Agradable! Todavía puede bajar de 188 a 184 así:$_=((-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, buen hallazgo! ¡Gracias! Desafortunadamente, el espacio posterior .map:es obligatorio
Mouq
Oh, estaba equivocado sobre el espacio, genial :)
Mouq
10

Rubí, 274 252 249 245 214 211 207 204 202 caracteres (-5 = 197)

¿Cómo PHP venció a Ruby en el recuento de char? >: O Debo encontrar alguna manera de jugar al golf más ...

Editar: superé la respuesta de PHP, ¡pero el usuario que la escribió me ayudó a hacerlo! Ve a votarlo; se lo merece :-P

Otra edición: Gah! ¡Me pasó de nuevo! Eres un oponente muy digno, @MathieuRodic; felicidades, tengo que dejarte ganar ;-)

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}"

Código no protegido (y versión ligeramente más antigua):

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}"

Salida de muestra:

c:\a\ruby>robotgolf
Data: 94:26,175:332,14:390,159:448,-45:20
Heading: 124.52305879195005
Distance: 279.5742334385328
Orientation: 397
Pomo de la puerta
fuente
¿Cómo se enfrenta el robot al norte después de haber girado cinco ángulos aleatorios?
WallyWest
@WallyWest Tenía la impresión de que la orientación marca el ángulo inicial del robot, ¿correcto? Podría hacer que marque el ángulo final para solo 3 caracteres adicionales.
Pomo de la puerta
No, siempre está orientado hacia el norte (rumbo 0) en la ejecución del código ... Luego gira, corre, gira, corre, gira, corre, gira, corre, gira y luego corre ... antes de apagarse. Tendrá que tener el ángulo final que enfrenta en la Orientationsección.
WallyWest
@WallyWest Ah, está bien, editado. ¿Está bien si la orientación no está en 0 ... 360, o tenemos que hacer una % 360?
Pomo de la puerta
Puede guardar 11 caracteres declarando M=Mathy P=M::PIreemplazando el código en consecuencia, y un carácter más al deshacerse del espacio después del segundo puts.
David Herrmann
5

PHP - 238 232 221 212 203 199 caracteres

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

(pruébelo aquí: http://ideone.com/dNZnKX )

Versión sin golf:

$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";

(pruébelo aquí: http://ideone.com/1HzWH7 )

Mathieu Rodic
fuente
Parece que Perl nos golpeó por poco a ambos en el último minuto. : -O
Pomo de la puerta
@Doorknob Sí, lo siento :)
Mouq
Seguro. Mouq, acabaste con todos nuestros esfuerzos con solo 188 ...
Mathieu Rodic
3

Python - 264 259 256 258 - 5 = 253 caracteres

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))

(pruébelo en http://ideone.com/FicW6e )

Versión sin golf:

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))

(pruébelo en http://ideone.com/O3PP7T )

NB: muchas respuestas incluyen -5 en su título, mientras que su programa no representa la distancia con precisión de hasta 3 decimales ...

Mathieu Rodic
fuente
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

Nada demasiado elegante aquí, más bien detallado. Este es un problema para el que no estoy contento de que las funciones trigonométricas de Python funcionen en radianes.

> 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
fuente
0

Python 2 = 376 319 caracteres (-5 para distancia = 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)

salida de muestra

-141:245, 56:355, 145:223, -10:80, -38:253,
Heading: 12
Distance: 559.031404
Orientation: -2
Brian
fuente
Python hace cálculos de trigonometría con radianes, no con grados. Por lo tanto, sus cálculos probablemente sean incorrectos ...
Mathieu Rodic