Створити будь-яке випадкове ціле число


17

Ваша програма / функція повинна

  • вивести рівно одне ціле число
  • вивести будь-яке ціле число з позитивною ймовірністю
  • вивести ціле число, що перевищує 1 000 000 або менше -1 000 000, принаймні з 50% ймовірністю.

Приклади виходів (усі повинні бути можливими):

59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001

Роз'яснення:

  • Допускається розрив кінцевої лінії.
  • Провідні нулі заборонені.
  • -0 дозволено.

Найкоротший код виграє.


2
@Optimizer Чому ви припускаєте однакову ймовірність? У цьому питанні не зазначено. Насправді з цього погляду зрозуміло, що розподіл не повинен бути рівномірним, доки принаймні 50% його не виходить за межі [-1 мільйона, 1 мільйон].
варення

10
Рішення, яке створює " рівномірний розподіл на всі цілі числа", неможливо. Цілих цілих чисел є нескінченно багато, тому кожне окреме ціле число з’явиться з вірогідністю 0. (Або: Виведення кінцевого числа означатиме, що ви нехтуєте нескінченно багатьма іншими!) Будь-яке рішення доведеться зневажити більш високі значення, щоб досягти Р (загальний ) = 1.
joeytwiddle

2
@Ypnypn Оперативна пам’ять комп'ютера також не є межею. Вам не доведеться зберігати частковий вихід ніде.
jimmy23013

4
@GiantTree - way too long to fit in an integer- Це правда лише в тому випадку, якщо ви припускаєте, що це integerозначає intтип даних на аркуші 32/64 біт, що не обов'язково є припустимим припущенням. "Цілий" почався як математичний термін , який не має обмежень щодо розміру.
Підроблена назва

5
Кожен, хто використовує генератор псевдовипадкових чисел для прийняття своїх рішень щодо виводу, виключає майже всі цілі числа та встановлює верхню межу розміру цілих чисел, які можуть бути вироблені (якщо припустити, що у PRNG є обмежений період). Чи можна це не враховувати у відповідях чи потрібна коректна відповідь справжнього генератора випадкових чисел?
трихоплакс

Відповіді:


12

CJam, 16 14 13 байт

