Meu robô escapou do laboratório!


13

Meu robô entrou em curto-circuito de alguma forma e fugiu aleatoriamente para algum lugar do meu laboratório!

Felizmente, sempre que ele faz isso, sua sequência de desligamento é iniciada, dando-lhe tempo suficiente para virar e correr aleatoriamente na direção em que está por cinco rodadas antes de desligar. Suas funções de giroscópio e acelerômetro ainda estão retransmitindo os dados para o laboratório enquanto ele ainda está ligado.

Os dados sempre virão na forma de cinco conjuntos de dois números, por exemplo.

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

Sua missão, jogadores de golfe, é: a) simular a seqüência frenética de rotação e rotação do robô, exibindo cinco conjuntos de números na forma de a1:d1,a2:d2,a3:d3,a4:d4,a5:d5onde a(n) é o ângulo no sentido horário (em graus), de modo -179<=a<=+180que o robô saia da posição atual ( inicialmente ele está no rumo zero antes de girar pela primeira vez), e d(n) é a distância em pés percorridos antes da próxima mudança de rumo, que é tal que os 0<=d<=500pés; eb) Um cabeçalho calculado do laboratório (que também está voltado para um zero), a distância em pés (precisão de até três casas decimais é fortemente incentivada, -5 bytes, se você o fizer) e o cabeçalho da orientação (em graus) de onde meu robô está voltado quando desligado.

Exemplo fácil:

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

As voltas e distâncias aleatórias são exatamente isso, aleatórias. Nenhum valor definido deve ser codificado, devemos ver a aleatoriedade em ação dentro do código.

Restrições à aleatoriedade: sem referências baseadas em relógio ou data, precisamos ver uma randomreferência nativa dentro do código. Sempre que você executa esse código, a aleatoriedade deve se apresentar com a possibilidade de mostrar 1 de 360 ​​possíveis ângulos de giro com cada rodada de giro. Portanto, o robô pode girar -36 graus em um turno e +157 graus no próximo, seguido por outro turno de +2 graus e outro turno de -116 graus e um turno final de +42 graus no turno final. Pelo menos 360 valores distintos devem ser possíveis (entre -179 a +180 graus, inclusive) a cada geração aleatória de ângulo.

Restrições à distância percorrida: Definidas da mesma forma, existem 501 distâncias possíveis que o robô pode percorrer (entre 0 e 500 pés, inclusive), portanto, espero que a aleatoriedade também esteja disponível ao determinar a distância de corrida do robô. O robô poderia teoricamente executar 45, 117, 364, 27 e 6 pés com cada uma de suas respectivas rodadas ...

Os dados fornecidos a você sempre estarão em valores inteiros ... o robô girará em intervalos inteiros de graus e será executado em intervalos inteiros de distância. Os valores de saída, no entanto, serão flutuantes ...

Isso é código-golfe. O menor código vence ... Agora, encontre o meu robô!

PS: em referência à minha "Precisão de até 3 casas decimais", se você pode fornecer o cabeçalho (em graus, para um MÍNIMO de 3 casas decimais) e uma distância em pés (também precisa também para um mínimo de 3 casas decimais), você receberá um bônus de -5 bytes).


1
@IsmaelMiguel e @OP - Eu provavelmente vou levar um tiro para isso, mas não poderia utilizar -180 < a <= +180como o <sinal em seus próprios meios menos do que mas não incluindo AFAIK ...
George

1
@GeorgeH Você está certo, mas o que o WallyWest está dizendo está errado. "-179 <= a <= 180 resulta em todos os 360 títulos possíveis possíveis" -> isso está errado, porque há 361 títulos. Ou o robô não pode ir para -180º?
Ismael Miguel

1
@IsmaelMiguel É permitido ir -180 graus, porque isso é exatamente o mesmo que 180.
Doorknob

1
Isso esta errado. + 180º significa meia volta no sentido horário. -180º significa meia volta no sentido anti-horário (ou anti-horário, como você preferir). se o intervalo for -179 <= a <= + 180, o robô não poderá girar 180º no sentido anti-horário. Por quê? Ele ficará preso a -179º! Talvez por isso ele teve curto-circuito ...
Ismael Miguel

