Dane wejściowe: dwie liczby całkowite n i k podane w dowolnej formie dogodnej dla kodu
Wynik Losowa, nie malejąca sekwencja k liczb całkowitych, każda w zakresie od 1 do n. Próbkę należy wybrać jednolicie ze wszystkich nie malejących sekwencji k liczb całkowitych o liczbach całkowitych z zakresu od 1 do n.
Dane wyjściowe mogą być w dowolnym rozsądnym formacie, który uważasz za dogodny.
Możesz użyć dowolnego pseudolosowego generatora, który udostępnia twoja ulubiona biblioteka / język.
Możemy założyć, że liczby całkowite n, k> 0.
Przykład
Powiedz n, k = 2. Nie malejące sekwencje to
1,1
1,2
2,2
Każda sekwencja powinna mieć prawdopodobieństwo 1/3 wyjścia.
Ograniczenie
Twój kod powinien działać w nie więcej niż kilka sekund dla k = 20 i n = 100.
Co nie działa
Jeśli próbkujesz losowo każdą liczbę całkowitą z zakresu od 1 do n, a następnie sortujesz listę, nie uzyskasz jednolitego rozkładu.
źródło
Odpowiedzi:
faktycznie ,
1412 bajtówTa odpowiedź jest oparta na 05AB1E odpowiedź Emigna użytkownika i odpowiedzi na to pytanie Math.SE . Zapraszamy do gry w golfa! Wypróbuj online!
Ungolfing
źródło
Python, 89 bajtów
Generowanie sekwencji rosnącej zamiast nie malejącej byłoby proste: jest to tylko losowy podzbiór
k
liczb między1
in
posortowany.Ale możemy przekonwertować rosnącą sekwencję na nie malejącą, zmniejszając każdą przerwę między kolejnymi liczbami o 1. Tak więc przerwa 1 staje się przerwą 0, tworząc równe liczby. Aby to zrobić, zmniejsz
i
największą wartość oi
Aby wynik był od
1
don
, dane wejściowe muszą być od1
don+k-1
. Daje to bijection między nie zmniejszającymi się sekwencjami liczb pomiędzy1
in
, do rosnących sekwencji między1
in+k-1
. Ten sam bijection stosuje się w argumencie gwiazdy i słupki do zliczania takich sekwencji.Kod korzysta z funkcji python
random.sample
, która pobierak
próbki bez zamiany z listy danych wejściowych. Sortowanie to daje rosnącą sekwencję.źródło
import*
zaoszczędzić 1 bajt)05AB1E , 13 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
Python, 87 bajtów
Prawdopodobieństwo uwzględnienia maksymalnej możliwej wartości
n
jest równek/(n+k-1)
. Aby go dołączyć, umieść go na końcu listy i zmniejsz pozostałe potrzebne liczbyk
. Aby go wykluczyć, zmniejsz górną granicęn
. Następnie powtarzaj tak długo, aż nie będą już potrzebne żadne wartości (k==0
).Wygląda na
random
to, że Python nie ma wbudowanej zmiennej Bernoulliego: 1 z pewnym prawdopodobieństwem i 0 w przeciwnym razie. To sprawdza, czy przypadkowa wartość od 0 do 1 generowana przezrandom
spada poniżejk/(n+k-1)
. Pyton 2 będzie jako współczynnik podziału pływaka, tak że zamiast mnożenia przez mianownikk>random()*(n+k-1)
.źródło
numpy.random
, co jest zbyt długie.JavaScript (Firefox 30+), 74 bajty
Wyjaśnienie
Doskonała odpowiedź xnor na język Python zawiera bardzo dobre podsumowanie tego, jak / dlaczego technika tutaj zastosowana. Pierwszym krokiem jest utworzenie zakresu [1, 2, ..., n + k - 1] :
Następnie musimy wziąć k losowych przedmiotów z tego zakresu. Aby to zrobić, musimy wybrać każdy element z prawdopodobieństwem s / q , gdzie s jest liczbą potrzebnych elementów, a q jest liczbą elementów pozostałych w zakresie. Ponieważ używamy rozumienia tablicowego, jest to dość łatwe:
To daje nam równomiernie rozmieszczoną rosnącą sekwencję liczb. Można to naprawić, odejmując liczbę znalezionych wcześniej elementów j :
Na koniec, przechowując k w j , możemy włączyć
k--
do wyrażenia i zapisać kilka bajtów:źródło
TI-BASIC, 54 bajtów
Postępuj zgodnie z logiką xnor, z niewielkim zastrzeżeniem. Możemy teoretycznie ogolić bajt, wykonując coś takiego:
Ale rand (jest zarezerwowany, aby utworzyć listę liczb losowych, więc nie bylibyśmy w stanie wykonać żądanego domniemanego mnożenia, aby zapisać bajt.
To powinno działać przyzwoicie szybko na 84+ na ograniczenie, ale sprawdzę, aby się upewnić, kiedy będę mógł.
źródło
PHP,
777573 bajtówUruchom tak:
Wyjaśnienie
Poprawki
end()
połączenie i ustawiając$argv[2]
na$k
aby skrócić dostęp do argumentów$i
Zamiast tego zwiększaj każdą iteracjęźródło