Otrzymujesz funkcję Rand5 (). Ta funkcja zwraca idealnie losowe (równomiernie rozmieszczone) liczby całkowite od 1 do 5.
Podaj funkcję Rand7 (), która używa Rand5 () do tworzenia idealnie losowych liczb całkowitych od 1 do 7.
code-challenge
math
random
Dan McGrath
źródło
źródło
Odpowiedzi:
Java - 61 znaków
Przetestuj sterownik do sprawdzania poprawności:
Wyniki
źródło
rand5
. Przeliczyłem je w Maple przy użyciu prostej algebry macierzowej, ale możesz to zrobić ołówkiem i papierem w ciągu kilku minut, jeśli chcesz. W każdym razie okazuje się, że Omar opublikował już te same dane (bez współczynnika normalizującego) w komentarzu do innej odpowiedzi kilka dni wcześniej. (Również ps., Możesz @ tylko powiadomić jednego użytkownika na komentarz, chociaż autor wpisu jest zawsze powiadamiany zawsze.)Perl - 47 (było 52) znaków
Plus mogę użyć trójskładnikowego operatora ORAZ rekurencji. Najlepszy… dzień… kiedykolwiek!
OK, 47 znaków, jeśli używasz mod zamiast div:
źródło
&
znaki, aby sprowadzić go do 46 znaków (w tym spacji, co oznacza, że twoja obecna wersja to 48).JavaScript, 42
Dodatkowa rzecz ES5:
źródło
Ruby - 54 znaki (na podstawie rozwiązania Dana McGratha, przy użyciu pętli)
Ruby - 45 znaków (to samo rozwiązanie, przy użyciu rekurencji)
źródło
(x=rand5+5*rand5-5)>7?
.W Pythonie:
źródło
W Common Lisp 70 znaków:
Nawiasy zajmują więcej miejsca, niż bym chciał.
źródło
(defun rand7()(setq n(-(+(rand5)(* 5(rand5)))5))(if(> n 7)(rand7)n))
(defun rand7()(if(>(setq n(-(+(rand5)(* 5(rand5)))5))7)(rand7)n))
W c / c ++ przy użyciu próbkowania odrzucania
62 znaków.
źródło
while(x>7)
taki, że byłyby spełnione tylko liczby w prawidłowym zakresie.Tłumaczenie na PHP, z odpowiedzi opublikowanej przez Dana McGratha.
67 znaków.
źródło
R, 34 znaki
W języku R (język zbudowany do obliczeń statystycznych) celowo oszustwo:
Dzięki leniwej ocenie argumentów wyeliminowałem średnik i nawiasy klamrowe.
Wyjście ponad 10 ^ 6 powtórzeń:
źródło
Rand7=function(){r=Rand5();sample(7)[r]}
Rand7=function(){sample(7)[Rand5()]}
scala,
47, 4059 znaków:z 2 wejściami z rand5:
Pomnożę pierwszy-1 przez 5 i dodam drugi. Większość wyników jest ignorowana i prowadzi do nowych obliczeń. Wynikiem powinna być równa dystrybucja wartości od 1 do 25, z których wybieram tylko 7 pierwszych. Mogłem zaakceptować pierwsze 21 z budowaniem modulo, ale doprowadziłoby to do dłuższego kodu.
historyczny kod, który zawiódł, ale niezbyt oczywiście. Dzięki Ilmari Karonen za zwrócenie na to uwagi:
Dzięki Yoshiteru Takeshicie za to podejście scala-2.8.0, dzięki któremu „suma” była tak łatwa. Moje rozwiązanie wcześniej:
rand5:
źródło
def rand7=(1 to 7).map(_=>rand5).sum%7+1
C ++
C ++ (109)
Grał w golfa
źródło
Tłumaczenie na Javascript, z odpowiedzi zamieszczonej przez Dana McGratha.
62 znaki
źródło
function Rand7(){for(x=8;x>7;x=rand5()+5*rand5()-5);return x}
jest nieco krótszy: PJavaScript, 85
Wiem, że odpowiedź jest krótsza, ale chciałem pokazać test tej układanki. Okazuje się, że tylko odpowiedź Clyde Lobo przy użyciu próbkowania odrzucenia Dana McGratha jest poprawna (między odpowiedziami JS).
źródło
С ++
Rozkład liczb (1000000 liczb całkowitych):
Średnia liczba wywołań do Rand5 () na każdą wygenerowaną liczbę całkowitą wynosi około 2,2 (od 2 do 10+).
źródło
W Javie (lub C / C ++, jak sądzę)
używając formuły generowania Alexandru, w 65 znakach:
z wykorzystaniem formuły generacyjnej Dana McGratha, w 60 znakach
źródło
Clojure - 58 znaków
źródło
Python,
5637 znakówInne rozwiązanie, które może być niepoprawne, w Pythonie:
To wydaje się zbyt proste, ale kiedy próbuję:
Dostaję dość równomierną dystrybucję (wszystkie między 14000 a 14500).
Dobra, teraz, gdy ktoś głosował na ten post: Czy to rozwiązanie jest rzeczywiście poprawne? Bardziej opublikowałem to tutaj, aby ludzie go krytykowali. Cóż, jeśli jest to poprawne, moja wersja w golfa byłaby:
który wychodzi na 37 znaków.
źródło
Java, 65 znaków:
źródło
Python, 70 znaków
ale całkowicie poprawne na podstawie uzasadnienia tutaj .
źródło
Perl, 43 znaki, iteracyjne próbkowanie odrzucenia
Daje to ostrzeżenie
Ambiguous use of -rand5 resolved as -&rand5()
, ale działa poprawnie. Przygotowanie&
również do drugiegorand5
połączenia naprawia go kosztem jednego pociągnięcia. (I odwrotnie, drugi&
można również usunąć, jeślirand5
został zdefiniowany za pomocą()
prototypu.)Ps. Następująca 46-znakowa wersja jest około trzy razy szybsza:
źródło
Java - 66 znaków
Dłuższa niż poprzednia procedura, ale myślę, że ta zwraca równomiernie rozłożone liczby w krótszym czasie.
źródło
PostScript (46)
Używa binarnego kodowania tokenów, dlatego oto zrzut heksowy:
Aby go wypróbować, możesz go również pobrać .
Oto niepoznany i skomentowany kod wraz z kodem testowym.
źródło
źródło
R (30 znaków)
Zdefiniuj rand7:
Ponieważ R zostało napisane z myślą o analizie statystycznej, to zadanie jest banalne, a ja korzystam z wbudowanej funkcji
sample
z zamiennikiem ustawionym na PRAWDA.Przykładowe dane wyjściowe:
źródło
Groovy
przykładowy rozkład na 35 000 iteracji:
Czy to źle, że jest stanowy?
źródło
Mathematica, 30
źródło
Co powiesz na to?
źródło
/
operator wykonuje matematykę całkowitą? Co stanie się z wynikami, jeśli wykona matematy dziesiętny, zmiennoprzecinkowy lub całkowity?[2/25, 4/25, 5/25, 5/25, 5/25, 3/25, 1/25]
. Niezupełnie jednolity.Java - 54
Test dystrybucji:
[1000915, 999689, 999169, 998227, 1001653, 1000419, 999928]
Algorytm:
> Liczby nie są już wzajemnie nieskorelowane, ale indywidualnie całkowicie przypadkowe.
źródło
Rubinowy (43 bajty)
Rozwiązanie cemper93 przeniesione do Ruby jest trzy bajty krótsze;) (34 bajty)
źródło
Kod C / C ++ kod podstawowy ma tylko jedną linię!
Srand7 () jest zalążkiem rand7, musi wywołać tę funkcję przed rand7, podobnie jak wywołanie srand przed randem w C.
Jest to bardzo dobre, ponieważ wywołuje rand () tylko jeden raz, i nie ma pętli, nie zużywa dodatkowych wspomnień.
Pozwól mi to wyjaśnić: rozważ tablicę liczb całkowitych o rozmiarze 5:
Mamy więc TABELĘ, każda z 1-7 pojawia się w niej 5 razy i ma wszystkie 35 liczb, więc prawdopodobieństwo każdej liczby wynosi 5/35 = 1/7. I następnym razem
Po wystarczającej liczbie razy możemy uzyskać równomierny rozkład 1-7.
Możemy więc przydzielić tablicę, aby przywrócić pięć elementów 1-7 za pomocą przesunięcia w lewo-w pętli i uzyskać za każdym razem jedną liczbę z rand5. Zamiast tego możemy wygenerować wszystkie siedem tablic wcześniej i używać ich cyklicznie. Kod jest również prosty, ma wiele krótkich kodów, które mogą to zrobić.
Ale możemy użyć właściwości operacji%, więc wiersze tabeli 1-7 są równoważne z (rand5 + i)% 7, to znaczy: a = rand ()% 5 + 1 to rand5 w języku C, b = gi ++ % 7 generuje wszystkie permutacje w powyższej tabeli, a 0–6 zastępuje 1–7 c = (a + b)% 7 + 1, generuje 1–7 równomiernie. Wreszcie mamy ten kod:
Ale nie możemy uzyskać 6 i 7 przy pierwszym wywołaniu, więc potrzebujemy zarodka, takiego jak srand dla rand w C / C ++, aby zmienić rozkład permutacji dla pierwszego oficjalnego połączenia.
Oto pełny kod do testowania:
źródło
6
lub7
zadzwonić raz ?int main(){if(rand7()==6) printf("Hello, world!");}
, przybliżenie za pomocą pętli wyświetli „Witaj, świecie!” 1 na 7 razy, ale twój kod nie.