Twój program / funkcja powinna
- wypisuje dokładnie jedną liczbę całkowitą
- wyprowadza dowolną liczbę całkowitą z prawdopodobieństwem dodatnim
- wyprowadza liczbę całkowitą większą niż 1.000.000 lub mniejszą niż -1.000.000 z prawdopodobieństwem co najmniej 50%.
Przykładowe dane wyjściowe (wszystkie muszą być możliwe):
59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001
Wyjaśnienia:
- Dopuszczalne jest przerywanie linii końcowej.
- Zera wiodące są niedozwolone.
-0
jest dozwolone.
Najkrótszy kod wygrywa.
way too long to fit in an integer
- Jest to prawdą tylko wtedy, gdy założymy, żeinteger
oznacza toint
typ danych w łuku 32/64 bitowym, co niekoniecznie jest prawidłowym założeniem. „Liczba całkowita” zaczęła się od terminu matematycznego , który nie ma ograniczeń wielkości.Odpowiedzi:
CJam,
161413 bajtówBędzie to działało przez bardzo długi czas, ponieważ wykorzystuje bieżący znacznik czasu (rzędu 10 12 ), aby ustalić, czy pętla powinna się zakończyć. Używam tego jako przesłania, ponieważ jest najkrótszy, ale istnieją dwie 14-bajtowe alternatywy, które mają swoje zalety:
Ten jest nie ograniczony przez okres PRNG, ponieważ zakres wszystkich liczb losowych zależy od aktualnej datownik. Dlatego powinno to być w stanie wygenerować dowolną liczbę, chociaż prawdopodobieństwo dla liczb ujemnych, a nawet małych liczb dodatnich, jest znikomo małe.
Poniżej znajduje się równoważna wersja, która używa
3e5
zamiast znacznika czasu. I20
dla pierwszego zakresu (jako przesłanie 13-bajtowe). Jest znacznie szybszy i spełnia wszystkie zasady. Jest to rodzaj ograniczającego przypadku, aby uzyskać 50% prawdopodobieństwa dla liczb powyżej 1 000 000, przy zachowaniu rozsądnego czasu działania i małego rozmiaru kodu. Wyjaśnienie i matematyczne uzasadnienie odnoszą się do tej wersji:Uruchomienie zajmuje zwykle kilka sekund. Można wymienić
5
z2
aby go uruchomić nawet szybciej. Ale wtedy wymóg 50% prawdopodobieństwa zostanie spełniony tylko dla 1000 zamiast 1 000 000.Zaczynam od 0. Potem mam pętlę, z której zerwałam z prawdopodobieństwem 1 / (3 * 10 5 ). W tej pętli dodam losową liczbę całkowitą od -1 do 18 (włącznie) do mojej sumy bieżącej. Istnieje skończone (aczkolwiek małe) prawdopodobieństwo, że każda liczba całkowita zostanie wyprowadzona, przy czym liczby całkowite dodatnie są znacznie bardziej prawdopodobne niż wartości ujemne (nie sądzę, byś widział wartość ujemną w swoim życiu). Wybicie z tak małym prawdopodobieństwem i zwiększenie czasu (i dodanie znacznie więcej niż odejmowanie) gwarantuje, że zwykle przekroczymy 1 000 000.
Niektóre matematyczne uzasadnienie:
Prawdopodobieństwo, że zrobimy mniej niż ta liczba kroków, jest
co ocenia na
0.324402
. Dlatego w około dwóch trzecich przypadków podejmiemy więcej 117 647 kroków, a każdy z nich z łatwością 1 000 000.9e9
bez dodawania bajtów (ale lat pracy).... lub 11 bajtów?
Wreszcie istnieje 11-bajtowa wersja, która nie jest również ograniczona przez okres PRNG, ale której zabraknie pamięci za każdym razem. Generuje tylko jedną liczbę losową (na podstawie znacznika czasu) podczas każdej iteracji i używa jej zarówno do zwiększania, jak i kończenia. Wyniki każdej iteracji pozostają na stosie i są sumowane tylko na końcu. Podziękowania dla Dennisa za ten pomysł:
źródło
Kmr
w danym okresie jest nadal prawdopodobnie dużą liczbą dodatnią większą niż okres. W takim przypadku nie może wygenerować wszystkich możliwych liczb.Java,
133149Przykładowe dane wyjściowe
Bez golfa
Stara odpowiedź (przed zmianą reguły)
źródło
-
.Mathematica - 47
Zasadniczo wystarczy wygenerować liczbę losową przy użyciu rozkładu normalnego z wariancją równą 1500000. To da liczbę całkowitą między -10 ^ 6 a 10 ^ 6 z prawdopodobieństwem 49,5015%.
źródło
Python 2,
7569 bajtówTrywialne jest sprawdzenie, czy pętla while w środku może generować wszystkie liczby całkowite (choć tendencyjne w kierunku zera). „12” wybiera się w taki sposób, że z grubsza połowa liczb przekracza ± 10 6 .
Starsze rozwiązanie:
Python 2, 44 bajtyNa podstawie rozwiązania Mathematica .Naprawdę nie działa, ponieważ Python
float
ma tylko skończoną precyzję.źródło
Ruby, 70
Aby generowanie bardzo dużych liczb było możliwe, zwracam liczbę jako
String
z lambda. Jeśli nie jest to dozwolone, policz 8 dodatkowych znaków (forputs f[]
), aby uczynić go programem zamiast funkcji.Wyjaśnienie
Wygeneruj liczbę pomiędzy
-1,000,000
a1,000,000
. Jeśli liczba jest równa1
lub wyższa, liczba jest zwracana jakoString
.Jeśli liczba jest niższa niż
1
, funkcja jest wywoływana rekurencyjnie, aby zwrócić liczbę spoza zakresu liczb. Aby mieć pewność, że można również wygenerować liczby ujemne,-
do wyniku powstaje a,String
jeśli liczba początkowa jest większa niż-500,000
.Mam nadzieję, że poprawnie zrozumiałem wyzwanie!
źródło
R, 38
Dobiera z rozkładu Gaussa ze średnią 2 000 000 losowo dobranymi odchyleniami standardowymi 1 000 000, tak że około 2/3 losowań będzie mieścić się w przedziale od 1 000 000 do 3 000 000. Rozkład jest nieograniczony, więc teoretycznie może to generować dowolną liczbę całkowitą. Pakiet Rmpfr zastępuje wbudowane podwójne pływaki R z dowolną precyzją.
źródło
sample(c(1,-1),1)
myśli. Wystarczy wycentrować na 1e6.Perl, 53 znaki
Na pewno nie widzę powodu, aby pracować z liczbami całkowitymi podczas drukowania jednego :)
Ma równe prawdopodobieństwo wydrukowania liczby z wiodącym „-” lub bez niego.
Drukuje 1-cyfrową liczbę 10% czasu, 2-cyfrową liczbę 9% czasu, 3-cyfrową liczbę 8,1% czasu, 4-cyfrową liczbę 7,29% czasu, 5-cyfrową liczbę 6,56% czasu, 6-cyfrowa liczba 5,9% czasu itp. Możliwa jest dowolna długość ze zmniejszającym się prawdopodobieństwem. Liczby od jednego do pięciu cyfr stanowią około 41,5% przypadków wyjściowych, a liczba 1 000 000 (lub 1 000 000) tylko 6 milionów części procentowych, więc liczba wyjściowa będzie poza zakresem od 1 000 000 do 1 000 000 około 54,6 % czasu.
Zarówno „0”, jak i „-0” są możliwymi wyjściami, które, mam nadzieję, nie stanowią problemu.
źródło
print int(rand(20)-10)||1
. Potrzebuję jednak sposobu na wygenerowanie 0 jako wyniku. Może || umrze 0, jeśli końcowe śmieci po zero są dozwolone. W przeciwnym razie potrzebna jest krótka droga, aby wydrukować zero i wyjść bez dalszego wyjścia, jeśliint(rand(20)-10)==0
.Perl, 114 znaków
Awaria:
Prawdopodobieństwo uzyskania wartości od -1 000 000 do 1 000 000 zmierza w kierunku zera, ALE jest to możliwe.
Perl, 25Generuje losową liczbę całkowitą w zakresie +/- 2 ^ 99.
Awaria
Testowany z 1 milionem próbek:
Spełnia to wszystkie zasady:
Edytować:
Musiałem zwiększyć wykładnik, aby generowane były większe liczby całkowite. Wybrałem 99, ponieważ kod jest tak krótki, jak to możliwe.źródło
-2^31
i+2^31-1
(32 bity). Możesz łatwo zwiększyć wykładniki, jeśli chcesz wygenerować większe liczby całkowite, ale może się nie powieść w zależności od implementacji Perla.1.#INF
a dokładniej)DO#,
126107 bajtówNie golfowany:
Szansa na wygenerowanie liczby n cyfr wynosi 1/2 (n-10), co jest większe niż 0 dla wszystkich dodatnich n, a 1/2 dla n = 11.
Tworzy również wiodące zera, które nie wydają się być niedozwolone w pierwotnym pytaniu ani w żadnym z jego komentarzy.źródło
using System;
nie potrzebujeszSystem.Random
dwa razy, ale tylkoRandom
, prawda?using
statements. It would only save 1 char anyways.-1E6, 1E6+1
.Perl, 62 bytes
print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}
I had the same idea as @Hobbs, of generating a digit at a time, but his code didn't satisfy the added no-leading-zeros requirement. Generating the first digit instead of just the sign solved that. And unless there's a shorter way to exit if we printed a zero, or a shorter way to generate the leading -9 to 9, this should do it for size.
In a shell loop:
while perl -e '...'; do echo;done |less
I think this is one of the shortest that doesn't require infinite RAM to satisfy the problem. As a bonus, the output is isn't strongly biased towards anything, and runtime is very fast.
I tried using bitwise and to save a character in the while condition, but I think this ends up being true more often, so the loop ends sooner. Would need more chars to adjust other things to counter that, to maintain the probability of generating abs(output) > 1M.
źródło
Javascript (73)
This solution uses that you can construct a number with base n by multiplying the previous number with n and adding a digit in base n. We have an additional
..?..:..
in there to be able to create all negative integers. The following code should be tested in a browser console.The probability to get an integer >=
2^1
(or <=-(2^1)
) is equal to the chance that the loop is ran 2 times. The chance of that happening is(98/99)^2
. The chance of getting a number that is greater than2^20
(or <=-(2^20)
) is therefore(98/99)^21 = 0.808
or 81%. This is all in theory though, and assuming that Math.random is truely random. It obviously isn't.Snippet testing this code. Also in a more readable fashion.
Show code snippet
źródło
GolfScript, 20 bytes
Yeah, this one is also kind of slow.
Compared to languages like CJam and Pyth, GolfScript suffers from a verbose random number generation keyword (
rand
). To overcome this handicap, I needed to find a way to use it only once.This code works by repeatedly picking a random number between 0 and 88−1 = 16,777,215 inclusive, and incrementing a counter until the random number happens to be 0. The resulting counter value has a geometric distribution with a median approximately -1 / log2(1 − 1/88) ≈ 11,629,080, so it meets the "over 1,000,000 at least 50% of the time" test.
Alas, the random number thus generated is always strictly positive. Thus, the extra
.2&(*4/
part is needed to let it become negative or zero. It works by extracting the second-lowest bit of the number (which is thus either 0 or 2), decrementing it to make it -1 or 1, multiplying it with the original number, and dividing the result by 4 (to get rid of the lowest two bits, which are now correlated with the sign, and also to allow the result to become zero). Even after the division by 4, the absolute value of the random number still has a median of -1 / log2(1 − 1/88) / 4 ≈ 2,907,270, so it still passes the 50% test.źródło
JavaScript, 81 bytes
This code fulfills all the rules:
0
in the outputAs a bonus, the algorithm runs with a time complexity of O(log10n) so it returns the integer almost instantly.
This assumes an REPL environment. Try running the above code in your browser's console, or use the stack snippet below:
Algorithm:
s
until aMath.random() > 0.1
.Math.random() > 0.5
, make the number negative (by prepending the strings
with-
).This algorithm does not have a uniform distribution across all integers. Integers with higher digit count are less probable than the lower ones. In each for loop iteration, there is a 10% chance that I will stop at the current digit. I just have to make sure that I stop after 6 digits more than 50% of the time.
This equation by @nutki explains the maximum value of stopping chance percentage based on the above condition:
Thus 0.1 is well within range to satisfy all the three rules of the question.
źródło
TI-BASIC, 14 bytes
Similar to @ssdecontrol's R answer, this draws from the Gaussian distribution with mean -1,000,000 or 1,000,000, chosen randomly, and standard deviation 9. The distribution is unbounded so in theory this can generate any integer.
Explanation:
źródło
:
means "print" due to how the explanation is presented). But can it generate numbers more than 20 digits?randNorm
?Bash, 66
It almost always prints 5000000. But if it found a valid number in
/dev/random
, it will print that number instead.And this one is faster:
źródło
/dev/urandom
which is less random./dev/urandom
in a shell script is basically the same as callingrand()
in other languages. Although if you're really using bash, not POSIX sh, you can get random numbers fromecho $RANDOM
. wiki.ubuntu.com/DashAsBinSh giveshexdump /dev/urandom
as an equivalent for bare-POSIX-minimum/bin/dash
.C++, 95 bytes
Expanded:
Explanation:
The function keeps on printing consecutive random digits until a random valued switch takes the required value to stop the function. d is the variable that keeps the value of the next digit to be printed. s is the switch variable that takes random integer values in the interval [0, 9], if s == 9 then no more digits are printed and the funtion ends.
The variables d and s are initialized in order to give special treatment to the first digit (taking it from the interval [-9, 9] and if the first digit is zero then the function must end to avoid leading zeroes). The value of d could be assigned as d=rand()%10 but then the first digit couldn't be negative. d is assigned instead as d=(rand()%19+d+9)%10 and initialized at -18 so the first value of d will range from [-9, 9] and the next values will always range from [0, 9].
The variable s ranges randomly from [0, 9], and if s equals 9, the function ends, so after printing the first digit the next one will be printed with a probability of 90% (assuming rand() is truly random, and in order to satisfy the third condition). s could be easily assigned as s=rand()%10, however, there is an exception, if the first digit is zero, the function must end. In order to handle such exception, s has been assigned as s=9-rand()%10*min(d*d+s+1,1) and initialized as -1. If the first digit is zero, the min will return 0 and s will equal to 9-0=9. s variable's assignment will always range from [0, 9], so the exception can only occur at the first digit.
Characteristics (assuming rand() is truly random)
The integer is printed digit by digit, with a fixed probability of 90% of printing another digit after printing the last one.
0 is the integer with highest chance of being printed, with a probability of aproximately 5.2%.
The probability of printing an integer on the interval [-10^6, 10^6] is aproximately 44% (the calculation is not written here).
Positive and negative integers are printed with the same probability (~47.4%).
Not all digits are printed with the same probability. For example: in the middle of printing the integer, if the last digit was 5, the digit 3 will have a slightly lower chance of being printed next. In general, if the last digit was d, the digit (d+18)%10 will have a slightly lower chance of being printed next.
Example outputs (10 executions)
źródło
Bash, 42 bytes
printf "%d\n" 0x$(xxd -p -l5 /dev/random)
/dev/random on OSX is just random bytes, and
xxd -p -l5
converts 5 of the ascii characters to hex, andprintf
turns it into decimal format.źródło
Pyth, 11 bytes
Note: this program will probably crash with a memory error on any real computer. To test it, try replacing
G
with a shorter string, such as in this code, which generates numbers averaging around 28000:This code loops, adding a random number from -1 to 8 to
Z
, with a 2^-26 probability of exiting the loop on each repetition. The 2^-26 probability is attained by selecting a random element (O
) of the set of all subsets (y
) of the alphabet (G
).Technical details & justification:
The probability 2^-26 is derived from two facts:
y
, when called on sequences, is the power-set function, an constructs the list of all subsets of the input. Since the input,G
, is 26 characters long, this power-set,yG
has 2^26 entries.OyG
selects a random element from those 2^26 entries. Exactly one of those entries, the empty string, will evaluate as falsy when passed toW
, the while loop. Therefore, there is a 2^-26 probability of exiting the loop each time.In any fixed number of loop cycles K, the probability of getting the number K*3.5 + m and getting K*3.5 - m are equal, because each sequences of addends that achieves one total can be inverted, -1 -> 8, 0 -> 7, etc., to achieve the other. Additionally, numbers closer to K*3.5 are clearly more likely than numbers farther away. Thus, if K > 2000000/3.5 = 571428.5 the probability of getting a number over 1000000 is greater than 75%, because some of the results above that number can be put into a one-to-one correspondence with all of the results below that number, and the upper less-than-half, can be put into a one-to-one correspondence with those under 1000000. The probability of getting at least 571429 loops is (1-2^-26)^571429, which is no less than (1-2^-26 * 571429), the expected number of times leaving the loop over the first 571429 tries, which is 99.1%. Thus, on 99.1% or more of trials, there is a 75% or more chance of getting at least 1000000, so there is more than a 50% chance of getting over 1000000.
This code relies on a behavior of
O
where a bug was accidentally introduced 3 days ago and was fixed today. It should work on any version of Pyth 3 from before Dec 22nd, or after today. The following code is equivalent, and has always worked:źródło
Java, 113 bytes
This program prints a binary number to standard output stream. You might have to wait a while because the probability of it ending the number (or it being positive) is approximately 0. The idea that the absolute value of a number generated is less than 1 million is amusing, yet possible.
Ungolfed:
Sample output: Will post when a number is done being generated.
źródło
Java (JDK),
140127 bytes-13 bytes
by sneaking more logic into the loop header - thanks to @ceilingcatTry it online!
źródło