0{Kmr(+esmr}g

Це буде працювати дуже довго, тому що він використовує поточну позначку часу (для порядку 10 12 ), щоб визначити, чи повинен цикл закінчуватися. Я використовую це як подання, оскільки це найкоротше, але є два 14-байтові альтернативи, які мають свої достоїнства:

0{esmr(+esmr}g

Цей не обмежений періодом PRNG, оскільки діапазон усіх випадкових чисел залежить від поточної мітки часу. Таким чином, це повинно бути в змозі створити будь-яке число, хоча ймовірність негативних чи навіть малих додатних чисел зникає мало.

Нижче представлена ​​еквівалентна версія, яка використовує 3e5замість часової позначки. І 20для першого діапазону (як 13-байтне подання). Це набагато швидше, а також дотримується всіх правил. Це свого роду обмежувальний випадок, щоб отримати 50-відсоткову ймовірність для чисел, що перевищують 1 000 000, зберігаючи розумний час виконання та невеликий розмір коду. Пояснення та математичне обґрунтування стосуються цієї версії:

0{Kmr(+3e5mr}g

Зазвичай на це потрібно кілька секунд. Ви можете замінити 5з , 2щоб зробити його працювати ще швидше. Але тоді вимога 50% -ної ймовірності буде виконана лише за 1000 замість 1 000 000.

Я починаю з 0. Потім у мене є цикл, який я вириваю з вірогідністю 1 / (3 * 10 5 ). У цьому циклі я додаю випадкове ціле число від -1 до 18 (включно) до моєї загальної суми. Існує кінцева (хоча і мала) ймовірність того, що кожне ціле число буде виведене, при цьому додатні цілі числа набагато частіше, ніж негативні (я не думаю, що ви побачите негативне протягом свого життя). Виведення з такою малою ймовірністю та збільшення більшої частини часу (і додавання набагато більше, ніж віднімання) гарантує, що ми зазвичай виходимо за межі 1 000 000.

0              "Push a 0.";
 {          }g "Do while...";
  Kmr          "Get a random integer in 0..19.";
     (         "Decrement to give -1..18.";
      +        "Add.";
       3e5mr   "Get a random integer in 0..299,999. Aborts if this is 0.";

Деякі математичні обгрунтування:

  • На кожному кроці ми додаємо в середньому 8,5.
  • Щоб дістатися до 1 000 000, нам потрібно 117 647 цих кроків.
  • Ймовірність того, що ми зробимо менше, ніж ця кількість кроків

    sum(n=0..117,646) (299,999/300,000)^n * 1/300,000
    

    який оцінює до 0.324402. Отже, приблизно в дві третини випадків ми зробимо більше 117 647 кроків і легко кожен 1 000 000.

  • (Зауважте, що це не точна ймовірність, оскільки коливання будуть приблизно середніми 8,5, але, щоб досягти 50%, нам потрібно вийти за рамки 117,646 до приблизно 210 000 кроків.)
  • Якщо ви сумніваєтесь, ми можемо легко підірвати знаменник ймовірності припинення, аж до 9e9додавання байтів (але років виконання).

... або 11 байт?

Нарешті, є 11-байтна версія, яка також не обмежена періодом PRNG, але яка буде втрачати пам'ять майже кожного разу. Він генерує лише одне випадкове число (на основі часової позначки) кожної ітерації та використовує його як для збільшення, так і для завершення. Результати кожної ітерації залишаються на стеку і підсумовуються лише в кінці. Дякуємо Деннісу за цю ідею:

{esmr(}h]:+

Я додав коментар до питання, щоб побачити, чи потрібні правила справжній генератор випадкових чисел, але я здогадався, що ви оціните педантизм. Чи є тут ваше псевдо випадкове джерело? Це обмежило б розмір набору можливих результатів максимум на період вашого PRNG, правда?
трихоплакс

(+1 незалежно від простої елегантності)
трихоплакс

Так, я досі здогадуюсь. Мені цікаво дізнатись, чи хтось публікує відповідь без цієї проблеми ...
trichoplax

Я бачу, що ОП заявила, що ви можете припустити, що ваш генератор випадкових чисел є справжнім генератором випадкових чисел, чи він є, чи ні - тож це тепер
зайве

Сума Kmrза період, ймовірно, завжди є великим додатним числом, більшим за період. І в цьому випадку він не може створити всі можливі числа.
jimmy23013

11

Ява, 133 149

void f(){String s=x(2)<1?"-":"";for(s+=x(9)+1;x(50)>0;s+=x(10));System.out.print(x(9)<1?0:s);}int x(int i){return new java.util.Random().nextInt(i);}

Приклади виходів

-8288612864831065123773
0
660850844164689214
-92190983694570102879284616600593698307556468079819964903404819
3264

Безумовно

void f() {
    String s = x(2)<1 ? "-" : "";       // start with optional negative sign
    s+=x(9)+1;                          // add a random non-zero digit
    for(; x(50)>0; )                    // with a 98% probability...
        s+=x(10)                        // append a random digit
    System.out.print(x(9)<1 ? 0 : s);   // 10% chance of printing 0 instead
}

int x(int i) {
    return new java.util.Random().nextInt(i);
}

Стара відповідь (перед зміною правила)

void f(){if(Math.random()<.5)System.out.print('-');do System.out.print(new java.util.Random().nextInt(10));while(Math.random()>.02);}

Ви обоє правильні, але в запитанні зазначено, що ймовірність повинна бути принаймні 50%, не в межах +/- 1.000.000
GiantTree

@Optimizer Redone.
Ypnypn

Якщо ви використовуєте двійкові літерали, ви не повинні їх друкувати -.
TheNumberOne

4

Математика - 47

Round@RandomVariate@NormalDistribution[0,15*^5]

В основному просто генеруйте випадкове число, використовуючи звичайний розподіл з відхиленням, рівним 1500000. Це призведе до цілого числа між -10 ^ 6 і 10 ^ 6 з вірогідністю 49,5015%.


"Це дасть ціле число між -10 ^ 6 і 10 ^ 6 з вірогідністю 50.4985%." - цього недостатньо. Ви неправильно прочитали специфікацію? Можливо, ви мали намір використовувати 10 ^ 7 як дисперсію?
Джон Дворак

@JanDvorak Неправильна ймовірність, вибачте. Тепер це правильний.
швед

Чи реально реалізація цього в Mathematica охоплює всі цілі числа? У мене немає доступу до джерела, але я б здогадався, що не ...
trichoplax

@githubphagocyte Це залежатиме від точності току.
швейцарський

4
Я маю на увазі те, що конкретизація будь-якої конкретної точності буде виключати числа, що перевищують це. Єдиний спосіб це може працювати, якби ви могли вказати необмежену точність.
трихоплакс

4

Пітон 2, 75 69 байт

from random import*;s=0;j=randrange
while j(12):s=s*9+j(-8,9)
print s

Тривіально перевірити, що цикл while в середині може генерувати всі цілі числа (хоча і упереджені до нуля). "12" вибирається таким, що приблизно половина чисел перевищує ± 10 6 .


Старіше рішення:

Python 2, 44 байти

На основі рішення Mathematica .

from random import*;print int(gauss(0,8**7))

Насправді не працює, тому що Python floatмає лише обмежену точність.


Це не зможе генерувати всі цілі числа, оскільки генератор псевдовипадкових чисел має кінцеву кількість внутрішнього стану. Згідно з документацією, Python використовує Mersenne Twister, тому стан досить великий. Але це не нескінченно, тому може створювати лише кінцеве підмножину всіх цілих чисел.
starblue

@starblue: З ОП: "Ви можете припустити, що генератор випадкових чисел вашої мови є справжнім генератором випадкових чисел, навіть якщо це не так."
kennytm

3

Рубі, 70

f=->{m=10**6
r=rand -m..m
r<1?(r>-5e5??-:'')+r.to_s+f[][/\d+/]:r.to_s}

Щоб зробити можливість генерування дуже великих чисел, я повертаю це число як String лямбда. Якщо це не дозволено, порахуйте ще 8 символів (для puts f[]), щоб зробити його програмою замість функції.

Пояснення

Утворіть число між -1,000,000і 1,000,000. Якщо число більше 1або вище, число повертається у вигляді аString .

Якщо число нижче 1, функція викликається рекурсивно для повернення числа поза діапазону чисел. Щоб переконатися, що також можна генерувати негативні числа, -до отриманого префіксу додається префіксString якщо початкове число більше, ніж -500,000.

Я сподіваюся, що я правильно зрозумів виклик!


3

R, 38

library(Rmpfr)
round(rnorm(1,2e6,1e6))

Малюнки з розподілу Гаусса із середнім значенням 2 000 000, вибраним випадковим чином, та зі стандартним відхиленням 1 000 000, так що приблизно 2/3 розіграшів буде лежати в межах 1 000 000 і 3 000 000. Розподіл необмежений, тому теоретично це може генерувати будь-яке ціле число. Пакет Rmpfr замінює вбудовані подвійні поплавці R з довільною точністю.


Так, я зрозумів, що я неправильно прочитав специфікацію. І я думаю, він має ті ж обмеження щодо точності машин із Mathematica
shadowtalker

Хм, в цьому випадку я не впевнений. Мені доведеться заглянути в це; розгляньте цю відповідь "на затриманні" наразі
shadowtalker

@ MartinBüttner виправлено, я думаю
shadowtalker

Цікаво. Я не думаю, що вам потрібно все sample(c(1,-1),1)думати. Просто центрування в 1e6 повинно вистачити ..
Мартін Ендер

@ MartinBüttner о, це не потрібно бути 50% на обох кінцях? Це було не ясно
shadowtalker

2

Perl, 53 символи

print"-"if rand>.5;do{print int rand 10}while rand>.1

Я, звичайно, не бачу причин для цього працювати з цілими числами при друкуванні одного :)

Має рівну ймовірність друку номера з провідним "-" або без нього.

Друкує одноцифрове число 10% часу, двозначне число 9% часу, 3-розрядне число 8,1% часу, 4-значний номер 7,29% часу, 5-значний номер 6,56% часу, 6-розрядне число 5,9% часу тощо. Можлива будь-яка довжина, зі зменшенням ймовірності. На один чи п'ятизначний цифри припадає близько 41,5% випадків виведення, а число 1 000 000 (або -1 000 000) лише 6 мільйонів відсотків, тому число виходу буде поза діапазону від -1 000 000 до 1 000 000 приблизно 54,6 % часу.

І "0", і "-0" є можливими виходами, що, сподіваюся, не є проблемою.


Чи не роздруковує цей "номер", як -00000000167? Це насправді не ціле число.
isaacg

1
@isaacg Я не бачу, чому це не ціле число.
Оптимізатор

2
@Optimizer Так, але ОП явно заборонив вести 0.
Мартін Ендер

Ви можете створити випадкову ненульову провідну цифру перед циклом, від -9 до +9. print int(rand(20)-10)||1. Мені потрібен спосіб генерувати 0 як вихід. Можливо, || помре 0, якщо дозволено сміття після нуля. Ще потрібно короткий спосіб надрукувати нуль і вийти без подальшого виведення, якщо int(rand(20)-10)==0.
Пітер Кордес

@PeterCordes погодився, це пристойний підхід, але мені не подобається писати його, і я не думаю, що це було б конкурентоспроможним по довжині. Не соромтеся подавати його самостійно :)
варення

2

Perl, 114 Chars

use Math::BigInt;sub r{$x=Math::BigInt->new(0);while(rand(99)!=0){$x->badd(rand(2**99)-2**98);}print($x->bstr());}

Зламатися:

use Math::BigInt;               -- include BigIntegers
  sub r{                        -- Define subroutine "r"
    $x=Math::BigInt->new(0);    -- Create BigInteger $x with initial value "0"
      while(rand(99)!=0){       -- Loop around until rand(99) equals "0" (may be a long time)
        $x->badd(               -- Add a value to that BigInt
          rand(2**99)-2**98);   -- Generate a random number between -2^98 and +2^98-1
        }print($x->bstr());}    -- print the value of the BigInt

Ймовірність отримати значення від -1.000.000 до 1.000.000 має тенденцію до нуля, Але це можливо.

Примітка. Ця підпрограма може тривалий час працювати і вимикати помилку "Без пам'яті!" помилка, але це технічно генерує будь-яке ціле число, як зазначено в питанні.

Перл, 25

sub r{rand(2**99)-2**98;}

Створює випадкове ціле число в межах +/- 2 ^ 99.

Зламатися

sub r{                    -- Define subroutine "r"
     rand(2**99)          -- Generate a random integer between 0 and 2^99
                -2**98;}  -- Subtract 2^98 to get negative values as well

Випробувано на 1 мільйон проб:

~5 are inside the range of +/-1.000.000
~999.995 are outside that range
= a probability of ~99,99% of generating an integer outside that range.
Compare that number to the probability of 2.000.000 in 2^99: It is approx. the same.

Це відповідає всім правилам:

  • 1 ціле число
  • будь-яке ціле число можливе
  • щонайменше 50% (у моєму випадку 99,99%) усіх генерованих цілих чисел виходять за межі +/- 1.000.000.

Це працює, тому що базовий генератор випадкових чисел визначає однакову ймовірність для кожного генерованого біта, роблячи це також і для генерованих цілих чисел.
Кожне ціле число має ймовірність генерувати 1/2 ^ 99.

Редагувати:

Мені довелося збільшити показник, щоб генерувалися більші цілі числа. Я вибрав 99, оскільки він зберігає код якомога коротше.


Хіба ми не погоджувалися, що верхня / нижня межі не повинна бути? Наприклад, ціле число 2 ^ 31 + 1 має 0 ймовірностей, порушуючи правило 2
Оптимізатор

@Optimizer для мене визначається ціле число, як у багатьох мовах програмування: число в межах -2^31та +2^31-1(32 біт). Ви можете легко збільшити показники, якщо ви хочете генерувати більші цілі числа, але це може вийти з ладу в залежності від реалізації Perl.
GiantTree

Я щойно бачив, що має бути сформовано і це смішно велике ціле число. Я швидко відредагую свій код.
GiantTree

@ MartinBüttner Я постарався зробити все можливе, щоб відповідати специфіці питання. Мені просто неможливо (принаймні, не без допомоги) генерувати нескінченно великі цілі числа. Найбільше ціле число Perl - це приблизно 1,7e308, що є межею, яку я не можу контролювати.
GiantTree

@ MartinBüttner Обидва можливі, але наприклад. рядок переповнюється після 2 Гб даних, що робить її знову кінцевою. Важко сказати, що число має бути нескінченно великим, якщо є проблеми із пам'яттю. Я скоро придумаю інший підхід, використовуючи BigInts. Також ціле число не переповнюється в 1.7e308, воно просто перетворюється на нескінченне ( 1.#INFякщо бути точним)
GiantTree

2

C #, 126 107 байт

string F(){var a=new System.Random();var b=a.Next(-1E6,1E6+1)+"";while(a.Next(1)>0)b+=a.Next(10);return b;}

Безголовки:

string F()
{
    System.Random rand = new System.Random();
    string rtn = rand.Next(-1E6, 1E6 + 1) + "";
    while (rand.Next(1) > 0)
         rtn += a.Next(10);
    return rtn;
}

Шанс генерувати кількість n цифр становить 1/2 ^ (n-10), що більше 0 для всіх позитивних n, і 1/2 для n = 11.Також створює провідні нулі, які, здається, не заборонені в оригінальному запитанні чи будь-яких його коментарях.


Під час використання using System;вам не потрібно System.Randomдвічі, а просто Random, правда?
Чарлі

@Charlie Це функція, тому я не можу використовувати usingзаяви. Це врятувало б лише 1 char.
LegionMammal978

1
Ви можете зберегти 1 char, видаливши пробіл у -1E6, 1E6+1.
ProgramFOX

2

Perl, 62 байти

print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}

Я мав таку ж ідею, що і @Hobbs, генерувати цифру за один раз, але його код не задовольняв додатковій вимозі нульових нульових нульових значень. Генерування першої цифри замість просто знаку вирішило це. І якщо немає коротшого способу виходу, якщо ми надрукували нуль, або коротший спосіб генерувати провідні -9 до 9, це слід зробити для розміру.

У петлі оболонки: while perl -e '...'; do echo;done |less

Я думаю, що це одна з найкоротших, яка не потребує нескінченної оперативної пам’яті для задоволення проблеми. Як бонус, результат не є сильно упередженим ні до чого, а час виконання дуже швидкий.

Я спробував використовувати побіжно і зберегти персонажа в умові, але я думаю, що це частіше буває істинним, тому цикл закінчується швидше. Буде потрібно більше символів, щоб скорегувати інші речі, щоб протистояти цьому, щоб зберегти ймовірність генерації abs (вихід)> 1М.


Приємно, ти вичавив деякі речі, про які я б не подумав :)
hobbs

