Circle Maze Checker

12

Znasz te drewniane zabawki z małymi łożyskami kulkowymi, w których obiekt ma poruszać się po labiryncie? To trochę tak. Biorąc pod uwagę labirynt i serię ruchów, określ, gdzie kończy się piłka.

Deska jest trzymana pionowo, a kula porusza się tylko grawitacyjnie, gdy deska jest obracana. Każdy „ruch” to obrót (w radianach).

Labirynt to po prostu koncentryczne okrągłe ściany, przy czym każda ściana ma dokładnie jeden otwór w zewnętrznym korytarzu, podobnie do tego (załóżmy, że te ściany są okręgami i nie są spiczaste):

labirynt

Jak widać, piłka zaczyna się na środku i próbuje się wydostać. Piłka będzie natychmiast spadają poprzez najszybciej jak prawidłowa orientacja zostanie osiągnięty, nawet jeśli jest to w połowie obrotu. Pojedynczy obrót może spowodować, że piłka spadnie przez wiele otworów. Na przykład obrót >= n * 2 * piwystarczy, aby uciec od labiryntu.

Na potrzeby gry piłka znajdująca się w 0.001radianach otworu jest uważana za „dopasowaną” i spada do następnego korytarza.

Wejście:

Dane wejściowe składają się z dwóch części:

  • Labirynt podaje liczba całkowita nreprezentująca liczbę ścian / otworów w labiryncie. Po nim następują nwiersze, po jednym na każdej z nich, wskazujące miejsce przejścia do następnego korytarza.

  • Ruchy są podawane jako liczba całkowita mreprezentująca liczbę wykonanych ruchów, a następnie (ponownie w osobnych liniach) mobroty planszy w radianach zgodnie z ruchem wskazówek zegara (ujemna jest przeciwna do ruchu wskazówek zegara).

Wszystkie pozycje przejścia podano jako 0 rad = up, z dodatnimi radianami idącymi zgodnie z ruchem wskazówek zegara.

Dla powyższego przykładowego obrazu dane wejściowe mogą wyglądać następująco:

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

Wyjście: wypisz numer korytarza, w którym kończy się kula. Korytarze mają indeks zerowy, zaczynając od środka, więc zaczynasz 0. Jeśli przejdziesz przez jeden otwór, znajdziesz się na korytarzu 1. Jeśli uciekniesz z całego labiryntu, wypisz dowolną liczbę całkowitą>= n

Dla próbki wejściowej są trzy ruchy. Pierwszy spowoduje, że piłka spadnie przez dwa otwory. Drugi nie znajdzie otwór, a trzeci stwierdzi jedną . Kula jest teraz w korytarzu 3, więc oczekiwany wynik to:

3

Zachowanie jest niezdefiniowane dla niepoprawnych danych wejściowych. Prawidłowe dane wejściowe są dobrze sformułowane, z n >= 1i m >= 0.

Punktacja to standardowy kod golfowy, najmniejsza liczba bajtów wygrywa. Standardowe luki są zabronione. Dane wejściowe nie mogą być zakodowane na stałe, ale można je pobierać ze standardowych danych wejściowych, argumentów, konsoli itp. Dane wyjściowe mogą być przesyłane do konsoli, pliku itp., Po prostu sprawiają, że dane wyjściowe są widoczne.

Geobity
źródło
„Zachowanie jest niezdefiniowane dla nieprawidłowych danych wejściowych”. << - Należy to umieścić we wszystkich puzzlach!
TheDoctor
W tym hipotetycznym przypadku można również obliczyć π w razie potrzeby ze zmienną dokładnością, podnosząc dokładność, aż wystarczy stwierdzić, czy piłka spadła, czy nie. Problem z tolerancją dopasowania (a przynajmniej jej obecnego brzmienia) polega na tym, że A) kolejne pasowania są bliżej siebie niż 0,001, tak że piłka spada tylko o dwa poziomy, jeśli uwzględni się tolerancję B), gdy piłka znajduje się w odległości 0,001 od dołka, przeskakuje do dołka (jeśli naprawdę chcesz coś przeczytać w treści).
Wrzlprmft
@Wrzlprmft Piłka nie skacze do dziury. Pomyśl o progu jako o tym, że dziury są nieco szersze niż piłka. Nadal spada do tej samej lokalizacji, tylko jeden poziom dalej. Jeśli wyobrażasz sobie, że próg był 1, będziesz po prostu pracował z dużymi dziurami, nie skacząc kulkami do środka otworu, gdy spadną.
Geobits
Dlaczego dane wejściowe są w tak niewygodnym formacie? Jestem prawie pewien, że grałem w golfa całe programy krócej niż to, co muszę przeczytać: /
Tal

Odpowiedzi:

2

Perl, 211 191

Z nowymi liniami i wcięciem dla czytelności:

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

Liczba ruchów na wejściu jest odrzucana, eof stdin wskazuje koniec ruchów.

użytkownik 2846289
źródło
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}

EDYCJA : Oto animowany przykład udowadniający, że ten solver działa: http://jsfiddle.net/F74AP/4/

ożywiony

Funkcja musi zostać wywołana przez przekazanie ciągu wejściowego.
Oto wywołanie przykładu podanego przez OP:

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

Zwraca 3zgodnie z przeznaczeniem.

Michael M.
źródło
2
W ramach wyzwania „... dane wejściowe nie mogą być zakodowane na stałe ...” . O ile się nie mylę, oznacza to, że musisz go przeczytać i mieć także pełny program. To wygląda jak funkcja.
Rainbolt
2
Nie rozumiem, wartości nie są zakodowane na stałe! „... Dane wejściowe nie mogą być zakodowane na stałe, ale można je pobierać ze standardowych danych wejściowych, argumentów, konsoli itp .”. Jeśli chodzi o kompletny program , nie widzę, gdzie jest określony, a poza tym IMO to kompletne rozwiązanie JS.
Michael M.
Nie podałem pełnego programu, więc nie widzę problemu tylko z funkcją. Jednak dane wejściowe określone jako oddzielone znakami nowej linii, które nie są jeszcze ułożone w natywne tablice. To powinno być proste do spełnienia.
Geobity
1
@Geobits, zmodyfikuję to później, spójrz na to skrzypce: jsfiddle.net/F74AP/1
Michael M.
1
@Geobits, prawda! Błąd prostego znaku ... Naprawiono ;-)
Michael M.