1
@WallyWest Não sou burra e entendo o que você quer dizer. Só estou dizendo que o intervalo deve ser fixo.
Ismael Miguel

Respostas:


2

Perl 6: 188 184 caracteres - 5 = 180 pontos

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

Golfe com espaço em branco:

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

Ungolfed:

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

Isso transforma os dados em números complexos com unpolar, coloca a soma deles para $complex, em seguida, recebe as coordenadas polares como $dist, $ang.

O ângulo cumulativo $cum-angleé coletado porque os ângulos são relativos ao robô enquanto ele se move pelo laboratório e porque precisamos do ângulo final do robô em nossa saída.

Saída de amostra:

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

O único truque real que o golfe usa é que ele (mis) usa todas as 3 variáveis ​​especiais do Perl 6 com bom efeito:

  • $! é usado para radianos ↔ graus
  • $_mantém os dados e qualquer coisa que pareça solitária .method()significa $_.method()(exceto dentro do map {…}bloco, onde $_assume o valor dos pares de números que compõem os dados)
  • $/mantém o que está na versão não-destruída ($dist, $ang). $0e $1realmente significa $/[0], ie,, $diste $/[1], ie,$ang

Agradável! Você ainda pode descer de 188 para 184 assim:$_=((-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, bom achado! Obrigado! Infelizmente, o espaço depois .map:é obrigatório
Mouq

Oh, eu estava errado sobre o espaço, cool :)
Mouq

10

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

Como o PHP venceu o Ruby na contagem de caracteres ?! >: O Precisa encontrar uma maneira de jogar mais ...

Edit: Eu venci a resposta do PHP, mas o usuário que a escreveu me ajudou a fazê-lo! Vá votar nele; ele merece :-P

Outra edição: Gah! Ele passou por mim de novo! Você é um oponente muito digno, @MathieuRodic; parabéns, eu tenho que deixar você ganhar ;-)

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 não-bloqueado (e versão um pouco mais antiga):

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

Saída de amostra:

c:\a\ruby>robotgolf
Data: 94:26,175:332,14:390,159:448,-45:20
Heading: 124.52305879195005
Distance: 279.5742334385328
Orientation: 397

Como o robô está voltado para o norte depois de ter girado cinco ângulos aleatórios?
21414 WallyWest

@WallyWest Fiquei com a impressão de que a orientação marca o ângulo inicial do robô, correto? Eu poderia fazer isso marcar o ângulo final por apenas 3 caracteres extras.
Maçaneta

Não, ele está sempre voltado para o norte (posição 0) na execução do código ... Então ele gira, corre, gira, corre, gira, corre, gira, gira, corre, gira e depois corre ... antes de desligar. Ele precisará ter o ângulo final que está voltado para a Orientationseção.
Wally West

@WallyWest Ah, tudo bem, editado. Tudo bem se a orientação não estiver em 0 ... 360, ou temos que fazer um trabalho % 360nela?
Maçaneta

Você pode salvar 11 caracteres declarando M=Mathe P=M::PIsubstituindo o código de acordo - e mais um caractere se livrando do espaço após o 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

(teste aqui: http://ideone.com/dNZnKX )

Versão sem golfe:

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

(teste aqui: http://ideone.com/1HzWH7 )


Parece que Perl nos venceu por pouco por pouco. : -O
Maçaneta da porta

@Doorknob Yup, desculpe :)
Mouq

Definitivamente. Mouq, você meio que eliminou todos os nossos esforços com apenas 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))

(teste em http://ideone.com/FicW6e )

Versão não destruída:

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

(teste em http://ideone.com/O3PP7T )

NB: muitas respostas incluem -5 no título, enquanto o programa não representa a distância com precisão de até três casas decimais ...


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 muito chique aqui, bastante detalhado. Esse é um problema para o qual não estou feliz que as funções trigonométricas do python funcionem em radianos.

> 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

0

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

saída de amostra

-141:245, 56:355, 145:223, -10:80, -38:253,
Heading: 12
Distance: 559.031404
Orientation: -2

Python faz cálculos de trigonometria com radianos, não com graus. Assim, os cálculos são provavelmente errado ...
Mathieu Rodic
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.