1

Javascript (73)

Це рішення використовує те, що ви можете побудувати число з базою n , помноживши попереднє число на n і додавши цифру в базу n . У нас є додаткове, ..?..:..щоб ми могли створити всі негативні цілі числа. Наступний код слід перевірити на консолі браузера.

b=Math.round;c=Math.random;x=0;while(b(c()*99)){x*=b(c())?2:-2;x+=b(c())}

Ймовірність отримати ціле число> = 2^1(або <= -(2^1)) дорівнює ймовірності, що цикл буде запущений у 2 рази. Шанс того, що трапиться, є (98/99)^2. Тому ймовірність отримати число, яке перевищує 2^20(або <= -(2^20)), становить (98/99)^21 = 0.808або 81%. Це все теоретично, але якщо припустити, що Math.random є дійсно випадковим. Очевидно, це не так.


Фрагмент тестування цього коду. Також в більш читаному вигляді.


1
The OP has now confirmed that you can assume that your PRNG is truly random, even if it isn't.
trichoplax

1

GolfScript, 20 bytes

0{)8.?rand}do.2&(*4/

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.

Цей код працює шляхом багаторазового вибору випадкового числа між 0 і 8 8 −1 = 16 777 215 включно, і нарощення лічильника до тих пір, поки випадкове число не стане 0. Отримане значення лічильника має геометричний розподіл з медіаною приблизно -1 / log 2 (1 - 1/8 8 ) ≈ 11 629,080, тому він відповідає тесту "понад 1 000 000 принаймні 50% часу".

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.


1

JavaScript, 81 bytes

This code fulfills all the rules:

  • Output any integer with positive probability
  • Output integers outside the range of +/-1000000 with at least 50% probability
  • No leading 0 in the output

As a bonus, the algorithm runs with a time complexity of O(log10n) so it returns the integer almost instantly.

for(s="",r=Math.random;r()>.1;s+=10*r()|0);r(s=s.replace(/^0*/,"")||0)<.5?"-"+s:s

This assumes an REPL environment. Try running the above code in your browser's console, or use the stack snippet below:

D.onclick = function() {
  for(s="", r=Math.random;r()>.1; s+=10*r()|0);
  P.innerHTML += (r(s=s.replace(/^0*/,"") || 0) <.5 ?"-" + s : s) + "<br>"
}
<button id=D>Generate a random number</button><pre id=P></pre>

Algorithm:

  • Keep appending random digits to string s until a Math.random() > 0.1.
  • Based on Math.random() > 0.5, make the number negative (by prepending the string s 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:

1 - 50%^(1/6) ≈ 0.11

Thus 0.1 is well within range to satisfy all the three rules of the question.


There are a few things that confuse me about this answer. Have you assumed that Math.random() generates a uniform distribution of random numbers, because the spec states that it is implementation dependent. Assuming that it is a uniform distribution, P(Math.random()>0.1)=0.9 so there is a huge probability that it will terminate between each iteration. An implementation of your algorithm run on Firefox 34.0 Ubuntu gives me a probability of ~0.47 (<0.5) every time that I test it: jsfiddle.net/WK_of_Angmar/dh8gq4pb
Wk_of_Angmar

Also, how have you managed to calculate a time complexity for an algorithm without an input?
Wk_of_Angmar

1

TI-BASIC, 14 bytes

1-2int(2rand:randNorm(AnsE6,9

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:

1-2int(2rand     - get a random integer 0 or 1, then multiply by 2 and subtract 1
:                - this gives the number 1 or -1 (with equal probability) to Ans
randNorm(AnsE6,9 - displays Gaussian distribution with mean (Ans * 1,000,000) and std. dev. 9

But can it generate "2" or "-2"?
kennytm


1
OK read the code wrongly (thought : means "print" due to how the explanation is presented). But can it generate numbers more than 20 digits?
kennytm

Any arbitrary long integer is possible as an output ? Isn't this limited by the range of randNorm ?
Optimizer

"The distribution is unbounded so in theory this can generate any integer." There is no range.
Timtech

1

Bash, 66

LANG=C sed -r '/^-?(0|[1-9][0-9]*)$/q;s/.*/5000000/;q'</dev/random

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:

LANG=C sed -r '/^-?(0|[1-9][0-9]*)$/q;s/.*/5000000/;q'</dev/urandom

1
@Optimizer It is supposed to be slow. That's because it is a real random source. But you can test it with /dev/urandom which is less random.
jimmy23013

@Optimizer How would that be taking manual input? It's reading a file, but everything's a file.
Nit

@Optimizer I simply don't understand the point you're going for.
Nit

reading from /dev/urandom in a shell script is basically the same as calling rand() in other languages. Although if you're really using bash, not POSIX sh, you can get random numbers from echo $RANDOM. wiki.ubuntu.com/DashAsBinSh gives hexdump /dev/urandom as an equivalent for bare-POSIX-minimum /bin/dash.
Peter Cordes

1

C++, 95 bytes

void f(){int d=-18,s=-1;while(s<9){d=(rand()%19+d+9)%10;cout<<d;s=9-rand()%10*min(d*d+s+1,1);}}

Expanded:

void f() {
    int d=-18,s=-1;
    while(s<9) {
        d=(rand()%19+d+9)%10;
        cout<<d;
        s=9-rand()%10*min(d*d+s+1,1);
    }
}

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)

-548856139437
7358950092214
507
912709491283845942316784
-68
-6
-87614261
0
-5139524
7

Process returned 0 (0x0)   execution time : 0.928 s
Press any key to continue.

1

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, and printf turns it into decimal format.


0

Pyth, 11 bytes

WOyG~ZtOT)Z

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:

pyth -c 'WOy"abcdefghijklm"~ZtOUT)Z'

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 to W, 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:

WOyG~ZtOUT)Z

What happened to the online compiler ?
Optimizer

@Optimizer Issues with the website, I'll work on it.
isaacg

Ah.. cool. Wanted to work on the Pyth translation of my CJam answer yesterday and found that it gives 404.
Optimizer

0

Java, 113 bytes

void g(){String a=Math.random()>0?"10":"01";for(;Math.random()>0;)a+=(int)(Math.random()*2);System.out.print(a);}

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:

void g(){
    String a=Math.random()>0?"10":"01";             //Make sure there are no trailing zeroes.
    for(;Math.random()>0;)a+=(int)(Math.random()*2);//Add digits
    System.out.print(a);                            //Print
}

Sample output: Will post when a number is done being generated.


0

Java (JDK), 140 127 bytes

()->{int i;var o=System.out;for(o.print(i=(int)(19*Math.random())-10);i!=0&Math.random()<.9;)o.print((int)(11*Math.random()));}

-13 bytes by sneaking more logic into the loop header - thanks to @ceilingcat

Try it online!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.