Circle Maze Checker

12

Você conhece aqueles brinquedos de madeira com pequenos rolamentos de esferas onde o objetivo é se movimentar pelo labirinto? Isso é meio assim. Dado um labirinto e uma série de jogadas, determine onde a bola termina.

A prancha é mantida na vertical e a bola se move apenas por gravidade quando a prancha é girada. Cada "movimento" é uma rotação (em radianos).

O labirinto é simplesmente paredes circulares concêntricas, com cada parede tendo exatamente uma abertura no corredor externo, semelhante a esta (suponha que essas paredes sejam circulares e não pontiagudas):

labirinto

Como você pode ver, a bola começa no meio e está tentando sair. A bola cairá instantaneamente assim que a orientação correta for alcançada, mesmo que esteja no meio de uma rotação. Uma única rotação pode fazer com que a bola caia por várias aberturas. Por exemplo, uma rotação >= n * 2 * pié suficiente para escapar de qualquer labirinto.

Para os propósitos do jogo, uma bola localizada dentro dos 0.001radianos da abertura é considerada um "encaixe" e passará para o próximo corredor.

Entrada:

A entrada está dividida em duas partes:

  • O labirinto é dado por um número inteiro que nrepresenta quantas paredes / aberturas existem no labirinto. Isto é seguido por nlinhas, com um número em cada, representando onde está a passagem para o próximo corredor.

  • Os movimentos são dados como um número inteiro mrepresentando quantos movimentos foram realizados, seguidos (novamente em linhas separadas) por mrotações no sentido horário da placa em radianos (o negativo é anti-horário).

Todas as posições de passagem são dadas como 0 rad = up, com radianos positivos no sentido horário.

Para a imagem de amostra acima, a entrada pode ser assim:

7                        // 7 openings
0
0.785398163
3.14159265
1.74532925
4.71238898
4.01425728
0
3                        // 3 moves
-3.92699082
3.14159265
0.81245687

Saída: emita o número do corredor em que a bola termina. Os corredores são indexados a zero, começando do centro, para você começar 0. Se você passar por uma abertura, estará no corredor 1. Se você escapar de todo o labirinto, imprima qualquer número inteiro>= n

Para a entrada de amostra, há três movimentos. O primeiro fará com que a bola caia por duas aberturas. O segundo não encontra uma abertura, e o terceiro encontra uma . A bola está agora no corredor 3, então a produção esperada é:

3

O comportamento é indefinido para entrada inválida. A entrada válida é bem formada, com n >= 1e m >= 0.

A pontuação é um código de golfe padrão, o menor número de bytes vence. As brechas padrão são proibidas. A entrada não deve ser codificada, mas pode ser obtida a partir de entradas, argumentos, console, etc. padrão. A saída pode ser para console, arquivo, o que for, basta torná-la visível em algum lugar.

Geobits
fonte
"O comportamento é indefinido para entrada inválida." << - Isso precisa ser colocado em todos os quebra-cabeças!
precisa saber é o seguinte
Nesse caso hipotético, você também pode calcular π sempre que necessário com precisão variável, aumentando a precisão até que seja suficiente para dizer se uma bola caiu ou não. Um problema que tenho com a tolerância para um ajuste (ou pelo menos sua redação atual) é que A) ajustes consecutivos estão mais próximos que 0,001 um do outro, de modo que a bola caia apenas dois níveis se a tolerância for levada em consideração B) quando a a bola está a 0,001 de um buraco, ela salta para o buraco (se você realmente quiser ler algo no texto).
Wrzlprmft
@Wrzlprmft A bola não pula para o buraco. Pense no limiar como significando que os buracos são um pouco mais largos que a bola. Ele ainda cai no mesmo local, apenas um nível a mais. Se você imagina que o limiar era 1, estaria trabalhando apenas com buracos grandes, sem pular bolas para o centro do buraco quando elas caem.
Geobits
Por que a entrada está em um formato tão inconveniente? Eu tenho certeza que eu tenho golfed programas inteiros mais curtos do que o que eu preciso lê-lo: /
Tal

Respostas:

2

Perl, 211 191

Com novas linhas e recuo para facilitar a leitura:

$p=atan2 0,-1;
@n=map~~<>,1..<>;
<>;
while(<>){
    $_=atan2(sin,cos)for@n;
    $y=abs($n[$-]+$_)<$p-.001
        ?$_
        :($_<=>0)*$p-$n[$-];
    $_+=$y for@n;
    $p-.001<abs$n[$-]&&++$-==@n&&last;
    $_-=$y;
    .001<abs&&redo
}
print$-

O número de movimentos na entrada é descartado, eof do stdin indica o fim dos movimentos.

user2846289
fonte
5

JavaScript 200

function f(i){with(Math)for(m=i.split('\n'),o=m.slice(1,t=+m[0]+1),m=m.slice(t+1),c=PI,p=2*c,r=0,s=1e-3;m.length;c%=p)abs(c-o[r])<s?r++:abs(t=m[0])<s?m.shift(c+=t):(b=t<0?-s:s,c+=p-b,m[0]-=b);return r}

EDIT : Aqui está um exemplo animado que prova que esse solucionador funciona: http://jsfiddle.net/F74AP/4/

animado

A função deve ser chamada passando a string de entrada.
Aqui está a chamada do exemplo dado pelo OP:

f("7\n0\n0.785398163\n3.14159265\n1.74532925\n4.71238898\n4.01425728\n0\n3\n-3.92699082\n3.14159265\n0.81245687");

Retorna 3como pretendido.

Michael M.
fonte
2
Do desafio, "... a entrada não deve ser codificada ..." . A menos que eu esteja enganado, isso significa que você deve lê-lo e também precisa ter um programa completo. Isso parece apenas uma função.
Rainbolt
2
Eu não entendo, os valores não são codificados! "... A entrada não deve ser codificada, mas pode ser obtida a partir da entrada padrão, argumentos, console, etc. ". Em relação ao programa completo , não vejo onde ele está especificado e, de qualquer forma, na IMO, esta é uma solução JS completa.
Michael M.
Como não especifiquei um programa completo, não vejo problema apenas com uma função. No entanto, a entrada é especificada como sendo separada por novas linhas, ainda não organizadas em matrizes nativas. Isso deve ser simples de satisfazer.
Geobits
1
@Geobits, vou modificá-lo mais tarde, dê uma olhada neste violino: jsfiddle.net/F74AP/1
Michael M.
1
@ Geobits, certo! Simples erro de sinal ... Fixa ;-)
Michael M.