1 / N的概率


29

因为没有足够的简单挑战,所以:

创建一个可选的未命名程序或函数,给定(通过任何方式)整数1≤N≤10000,以伪随机概率1 / N输出您语言的True值,否则为False。

请注意,命名要求已被删除。随意编辑答案和分数。

某些语言的True和False使用1(或-1)和0,也可以。

例:

输入测试示例:

4 -> True
4 -> False
4 -> False
4 -> False
4 -> False
4 -> True
4 -> False
4 -> False

即给出4;它会以25%的机会返回True,并以75%的机会返回False。




由于并非所有语言都内置了“伪随机性”,是否有可能获得种子作为第二个论点?(例如Brainfuck)
瑕疵的

@flawr使用当前毫秒...
亚当

1
N我们必须接受的最大金额是多少?
Toby Speight

Answers:


27

具有ParserFunctions的 MediaWiki模板,48字节

{{#ifexpr:1>{{#time:U}} mod {{{n}}}|true|false}}

13
语言:-)有趣的选择
亚当

6
Who the heck thought it would be sensible to add non-deterministic functions to MediaWiki templates!?
user253751

4
@immibis: well the non-determinism occurs from #time, probably to update the age of living people, etc.
Willem Van Onsem

15

Pyth, 3 bytes

!OQ

Try it online

Simple inversion of random choice from 0 to input

Amusingly in Pyth it is not possible to make a function that does this without $ because Pyth functions are automatically memoized.



@LeakyNun Ah right, I had forgotten about using the time for a random function, that's rather clever.
FryAmTheEggman

No, I just used time to de-memoize it.
Leaky Nun

1
I'm aware, I guess I just didn't word it well :P That said I don't think it would really work as a workaround for most submissions, if it were ever better than a full program for some reason. Taking the time as an argument probably isn't just allowed by default.
FryAmTheEggman

1
@LeakyNun I believe this question predates the Q filling in at the end, as otherwise I would have answered !O ;)
FryAmTheEggman

12

CJam, 5 bytes

Gotta be quick with these ones...

rimr!

Test it here.

Explanation

ri e# Read input and convert to integer N.
mr e# Get a uniformly random value in [0 1 ... N-1].
!  e# Logical NOT, turns 0 into 1 and everything else into 0.

11
"Gotta be quick with these ones..." which is a reason to disagree with OP that "there are not enough simple code-golf challenges". If FGITW is an issue, IMO it's too simple.
Peter Taylor

12

TI-BASIC, 4 bytes using one byte tokens

