Problem:
Biorąc pod uwagę niepusty zestaw punktów na płaszczyźnie kartezjańskiej, znajdź najmniejsze koło, które je ogarnia ( link z Wikipedii ).
Ten problem jest trywialny, jeśli liczba punktów wynosi trzy lub mniej (jeśli jest jeden punkt, okrąg ma promień zero; jeśli są dwa punkty, odcinek linii łączący punkty jest średnicą koła; jeśli istnieją trzy (nieliniowe) punkty, możliwe jest uzyskanie równania koła, które dotyka ich wszystkich, jeśli tworzą trójkąt nie rozwarty lub koło, które dotyka tylko dwóch punktów i otacza trzeci, jeśli trójkąt jest tępy). Tak więc, ze względu na to wyzwanie, liczba punktów powinna być większa niż trzy.
Wyzwanie:
- Dane wejściowe: lista 4 lub więcej punktów innych niż kolinearne. Punkty powinny mieć współrzędne X i Y; współrzędne mogą być zmiennoprzecinkowe. Aby ułatwić wyzwanie, żadne dwa punkty nie powinny mieć tej samej współrzędnej X.
Na przykład:[(0,0), (2,1), (5,3), (-1,-1)]
- Wyjście: krotka wartości,
(h,k,r)
taka, że jest równaniem najmniejszego okręgu, który obejmuje wszystkie punkty.
Zasady:
- Możesz wybrać metodę wprowadzania odpowiednią dla twojego programu.
- Dane wyjściowe powinny zostać wydrukowane
STDOUT
lub zwrócone przez funkcję. - Preferowane są języki „zwykłe” ogólnego przeznaczenia, ale akceptowany jest każdy esolang.
- Możesz założyć, że punkty nie są współliniowe.
- To jest golf golfowy, więc wygrywa najmniejszy program w bajtach. Zwycięzca zostanie wybrany tydzień po opublikowaniu wyzwania.
- Jako nagłówek w pierwszym wierszu odpowiedzi podaj użyty język i długość w bajtach:
# Language: n bytes
- Jako nagłówek w pierwszym wierszu odpowiedzi podaj użyty język i długość w bajtach:
Przypadki testowe:
- 1:
- Wkład:
[(-8,0), (3,1), (-6.2,-8), (3,9.5)]
- Wydajność:
[-1.6, 0.75, 9.89]
- Wkład:
- 2:
- Wkład:
[(7.1,-6.9), (-7,-9), (5,10), (-9.5,-8)]
- Wydajność:
[-1.73, 0.58, 11.58]
- Wkład:
- 3:
- Wkład:
[(0,0), (1,2), (3,-4), (4,-5), (10,-10)]
- Wydajność:
[5.5, -4, 7.5]
- Wkład:
- 4:
- Wkład:
[(6,6), (-6,7), (-7,-6), (6,-8)]
- Wydajność:
[0, -0.5, 9.60]
- Wkład:
Miłej gry w golfa !!!
Odpowiedzi:
Wolfram Language (Mathematica) ,
2827 bajtówWypróbuj online!
Przydają się tutaj wbudowane. Dane wyjściowe to obiekt dyskowy o środku i promieniu. Podobnie jak inne, stwierdziłem, że 2. i 3. przypadek testowy różnią się od pytania.
Dzięki @lirtosiast za uratowanie bajtu!
Jeśli jako dane wyjściowe wymagana jest lista, można to zrobić w 35 bajtach (kosztem dodatkowych 8 bajtów) . Dzięki @Roman za zwrócenie na to uwagi.
źródło
Append@@BoundingRegion[#,"MinDisk"]&
JavaScript (ES6),
298 ... 243242 bajtówZwraca tablicę
[x, y, r]
.Wypróbuj online!
lub zobacz sformatowaną wersję
W jaki sposób?
metoda
Dla każdej pary punktów generujemy okrąg którego średnica wynosi .(A,B) (X,Y,r) AB
Dla każdego potrójnego punktu generujemy okrąg który otacza trójkąt .(A,B,C) (X,Y,r) ABC
Dla każdego wygenerowanego okręgu sprawdzamy, czy każdy punkt jest w nim zawarty:(x,y)
I w końcu zwracamy najmniejsze prawidłowe koło.
Realizacja
W kodzie JS wzór na obliczenie dla ograniczonego okręgu trójkąta jest nieco uproszczony. Zakładając , definiujemy , co prowadzi do:(X,Y) d≠0 q=Cx2+Cy2
W ten sposób funkcja pomocnicza wymaga tylko dwóch parametrów do obliczenia każdej współrzędnej:F (j,k)
Trzeci parametr stosowany w (to jej rzeczywisty argumentu ) stosuje się do obliczenia , gdy , co oznacza, że trójkąt jest zdegenerowany i spróbować zamiast używać średnicę.F s (X,Y) d=0
źródło
R , 59 bajtów
Wypróbuj online!
Pobiera dane wejściowe jako wektor złożonych współrzędnych.
Mod
jest odległością (modułem) w płaszczyźnie zespolonej inlm
jest funkcją optymalizacyjną: znajduje pozycję środka (wyjście asestimate
), która minimalizuje maksymalną odległość do punktów wejściowych i podaje odpowiednią odległość (wyjście asminimum
), tj. promień . Dokładne do 3-6 cyfr; stopka TIO zaokrągla wynik do 2 cyfr.nlm
przyjmuje na wejściu wektor numeryczny:y%*%c(1,1i)
firma przekształca go w kompleks.źródło
Galaretka ,
10098 bajtówWypróbuj online!
W przeciwieństwie do mojej odpowiedzi w języku Wolfram , Jelly potrzebuje sporo kodu, aby to osiągnąć (chyba że czegoś mi brakuje!). Ten pełny program przyjmuje listę punktów jako argument i zwraca środek i promień najmniejszego otaczającego okręgu. Generuje on okręgi dla wszystkich zestawów trzech punktów i średnice dla wszystkich zestawów dwóch punktów, czeki, które obejmują wszystkie punkty, a następnie wybiera ten o najmniejszym promieniu.
Kod bitu make_circumcircle został zainspirowany kodem na tej stronie , z kolei zainspirowanym Wikipedią.
źródło
APL (NARS), 348 znaków, 696 bajtów
Jest to jedna „implementacja” formuł w rozwiązaniu Arnauld ... Wyniki i komentarze:
f: znajduje kombinację ojetów alfa w zestawie omega
((X, Y), r) od teraz reprezentują jedną obwódkę o promieniu ri środku w (XY).
c: sprawdza, czy punkt w ⍺ znajduje się wewnątrz obwodu ((XY) r) w ⍵ (wynik <= 0) ot jest zewnętrzny (wynik> 0) W przypadku wprowadzenia obwodu w ⍵ jest to input jako wejście, to zwróci 1 (poza obwodem) każde możliwe wejście w ⍺.
p: jeśli ⍵ jest tablicą ((XY) r); dla każdego z ((XY) r) w ⍵ zapisuje 1, jeśli wszystkie punkty w tablicy ⍺ są wewnętrzne dla ((XY) r) w przeciwnym razie zapisuje 0 NB Oto coś, co nie idzie, ponieważ musiałem zaokrąglić do epsilon = 1e¯ 13 innymi słowy w ograniczonych przypadkach punktów w samolocie (i prawdopodobnie zbudowanych specjalnie) cel nie jest w 100% ubezpieczony
s2: od 2-punktowego w ⍵ zwraca obwód w formacie ((XY) r), który ma średnicę w tych 2 punktach
s3: z 3 punktów zwraca obwód w formacie ((XY) r) przechodzący przez te trzy punkty Jeśli wystąpią problemy (na przykład punkty są wyrównane), to się nie powiedzie i zwróci ⍬.
zauważ, że -. × znajdź wyznacznik macierzy nxn i
s: z n punktów na ⍵, wyszukuje obwody typu znalezione przez s2 lub te typu s3, które zawierają wszystkie n punktów.
s1: z zestawu znalezionego z powyższego s oblicza te, które mają minimalny promień i zwraca pierwszy, który ma minimalny promień. Trzy liczby jako tablice (pierwsza i druga współrzędna są współrzędnymi środka, a trzecia to promień znalezionego obwodu).
źródło
Python 2 (PyPy) ,
244242 bajtówWypróbuj online!
Wykorzystuje to algorytm O (n ^ 4) brute-force, iterujący po każdej parze i trójkącie punktów, obliczający środek i utrzymujący środek, który potrzebuje najmniejszego promienia, aby objąć wszystkie punkty. Oblicza obwód 3 punktów poprzez znalezienie przecięcia dwóch prostopadłych dwusiecznych (lub, jeśli dwa punkty są równe, wykorzystuje punkt środkowy z trzecim).
źródło
P={x+y*1j for x,y in input()}
oszczędza również 2 bajty.Python
212190 bajtówTo rozwiązanie jest nieprawidłowe i muszę teraz działać, więc nie mam czasu, aby to naprawić.
Wypróbuj online!
Zorientowałem się, które dwa punkty są najdalej, a następnie wygenerowałem równanie dla koła na podstawie tych punktów!
Wiem, że nie jest to najkrótszy w Pythonie, ale to najlepsze, co mogłem zrobić! To także moja pierwsza próba zrobienia jednego z nich, więc proszę zrozumcie!
źródło
if g>c:\n c=g\n d=[e,f]
doif g>c:c=g;d=[e,f]
, oszczędzając ci dużo białych znaków. Nie sądzę, że musisz wcześniej zainicjować d, używając również dwóch zmiennych,E,F=e,f
aw wierszu 10print
znacznie skrócisz. Wydaje mi się, że rozwiązanie zemax
zrozumieniem listy byłoby nawet krótsze niż dwie pętle, ale mogę się mylić. Niestety twoje rozwiązanie jest nieprawidłowe. Dla punktów (-1,0), (0,1.41), (0,5, 0), (1,0) twoje rozwiązanie oblicza okrąg wokół 0 o promieniu 1. Ale punktu (1, 1.41) nie ma w tym okrąg.