Mój robot uciekł z laboratorium!

13

Mój robot jakoś zwarł i przypadkowo uciekł gdzieś z mojego laboratorium!

Na szczęście za każdym razem, gdy to robi, rozpoczyna się sekwencja wyłączania, dająca mu wystarczająco dużo czasu, aby losowo się odwrócił i pobiegł w kierunku przeciwległym przez pięć rund, zanim się wyłączy. Jego żyroskop i funkcje akcelerometru nadal przekazują dane z powrotem do laboratorium, gdy on jest nadal włączony.

Dane zawsze będą miały na przykład postać pięciu zestawów dwóch liczb.

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

Twoja misja, golfiści, to: a) zasymulować szaleńczą sekwencję biegu i obrotu robota, wyświetlając pięć zestawów liczb w postaci a1:d1,a2:d2,a3:d3,a4:d4,a5:d5gdzie a(n) jest kątem zgodnym z ruchem wskazówek zegara (w stopniach), dzięki -179<=a<=+180czemu robot skręci z bieżącego kierunku ( początkowo ma zerowy kurs, zanim zacznie amok i skręci po raz pierwszy), oraz d(n) jest odległością w stopach, jaką przebył przed następną zmianą kursu, czyli 0<=d<=500stopami; oraz b) Obliczony kurs z laboratorium (który również jest skierowany na pozycję zerową), odległość w stopach (zdecydowanie zaleca się dokładność do 3 miejsc po przecinku, -5 bajtów, jeśli tak się dzieje), a także orientacja (w stopniach) gdzie stoi mój robot, gdy się wyłączył.

Prosty przykład:

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

Losowe zakręty i odległości są po prostu losowe. Żadne ustawione wartości nie mają być zakodowane na stałe, musimy zobaczyć losowość działania w kodzie.

Ograniczenia losowości: Brak odwołań opartych na zegarze lub dacie, musimy zobaczyć natywne randomodwołanie w kodzie. Ilekroć uruchamiasz ten kod, losowość musi przedstawiać się z możliwością pokazania 1 z 360 możliwych kątów skrętu przy każdej rundzie. Tak więc robot może obrócić o -36 stopni za jednym obrotem i może obrócić o +157 stopni za następnym, a następnie o kolejny obrót o +2 stopnie o kolejny obrót o -116 stopni i końcowy obrót o +42 stopnie przy ostatnim zwoju. Przy każdym losowym generowaniu kąta muszą być możliwe co najmniej 360 różnych wartości (od -179 do +180 stopni włącznie).

Ograniczenia biegu na odległość: Podobnie ustawione, istnieje 501 możliwych odległości, które robot może przejechać (od 0 do 500 stóp włącznie), więc spodziewam się, że losowość będzie dostępna również przy określaniu odległości biegu robota. Robot mógłby teoretycznie przejechać 45, 117, 364, 27 i 6 stóp z każdą z odpowiednich rund ...

Dostarczone dane będą zawsze w liczbach całkowitych ... robot skręci w całkowitych zakresach stopni i będzie działał w całkowitych zakresach odległości. Wartości wyjściowe będą jednak zmiennoprzecinkowe ...

To jest golf golfowy. Najkrótszy kod wygrywa ... Teraz idź znajdź mojego robota!

PS: W odniesieniu do mojej „Dokładności do 3 miejsc po przecinku”, jeśli możesz podać nagłówek (w stopniach, do MINIMUM 3 miejsc po przecinku) i odległość w stopach (również dokładna do MINIMUM 3 miejsc po przecinku) dostanie premię -5 bajtów).

WallyWest
źródło
1
@ IsmaelMiguel i @OP - Prawdopodobnie zostanę postrzelony za to, ale czy nie mógłbyś użyć tego -180 < a <= +180jako <znaku jako takiego, oznacza mniej niż, ale nie wliczając AFAIK ...
George
1
@GeorgeH Masz rację, ale to, co mówi WallyWest, jest złe. „-179 <= a <= 180 daje wszystkie 360 ​​możliwych nagłówków liczb całkowitych” -> to źle, ponieważ jest 361 nagłówków. Czy robot nie może przejść do -180º?
Ismael Miguel
1
@IsmaelMiguel Dopuszczalne jest odchylenie -180 stopni, ponieważ jest to dokładnie to samo co 180.
Klamka
1
To jest złe. + 180º oznacza pół obrotu w prawo. -180º oznacza pół obrotu w lewo (lub w lewo, jak wolisz). jeśli zakres wynosi -179 <= a <= + 180, robot nie może obrócić o 180º w kierunku przeciwnym do ruchu wskazówek zegara. Dlaczego? Utknie w temperaturze -179º! Może dlatego miał zwarcie ...
Ismael Miguel
1
@WallyWest Nie jestem głupi i rozumiem, co masz na myśli. Mówię tylko, że zakres powinien zostać ustalony.
Ismael Miguel

Odpowiedzi:

2

Perl 6: 188 184 znaków - 5 = 180 punktów

