Weź dwuwymiarową siatkę i narysuj na niej kilka segmentów linii, które będą reprezentować lustra. Teraz wybierz punkt, aby umieścić teoretyczny laser i kąt, aby zdefiniować kierunek, w który wskazuje. Pytanie brzmi: jeśli podążasz ścieżką wiązki laserowej na określonej odległości, w jakim punkcie współrzędnych jesteś?
Przykład:
Na tym rysunku L
jest położenie lasera t
jest jego kąt (mierzona od dodatniej osi X) M1
, M2
i M3
są regulowane lusterka odcinka linii, i E
jest punktem na drodze wiązki laserowej po D = d1 + d2 + d3 + d4
jednostek, począwszy od L
.
Cel
Napisz najkrótszy program (w bajtach), które wyjścia E
podane L
, t
, D
, oraz listę luster.
(Użyj http://mothereff.in/byte-counter do liczenia bajtów.)
Format wejściowy
Dane wejściowe będą pochodzić ze standardowego wejścia w formacie:
Lx Ly t D M1x1 M1y1 M1x2 M1y2 M2x1 M2y1 M2x2 M2y2 ...
- Wszystkie wartości będą punkty odpowiadające tym regex pływających:
[-+]?[0-9]*\.?[0-9]+
. - Zawsze jest dokładnie jedna spacja między każdą liczbą.
- Wymagane jest stosowanie cudzysłowów wokół danych wejściowych.
t
jest w stopniach, ale niekoniecznie w[0, 360)
zakresie. (Jeśli wolisz, możesz zamiast tego użyć radianów, po prostu powiedz to w swojej odpowiedzi).D
może być ujemny, skutecznie obracając laser o 180 stopni.D
może również wynosić 0.- Może być dowolnie wiele kopii lustrzanych (w tym w ogóle żadnych).
- Kolejność serwerów lustrzanych nie powinna mieć znaczenia.
- Możesz założyć, że dane wejściowe będą wielokrotności 4 liczb. na przykład
Lx Ly t
czyLx Ly t D M1x1
są nieważne i nie będą testowane. Żadne dane wejściowe są również nieprawidłowe.
Powyższy układ można wprowadzić jako:
1 1 430 17 4.8 6.3 6.2 5.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
(Zwróć uwagę, że obraz został narysowany odręcznie, a te wartości są jedynie przybliżeniami. Wartości wejściowe Martina Büttnera z
1 1 430 17 4.8 5.3 6.2 4.3 1.5 4.8 3.5 6 6.3 1.8 7.1 3
spowoduje więcej kolizji, choć nie pasują do szkicu).
Format wyjściowy
Dane wyjściowe powinny przejść na standardowe wyjście w formacie:
Ex Ey
Są to również zmiennoprzecinkowe i mogą mieć postać wykładniczą.
Notatki
- Lustra mogą się przecinać.
- Obie strony lusterek są odblaskowe.
- Wiązka może trafić wiele razy w to samo lustro.
- Wiązka trwa wiecznie.
Niezdefiniowane przypadki
Możesz założyć, że w przypadkach, w których
- laser rozpoczyna się na odcinku linii lustrzanej
- promień lasera uderza w punkt końcowy lustra
- promień lasera uderza w przecięcie dwóch luster
są niezdefiniowane i nie będą testowane. Twój program może zrobić wszystko, jeśli wystąpią, w tym zgłosić błąd.
Premia
Dla zabawy przyznam 200 punktów premiowych za najwyżej ocenione zgłoszenie, które przedstawia graficzną reprezentację problemu (możesz nawet napisać interaktywny skrypt). Te bonusy nie muszą być rozgrywane w golfa i mogą być pobłażliwe przy przetwarzaniu danych wejściowych i wyjściowych. Różnią się one od rzeczywistych zgłoszeń golfowych, ale oba powinny zostać przesłane w tej samej odpowiedzi .
Uwaga: Tylko przesłanie odpowiedzi premiowej jest w porządku, po prostu nie będziesz akceptowaną odpowiedzią. Aby zostać zaakceptowanym, musisz dokładnie przestrzegać specyfikacji wejścia / wyjścia (np. Wyjście dotyczy tylko Ex Ey
, a nie obrazów) i być najkrótszym.
Odpowiedzi:
Rubinowy, 327 bajtów
(przewiń w dół)
Mathematica, dodatkowa odpowiedź
Teraz wybieram tylko przesyłanie graficzne. Mogę przenieść to później do Ruby i pograć w golfa, jeśli mi się spodoba.
Możesz to tak nazwać
To da ci animację w Mathematica, a także wyeksportuje GIF (ten u góry dla tego wejścia). Lekko rozszerzyłem o to przykład OP, aby uczynić go nieco bardziej interesującym.
Więcej przykładów
Rurka o lekko rozbieżnych ścianach, ale z zamkniętym końcem:
Trójkąt równoboczny i kierunek początkowy, który jest prawie równoległy do jednego z boków.
Jeszcze jeden:
Ruby, gra w golfa
Jest to w zasadzie bezpośrednie tłumaczenie rozwiązania Mathematica na Ruby, a także trochę gry w golfa i upewnienie się, że spełnia on kryteria wejścia / wyjścia.
źródło
Python 3 (
421C 390C, 366C)Użyj
builtin.complex
jako wektora 2d. WięcAby pokonać rozwiązanie Ruby 368C, znalazłem dość kompaktową metodę obliczania odbicia punktu wzdłuż lustra. A także użył złożonej algebry, aby zmniejszyć liczbę znaków. Można je łatwo znaleźć w nierozwiniętym kodzie.
Oto wersja golfowa.
Bez golfa
Bonus: HTML, Coffeescript, dostosowanie i kalkulacja w czasie rzeczywistym
Przeciągasz dowolne punkty końcowe (lub lazer, mirra), a następnie renderowana jest ścieżka. Obsługuje również dwa typy danych wejściowych, ten opisany w pytaniu i ten używany przez @Martin Büttner.
Skalowanie jest również dostosowywane automatycznie.
Na razie nie ma animacji. Może poprawię to później. Jednak przeciągnięcie białych punktów spowoduje wyświetlenie innego rodzaju animacji. Wypróbuj online tutaj , to zabawne!
Cały projekt można znaleźć tutaj
Aktualizacja
Tutaj przedstawiam interesujący przypadek:
Rezultat to:
źródło
HTML JavaScript,
10,543,947889Naprawiłem błąd i upewniłem się, że wyjście spełnia specyfikację pytania. Poniższa strona ma wersję golfową, a także graficzną wersję bonusową. Naprawiłem również błąd wskazany przez @Ray, który zapisał 58 znaków. (Dzięki Ray.) Możesz także uruchomić golfowy kod w konsoli JavaScript. (Teraz używam zielonego lasera 2 mW).
Kod golfowy
Wkład
Wydajność
Możesz to przetestować tutaj: http://goo.gl/wKgIKD
Wyjaśnienie
Kod na stronie jest komentowany. Zasadniczo obliczam przecięcie lasera z każdym lustrem, zakładając, że laser i lustra są nieskończenie długie. Następnie sprawdzam, czy przecięcie znajduje się w skończonej długości lustra i lasera. Następnie biorę najbliższe skrzyżowanie, przesuwam laser do tego punktu i kontynuuję, dopóki laser nie ominie wszystkich lusterek.
Bardzo fajny projekt. Dzięki, że zadałeś to pytanie!
Czytelny kod
źródło
0 0 0.4 100 1 1 1 -1 1 -1 -1 -1 -1 -1 -1 1 -1 1 1 1
.Python - 765
Dobre wyzwanie. To jest moje rozwiązanie, które pobiera dane wejściowe ze standardowego wejścia i wyjścia na standardowe wyjście. Korzystając z przykładu @Martin Büttner:
Oto kod do gry w golfa:
A oto niepoznany kod z liczbą bonusową
źródło
sys.argv
to nie jest standardowe.Matlab (388)
Wątek
Pojęcia
Punkty refleksji
Aby obliczyć punkty odbicia, musimy po prostu przeciąć dwie proste linie. Jeden z punktem p0 i wektorem v, drugi między dwoma punktami p1, p2. Zatem równanie do rozwiązania to (s, t są parametrami): p0 + t v = s p1 + (1-s) * p2.
Parametr s jest wówczas współrzędną barrocentryczną lustra, więc jeśli 0
Mirroring
Odbicie lustrzane v jest dość proste. Załóżmy, że || v || = || n || = 1 gdzie n jest normalnym wektorem bieżącego lustra. Następnie możesz po prostu użyć wzoru v: = v-2 ** n gdzie <,> jest iloczynem kropkowym.
Ważność kroku
Przy obliczaniu najbliższego „prawidłowego” lustra musimy wziąć pod uwagę niektóre kryteria, które czynią go ważnym. Najpierw punkt przecięcia lustra musi znajdować się między dwoma punktami końcowymi, więc musi wynosić 0
Program
Lekko golfowy (388)
źródło