Czytałem gdzieś o kręgach, a teraz dowiedziałem się o dyskach ( to właściwie dość powszechna koncepcja ) i pomyślałem o codegolfie.
Twoim zadaniem jest zrandomizowanie punktu / kilku punktów na dysku o promieniu 1.
Zasady:
- Wszystkie punkty muszą mieć jednakowe prawdopodobieństwo wygenerowania
- Należy użyć współrzędnych zmiennoprzecinkowych; minimalny wymóg to dwa miejsca po przecinku (np. punkty
(0.12, -0.45)
lub(0.00, -1.00)
są ważne) - Otrzymasz -20 bajtów, jeśli twój program faktycznie wyświetla okrąg ograniczający i wygenerowane w nim punkty. Współrzędne nadal muszą być prawidłowe, ale nie wyświetlane, a wygenerowany obraz musi mieć rozmiar co najmniej 201 na 201 pikseli
- Otrzymasz -5 bajtów, jeśli twój program pobierze liczbę punktów do wygenerowania jako wejście na standardowe wejście
- Jeśli zdecydujesz się nie drukować okręgu ograniczającego i punktów, twój program musi wypisać punkty wygenerowane w formacie
(x, y)
lub(x,y)
na standardowym wyjściu - Jeśli zdecydujesz się przyjąć liczbę wygenerowanych punktów jako dane wejściowe, ale nie wykreślić go - Twój program musi wypisać wszystkie losowe punkty w formacie określonym powyżej z jedną spacją między nimi lub bez
Najkrótsze przesłanie w bajtach wygrywa!
code-golf
math
graphical-output
random
sweerpotato
źródło
źródło
0.3503082505747327+0.13499221288682994j
.Odpowiedzi:
Pyth, 26 - 5 = 21 bajtów
Pobiera liczbę współrzędnych do wygenerowania na stdin i wysyła je na stdout w następujący sposób:
Stosuje strategię podobną do @ MartinBüttner, generując współrzędne biegunowe i promienie, z tym wyjątkiem, że używa złożonego potęgowania.
źródło
p
, prawda? Po prostu zmienia wyjście na oddzielne linie.CJam,
2827 bajtówTo rozwiązanie nie opiera się na odrzuceniu. Generuję punkty we współrzędnych biegunowych, ale z nierównomiernym rozkładem promieni, aby uzyskać jednolitą gęstość punktów.
Sprawdź to tutaj.
Wyjaśnienie
Dlaczego to działa? Rozważmy wąski pierścień o promieniu
r
i (małej) szerokościdr
. Obszar jest w przybliżeniu2π*r*dr
(jeśli pierścień jest wąski, obwód wewnętrzny i zewnętrzny są prawie identyczne, a krzywiznę można zignorować, tak że obszar można traktować jak prostokąt o bokach o obwodzie i szerokości pierścień). Zatem obszar zwiększa się liniowo wraz z promieniem. Oznacza to, że chcemy również liniowego rozkładu promieni losowych, aby uzyskać stałą gęstość (przy podwójnym promieniu jest dwa razy więcej miejsca do wypełnienia, więc chcemy tam dwa razy więcej punktów).Jak wygenerować liniowy rozkład losowy od 0 do 1? Najpierw spójrzmy na dyskretny przypadek. Powiedzmy, że mamy pożądany rozkład 4 wartości, takich jak
{0.1, 0.4, 0.2, 0.3}
(tzn. Chcemy1
być 4 razy tak powszechne jak0
i dwa razy tak powszechne jak2
; chcemy3
trzy razy częściej niż0
):Jak wybrać jedną z czterech wartości o pożądanym rozkładzie? Możemy je ułożyć w stos, wybrać równomiernie losową wartość od 0 do 1 na osi y i wybrać segment w tym punkcie:
Istnieje jednak inny sposób wizualizacji tego wyboru. Zamiast tego możemy zastąpić każdą wartość rozkładu akumulacją wartości do tego momentu:
A teraz traktujemy górną linię tego wykresu jako funkcję
f(x) = y
i odwracamy ją, aby uzyskać funkcję , którą możemy zastosować do równomiernie losowej wartości w :g(y) = f-1(y) = x
y ∈ [0,1]
Fajnie, więc jak wykorzystać to do generowania liniowego rozkładu promieni? Oto rozkład, który chcemy:
Pierwszym krokiem jest zebranie wartości rozkładu. Ale rozkład jest ciągły, więc zamiast sumowania wszystkich poprzednich wartości, bierzemy całkę od
0
dor
. Możemy łatwo rozwiązać ten analitycznie: . Chcemy jednak to znormalizować, tzn. Pomnożyć przez stałą, tak aby to dało maksymalną wartość , więc tak naprawdę chcemy :∫0r r dr = 1/2 r2
1
r
r2
I na koniec odwracamy to, aby uzyskać funkcję, którą możemy zastosować do jednolitej wartości
[0,1]
, którą możemy ponownie wykonać analitycznie: po prostur = √y
, gdziey
jest wartość losowa:Jest to dość użyteczna technika, która często może być używana do generowania prostych rozkładów dokładnie (działa dla każdego rozkładu, ale w przypadku skomplikowanych dwa ostatnie kroki mogą wymagać rozwiązania numerycznego). Nie użyłbym go jednak w tym konkretnym przypadku w kodzie produkcyjnym, ponieważ pierwiastek kwadratowy, sinus i cosinus są zbyt drogie: użycie algorytmu opartego na odrzucaniu jest średnio znacznie szybsze, ponieważ wymaga tylko dodawania i mnożenia.
źródło
Mathematica,
6844-20 = 24 bajtówBardzo dziękuję Davidowi Carraherowi za poinformowanie mnie o tym
RandomPoint
, co pozwoliło zaoszczędzić 24 (!) Bajtów. Mathematica ma mieć wbudowaną za wszystko.To wykreśla punkt i okrąg ograniczający, aby zakwalifikować się do premii:
Rezultatem jest obraz wektorowy, więc specyfikacja wielkości 201 x 201 pikseli naprawdę nie ma sensu, ale domyślnie renderuje większy.
źródło
Graphics[{Circle[], Point@RandomPoint@Disk[]}]
?Graphics@{Circle[], Point@RandomPoint@Disk[]}
,
?CJam,
3126 bajtówDziała to poprzez wielokrotne generowanie losowych punktów w kwadracie o długości boku 2 i zatrzymywanie pierwszego, który wpada w dysk jednostki.
Dzięki @ MartinBüttner za grę w golfa z 3 bajtów!
Wypróbuj online w interpretatorze CJam .
Jak to działa
źródło
iKe ,
5351 bajtówNic szczególnego, ale przypuszczam, że powinniśmy mieć co najmniej jedno rozwiązanie graficzne:
Wypróbuj w swojej przeglądarce .
Edycja: Mogę zgolić dwa bajty, stosując podejście @ MartinBüttnera do modyfikacji rozkładu współrzędnych biegunowych. Myślę, że jest to również bardziej bezpośrednie:
źródło
Perl, 59 bajtów
To tylko proste rozwiązanie, generujące punkty w kwadracie i odrzucające je zbyt daleko. Moją szczególną sztuczką w golfa jest uwzględnienie zadań wewnątrz warunku.
Edycja: W trakcie gry w golfa znalazłem interesujący sposób drukowania losowych punktów na kole .
źródło
Oktawa,
2453-20 = 33 bajtówGeneruje 501 równomiernie rozmieszczonych wartości theta plus jedną liczbę losową i skaluje je wszystkie do [0..2π]. Następnie generuje 501 1 dla promienia okręgu, plus losowy promień punktu i bierze pierwiastek kwadratowy, aby zapewnić równomierny rozkład na dysku. Następnie rysuje wszystkie punkty jako współrzędne biegunowe.
Oto krótka demonstracja rozkładu (bez koła jednostki):
źródło
Octave / Matlab,
7464 bajtówMetoda odrzucenia , 64 bajty:
Metoda bezpośrednia , 74 bajty (podziękowania dla Martina Büttnera za pomoc w poprawieniu dwóch błędów):
źródło
R,
999581-20 =797561 bajtówUżyj konstrukcji liczb zespolonych, aby zbudować x / y ze współrzędnych biegunowych. Biorąc wkład był nieco drogi i prawdopodobnie jest na to lepszy sposób.
ylim
Ima na celu zapewnienie cały krąg wykreślono ixlim
asp
zapewnia punkty pokazane są pod symbolem okręgu.Dzięki @jbaums i @flodel za oszczędności
Wypróbuj tutaj
źródło
runif(9,0,1)
można uprościćrunif(9)
symbols(0,0,1,i=F,asp=1,ylim=c(-1,1));points(complex(,,,runif(9),runif(9,-1)*pi))
yli
działa zamiastylim
.Przetwarzanie / Java 141 bajtów-20 = 121
wymóg, aby 201 * 201 był minimalnym rozmiarem, wymaga ode mnie wprowadzenia
setup
metody, ponieważ Processing.org ma domyślną wartość 200 x 200 :(źródło
QBasic, 138 bajtów - 20-5 = 113
Bierze dane wejściowe użytkownika i rysuje dysk i punkty. Testowane na QB64 .
Jest to dość prosta strategia „rzut na tarczę i trzymaj to, co się trzyma”. Haczyk polega na tym, że „tego, co się trzyma”, nie określa się matematycznie, lecz graficznie: na czarnym tle wykreślany jest biały dysk, a następnie losowo generowane punkty są odrzucane, aż nie będą czarne. Same punkty są narysowane na niebiesko (choć trudno powiedzieć, kiedy są pojedynczymi pikselami - kliknij obraz, aby powiększyć).
źródło
awk - 95 - 5 = 90
Ponieważ nie byłem całkiem pewien co do części rand () <.5, przeprowadziłem z tym testem dystrybucji, używając tego skryptu:
co dla wejścia 1e7 daje mi ten wynik, po tym, jak wypiłem raz lub dwa razy przy mojej kawie:
co moim zdaniem jest całkiem w porządku.
Krótkie wyjaśnienie:
Po napisaniu przez chwilę okazało się, że jeśli chcesz podzielić dysk na cztery pierścienie o równej powierzchni, promienie, w których musisz wyciąć, to sqrt (1/4), sqrt (1/2 ) i sqrt (3/4). Ponieważ rzeczywisty promień punktu I testu będzie sqrt (x ^ 2 + y ^ 2), mogę pominąć kwadratowanie rootowania razem. „Zbieg okoliczności” 1/4, 2/4, 3/4 może być związany z tym, co zauważył wcześniej M. Buettner.
źródło
HPPPL , 146 (171–20–5) bajtów
Przykład dla 10000 punktów (w tym czas w sekundach dla rzeczywistego urządzenia):
Sama funkcja jest wywoływana przez
r(n)
. Reszta na powyższym obrazku służy wyłącznie celom czasowym.Wynik (średnica dysku wynosi 236 pikseli):
Powyższa wersja nie przechowuje współrzędnych punktu, więc napisałem wersję, która przyjmuje dwa parametry
r(n,p)
.n
jest liczbą punktów ip=0
zwraca punkty do terminala,p=1
drukuje punkty i dysk), w przypadku gdy zapisywanie współrzędnych jest obowiązkowe. Ta wersja ma długość 283 (308-20-5) bajtów:Wersja bez golfa:
Wyjście końcowe dla
r(10,0)
:r(10,1)
pokazuje dysk z punktami, jak pokazano powyżej.źródło
JavaScript, 75 bajtów
Oparte na odrzuceniu:
Metoda bezpośrednia (80 bajtów):
źródło
Python,
135130 bajtówUsunięto
**0.5
dzięki @ jimmy23013 „s sugestia (bo jest koło jednostka, jestem teraz sprawdzenie, czy odległość do kwadratu między (x, y) i (0, 0) jest równa 1 2 . Jest to to samo).Pozwoliło mi to również usunąć nawiasy.
źródło
**0.5
.