$_=((-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 z białymi znakami:

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

Nie golfowany:

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

Ten zamienia dane w liczbach zespolonych z unpolar, wkłada je do sumy $complex, a następnie pobiera współrzędne polarne jak $dist, $ang.

Kąt skumulowany $cum-anglejest zbierany, ponieważ kąty odnoszą się do robota poruszającego się w laboratorium i ponieważ potrzebujemy końcowego kąta robota w naszej wydajności.

Przykładowe dane wyjściowe:

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

Jedyną prawdziwą sztuczką, jakiej używa golf, jest to, że (źle) wykorzystuje wszystkie 3 specjalne zmienne Perla 6, aby uzyskać dobry efekt:

  • $! jest stosowany dla radianów ↔ stopni
  • $_przechowuje dane i wszystko, co wygląda na samotne, w .method()rzeczywistości oznacza $_.method()(z wyjątkiem wewnątrz map {…}bloku, gdzie $_faktycznie przyjmuje wartość par liczb, które składają się na dane)
  • $/zawiera to, co jest w wersji bez golfa ($dist, $ang). $0i $1faktycznie oznacza $/[0], tj. $disti $/[1], tj.$ang
Mouq
źródło
Ładny! Nadal możesz zejść z 188 do 184 w następujący sposób:$_=((-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, nice find! Dzięki! Niestety, miejsce po .map:jest obowiązkowe
Mouq
Och, myliłem się co do miejsca, fajnie :)
Mouq
10

Rubinowy, 274 252 249 245 214 211 207 204 202 znaków (-5 = 197)

W jaki sposób PHP pokonało Ruby w char? >: O Musisz znaleźć sposób na golfa więcej ...

Edycja: Pobiłem odpowiedź PHP, ale użytkownik, który ją napisał, pomógł mi to zrobić! Głosujcie do niego; zasługuje na to :-P

Kolejna edycja: Gah! Minął mnie ponownie! Jesteś bardzo godnym przeciwnikiem, @MathieuRodic; gratulacje, muszę pozwolić ci wygrać ;-)

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

Kod niepolecany (i nieco dużo starsza wersja):

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

Przykładowe dane wyjściowe:

c:\a\ruby>robotgolf
Data: 94:26,175:332,14:390,159:448,-45:20
Heading: 124.52305879195005
Distance: 279.5742334385328
Orientation: 397
Klamka
źródło
Jak robot skierowany jest na północ po obróceniu pięciu losowych kątów?
WallyWest
@WallyWest Miałem wrażenie, że orientacja oznacza kąt początkowy robota, prawda? Mógłbym wyznaczyć kąt końcowy tylko dla 3 dodatkowych znaków.
Klamka
Nie, zawsze jest skierowany na północ (pozycja 0) przy wykonywaniu kodu ... Potem obraca się, biegnie, obraca się, biegnie, obraca się, biegnie, obraca się, biegnie, obraca się, a następnie biegnie ... zanim się wyłączy. Będzie musiał mieć końcowy kąt, który jest skierowany w Orientationprzekroju.
WallyWest
@WallyWest Ah, dobra, zredagowane. Czy jest w porządku, jeśli orientacja nie jest w zakresie 0 ... 360, czy też musimy to zrobić % 360?
Klamka
Możesz zapisać 11 znaków, odpowiednio deklarując M=Mathi P=M::PIzamieniając kod - i jeszcze jeden znak, pozbywając się miejsca po drugim puts.
David Herrmann
5

PHP - 238 232 221 212 203 199 znaków

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

(przetestuj tutaj: http://ideone.com/dNZnKX )

Wersja bez gry w golfa:

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

(przetestuj tutaj: http://ideone.com/1HzWH7 )

Mathieu Rodic
źródło
Wygląda na to, że Perl po prostu ledwo nas pokonał w ostatniej chwili. : -O
Klamka
@Doorknob Tak, przepraszam :)
Mouq
Zdecydowanie. Mouq, zniszczyłeś wszystkie nasze wysiłki tylko 188 ...
Mathieu Rodic
3

Python - 264 259 256 258 - 5 = 253 znaków

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

(przetestuj na http://ideone.com/FicW6e )

Wersja bez golfa:

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

(przetestuj na http://ideone.com/O3PP7T )

Uwaga: wiele odpowiedzi zawiera w tytule -5 , a ich program nie oddaje odległości z dokładnością do 3 miejsc po przecinku ...

Mathieu Rodic
źródło
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

Nie ma tu nic nadzwyczajnego, raczej gadatliwy. Jest to jeden problem, z którego nie jestem zadowolony, że funkcje trygonowe Pythona działają w radianach.

> 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
źródło
0

Python 2 = 376 319 znaków (-5 dla odległości = 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)

próbka wyjściowa

-141:245, 56:355, 145:223, -10:80, -38:253,
Heading: 12
Distance: 559.031404
Orientation: -2
Brian
źródło
Python wykonuje obliczenia trygonometryczne za pomocą radianów, a nie stopni. Dlatego twoje obliczenia są prawdopodobnie błędne ...
Mathieu Rodic