not(int(Ansrand

Determines if the integer part of the input times a random number in [0,1) is zero. Ansrand<1 also works.


How... Is that four bytes?
John Dvorak

3
@JanDvorak The first bytes is not(, the next is int(, the next is Ans, the next is rand. In general, graphing calculators do not use ASCII as their internal representation for programs.
user253751

@immibis In general, computers don't use ASCII either. This might be questionable, is there a meta discussion about that?
Kroltan

7
@Kroltan Yes; this is the meta discussion, and this is the list of tokens that are one byte, which includes all four that I used.
lirtosiast

@ThomasKwa thanks!
Kroltan

11

MATL, 5 bytes

Three different versions of this one, all length 5.

iYr1=

which takes an input (i), generates a random integer between 1 and that number (Yr), and sees if it it is equal to 1 (1=). Alternatively,

li/r>

make a 1 (l, a workaround because there is a bug with doing 1i at the moment), take an input (i), divide to get 1/N (/), make a random number between 0 and 1 (r), and see if the random number is smaller than 1/N. Or,

ir*1<

take and input (i), and multiply by a random number between 0 and 1 (r*), and see if the result is smaller than 1 (1<).

In Matlab, not MATL, you can do this anonymous function

@(n)n*rand<1

for 12 bytes, which is used by doing ans(5), for example.


10

JavaScript ES6, 15 bytes

-5 bytes thanks to Downgoat.

x=>1>new Date%x

Based off (uses) of this answer's technique.


1
new Date can also work and might save a few bytes
Downgoat

@Downgoat Ah, right, Date randomness!
Conor O'Brien

10

Julia, 17 16 15 bytes

n->2>rand(1:n)

This is a function that generates a random integer between 1 and n and tests whether it's less than 2. There will be a 1/n chance of this happening, and thus a 1/n chance of returning true.

Saved 1 byte thanks to Thomas Kwa!


9

Microscript II, 3 bytes

NR!

Reads an integer n, generates a random integer between 0 and n-1 (inclusive), then applies a boolean negation to that value.


8

Candy, 2 bytes

Hn

H stands for Heisen-double

n stands for not

The 'n' is passed with the -i flag as numeric input. Values left on the stack are printed on exit.

"Long" form:

rand   # number between 0 and pop()
not    # cast to int, invert non-zero to zero, and zero to one

I think you'd need to count -i as one byte.
lirtosiast

1
basically the only way to pass numeric input is with the -i flag. I guess only languages that read from stdin suffer no input specification penalty?
Dale Johnson

Well, if there were a generic input flag, or you just used regular CLAs to pass arguments, that would definitely be fine. It seems unfair that the datatype is being specified for free, though.
lirtosiast

2
@ThomasKwa Should a function written in a dynamic language have to count the bytes to specify that the argument is an integer in the documentation? In lambda x: random.random()<1/x (ungolfed) it's also "specified for free" that the argument is a number.
user253751

@immibis Hmm, that's a good point. I guess trying to keep the rules for programs and functions the same should allow this, then. I'll make a post on meta.
lirtosiast

7

Seriously, 3 bytes

,JY

0 is falsey and 1 is truthy. Try it online

Explanation:

,JY
,    get input
 J   push a random integer in range(0, input) ([0, ..., input-1])
  Y  logical not: push 0 if truthy else 1  

7

R, 30 22 bytes

code

cat(runif(1)<1/scan())          #new
f=function(N)cat(runif(1)<1/N)  #old

It generates a number from a uniform distribution (0 to 1) and should evaluate to true 1/n of the times.


6

Japt, 6 bytes

1>U*Mr

Try it online!

Mr is equivalent to JS's Math.random. The rest is pretty obvious. I could probably add a number function that generates a random float between 0 and the number. When this happens, two bytes will be saved:

1>Ur    // Doesn't currently work

Alternate version:

1>Ð %U

Ð is equivalent to new Date(, and the Date object, when asked to convert to a number, becomes the current timestamp in milliseconds. Thus, this is entirely random, unless it is run multiple times per ms.


6

Marbelous, 21 bytes

}0    # takes one input n
--    # decrements n
??    # random value from range 0..n (inclusive)
=0?0  # push right if not equal to 0, fall through otherwise | convert to zero
++    # increment | no-op
{0//  # output | push left

I've taken 0 to be falsey and 1 to be truthy, though there is no real reason for that seeing as Marbelous doesn't really have an if. More Marbelousy would be output to {0 for true and {> for false. This would look like this:

}0
--
??
=0{>
{0

But I'm not sure that's valid.


I'd be up for a meta discussion on this. Short version of my view: outputting a value to a different output is equivalent to having different output tuples in another language. If (nil,1) and (1,nil) can be your truthy and falsey values in another language, then {0 vs {> should be allowed in Marbelous. PS: your {> version won't exit because you never fill the other output.
Sparr

@Sparr it will exit due to inactivity, no?
overactor

You're right. I feel dumb.
Sparr

6

APL, 6 3 bytes

+=?

This is a function train that takes an integer and returns 1 or 0 (APL's true/false). We generate a random integer from 1 to the input using ?, then check whether the input is equal to that integer. That results in a 1/input chance of true.

Saved 3 bytes thanks to Thomas Kwa!


@ThomasKwa I thought about some kind of train, but does that really count as a "named function" if assigned? I guess the "named" part is throwing me here since it's atypical.
Alex A.

@ThomasKwa Assignment of trains (and derived functions) is completely parallel to all other assignments.
Adám

@NBZ what do you mean by parallel?
lirtosiast

@ThomasKwa Equivalent; behaving like any other function assignment.
Adám

I would use instead of '+' because + means Conjugate for complex numbers. Of course it doesn't matter here, and + is the traditional identity (no-op) function, but now we have (same). Other no-ops for scalars are: (materialize), (pick), (enclose), (split), (mix), (unique), (enlist), , (ravel), (table), (reverse), (reverse first), and (transpose). Some change the scalar into a vector or matrix.
Adám

6

PlatyPar, 3 bytes

#?!

#? gets a random number [0,n) where n is input. ! returns true if the number before it is 0, else it returns false.

Using more recent features that were implemented (but unfortunately for me not committed) before this question was asked I can get it down to 2 with ~! Try it online!


5

Java, 43 bytes

boolean b(int a){return a*Math.random()<1;}

1
a->a*Math.random()<1 is shorter.
TheNumberOne

Should specify "Java 7 or earlier".
corsiKa

@corsiKlauseHoHoHo This works in Java 8 as well though
SuperJedi224

1
Of course it does - but it's not golfed for Java 8, which would use lambdas to save space. By that logic, all Java answers are also Groovy answers, but Groovy is always the same or smaller because it has shortcuts that Java doesn't.
corsiKa

5

C, 24 bytes

f(n){return!(rand()%n);}

I've rolled back OP's edit removing the first 4 characters. It's nice to have bytes reduced, but to me, having the returnwithout the f(n) doesn't make any sense syntactically.
Level River St

1
@insertusernamehere rand()%n is a standard way of getting a random number in the range 0..n-1. You are correct, it does rely on n being much smaller than RAND_MAX but there is no upper limit for n mentioned in the question. An alternative approach would be to do a reject and re-roll on all numbers from n to RAND_MAX but it would be hopelessly inefficient at small n.
Level River St

5

><>, 27 + 3 for -v = 30 bytes

Here is a not-uniform-at-all solution where I mod N the sum of 15876 random picks of 0 or 1 :

0"~":*>:?vr%0=n;
1-$1+$^-1x

N must be input on the stack with -v flag, output is 0 for falsey and 1 for truthy.

A much smarter and uniform solution that work for 1/2^N instead :

4{:?!v1-}:">"$2p:"x"$3p:"^"$4p1+:">"$3p1+!
   ^1<
0n;
1n;>
 

For an input 3 you've got 1/8 chances of getting 1 and 7/8 of getting 0.

Explanation :

I append as much x as needed on the 4th line and surround them with directions so there is only two ways out of the x: either the falsey output or the next x. If all x go in the right direction, the last one will route to the truthy output.

For example for N=5, the final codespace is the following :

4{:?!v1-}:">"$2p:"x"$3p:"^"$4p1+:">"$3p1+!
   ^1<
0n; > > > > >
1n;>x>x>x>x>x>
    ^ ^ ^ ^ ^

While it's true you can't get a perfect distribution for arbitrary N, neither can anyone else using a PRNG. You could loop through an x a few times to get a bunch of random bits, assemble them into an int I, then use I%N as your random value.
Sparr

@Sparr edited my answer but I feel like using a big number of iteration will 'average out' the resulting integer, making the output heavily tend toward (iterNum/2)%N. I don't think using a lower number would be a solution either. Did I maybe not quite understood you, or would you have any further idea to better the solution?
Aaron

instead of adding 15000 bits together, produce just 32 bits and concatenate them, giving you a uniformly distributed 32-bit random integer. mod that.
Sparr

@Sparr that seems better indeed, even if I've no idea why ;) That'll cost much more bytes (><> sucks for byte operations & base conversion) but I'll change my answer this evening (CEST).
Aaron

you can concatenate bits by multiplying by two and adding: r=0; for(0..32) r=r*2+randbit;
Sparr

4

Mathematica, 18 16 bytes

#RandomReal[]<1&

Basic solution. The unnamed Function creates a random number in [0, 1), multiplies it by its argument, and checks if it is still less than 1.


4

Python, 42 bytes

import random
lambda n:1>random.random()*n

Edit: Removed the time.time() answer because of the distribution.


2
For random, it's worth doing from random import* to save on random.. Not for time though.
xnor

1
Random numbers generated by modulo division are not uniformly distributed.
Trang Oul

@TrangOul That's a good point; for larger n the effect could be noticeable. I think 1>time.time()%1*n could work.
lirtosiast

@TrangOul I presume you know the difference between rand in C, and time.time in Python... One obvious feature of the latter is that it returns the current time, which is unbounded, so that time.time()%n has a uniform distribution (over long enough periods of time) for any n.
user253751

4

TeaScript, 3 bytes

!N×

Try it here.

Explanation

 N  maps to Math.rand which is a utility function that returns an integer
    between `arg1` and `arg2` or `0` and `arg1` if only one argument is
    provided.
  × is expanded to `(x)`, where `x` is initialised with the value provided
    in the input boxes; × represents byte '\xd7'
!   negate the result, 0 results in true, anything else false

1
How does seven chars add up to 6 bytes? And is the (R) a (single byte) ANSI char?
Adám

@NBZ, haha! I think I lied... I blame hangover... I'll update now as I'm going to change the mechanism to a more straightforward one that I've just noticed! In this current version the ® represents the char '\xae' so is just one byte. :)
Dom Hastings

4

Fuzzy Octo Guacamole, 10 bytes

^-!_[0]1.|

Explanation:

^-!_[0]1.|

^          # Get input.
 -         # Decrement, so we can append <ToS> zeros and a 1 to the stack.
  !        # Set loop counter.
   _       # Pop, since we are done with the input.
    [      # Start loop
     0     # Push 0
      ]    # End for loop. We have pushed input-1 0s to the stack.
       1   # Push a single 1 to the stack.
        .  # Switch stacks
         | # Pick a random item from the inactive stack, which has n-1 falsy items and 1 truthy item, so the truthy probability is 1/n.
           # (implicit output)

3

Perl 6,  10  8 bytes

!(^*).pick
#  ^- The * is the argument

This code creates a Range from 0 up-to but excluding the input *. It then picks one at random and the ! returns True when it receives a 0.

1>*.rand
# ^- The * is the argument

This takes the input * and multiplies it by a random Num from 0..^1 then returns True if it was smaller than 1.

# store it in a lexical code variable for ease of use
my &code = 1>*.rand;

die "never dies here" unless code 1;

for ^8 { say code 4 }
False
True
False
False
False
True
False
False

3

Prolog (SWI), 24 bytes

Code:

p(N):-X is 1/N,maybe(X).

maybe(+P) is a function which succeeds with probability P and fails with probability 1-P

Example:

p(4).
false

p(4).
false

p(4).
true

3

PowerShell, 25 Bytes

!(Random -ma($args[0]--))

The Get-Random function when given a -Maximum parameter n returns a value from the range [0,n). We leverage that by subtracting 1 from our input $args[0], so we're properly zero-indexed, and get a random value. Precisely 1/nth of the time, this value will be 0, so when we Boolean-not it with ! it will return True. The other times will return False.


3

J, 3 bytes

0=?

This is a monadic fork that takes an argument on the right. Similarly to APL, ? generates a random integer; however, J arrays are zero-based. So we compare to 0 instead of to the input.


3

Minkolang 0.14, 7 bytes

1nH1=N.

Try it here.

Explanation

1          Pushes 1
 n         Takes number from input
  H        Pops b,a and pushes a random integer between a and b, inclusive
   1=      1 if equal to 1, 0 otherwise
     N.    Output as number and stop.

3

PHP, 22 bytes

<?=2>rand(1,$argv[1]);

Reads n from command line, like:

$ php probability.php 4

Outputs (false is cast to an empty string in PHP) or 1 (in case of true).


3

C#, 56 45 bytes

Thanks to, pinkfloydx33 it's 45 now.

bool b(int n){return new Random().Next(n)<1;}

Old 56 bytes

Generates random positive integer bigger or equal to 0 and smaller than n and checks if it's smaller than 1 and return comparison result.

bool a(int n){Random r=new Random();return r.Next(n)<1;}

1
Welcome to PPCG! Unfortunately, this submission doesn't work, because Random.Next(k) returns an integer k such that 0 <= k < n. By changing the condition to <1, it will be correct. In addition, the use of a lambda expression may get your code shorter.
Mego

@Mego Sure, thank you for comment. I made it 0 < k <= n and it should be like you said. I'll correct it immediately.
ivaan

2
Use var r saves three. Or if c#6, bool a(int n) => new Random().Next(n)<1; for 41. Though not sure if initializing a new Random per method call will work properly as far as distribution?
pinkfloydx33

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.