0までランダム化


29

チャレンジ

サンドボックスポスト

正の整数を考えると(K)出力に一様乱数整数(Y)の間を[0, K)

場合Y > 0と仮定K = Yしてまでこのプロセスを繰り返しますY = 0

ルール

  • 最初に入力を印刷する必要があります
  • 希望通りの出力形式
  • プログラムを終了する必要があります。
  • 0 最終出力である必要があります。オプションとして空行 0

提出が関数である場合、印刷に加えて0を返すことができますか?
アダム

1
@アダムはい、あなたはほかに返すことができます
ルイス・フェリペ・デ・イエスムニョス

RNGをシードする必要がありますか?
SIGSTACKFAULT

区切り文字なしで印刷できますか?
タイタス

私は興味を持ちました。このプログラムが終了するまでの平均ステップ数がH(K-1)+ 1であることを証明するのは非常に簡単です。ここで、H(K)はK 番目の調和数です。n = 1000の場合、平均で8.484ステップです。
-J.Doe

回答:


19

Pyth6 5 4バイト

.uOW

ここで試してみてください!

使い方

.uOW完全なプログラム。STDINから整数を取得し、リストをSTDOUTに出力します。
.u累積固定小数点。指定された関数に指定された初期値を適用し、
        結果が発生するまで、暗黙的に入力に割り当てられます 
        前が見つかりました。中間結果のリストを返します。
   W条件付きアプリケーション。引数(現在の値)が真実であれば、
        以下の関数を適用します。それ以外の場合は変更しません。
  O範囲[0、N)のランダムな整数。
        IOW:.uの各反復で、変数Nを現在の値に割り当て、開始します
        入力付き。Nが0でない場合、[0、N)のランダムな整数を選択します。
        Nを変更せずに返します。0に遭遇するたびに、次の反復も
        結果は0であるため、ループはそこで停止します。

1
私はPythでこれを行う方法を見ましたが、私は初心者です。尊敬。8月の月の言語か。
エルペドロ

15

C(gcc)、42バイト

f(_){printf("%d\n",_);(_=rand()%_)&&f(_);}

オンラインでお試しください!

短絡論理ANDを使用します。

f(_){                 // f(int _) {
    printf("%d\n",_); // print argument and a newline
    (_=rand()%_)      // set _ to rand()%_
    &&f(_);}          // short-circuit AND to recursively call f if _ not zero

C(gcc)、40バイト(印刷初期値なし)

f(_){printf("%d\n",_=rand()%_);_&&f(_);}

オンラインでお試しください!

短絡論理ANDを使用します。

f(_){              // f(int _) {
    printf("%d\n", // print an integer and a newline 
    _=             // The integer is _ which we set to...
    rand()%_);     // a random value modulo the input _
    _&&f(_);}      // short-circuit AND to recursively call f if _ not zero

4
rand()%_均一ではない
-njzk2

(確信がない場合は、この方法を使用して6面のサイコロを使用して[1,5]値を生成してみてください。)
njzk2

3
私はrand()がほとんど常にバイアスされていることを完全に認識しています(切り捨てによる) )。私たちが扱っている範囲の実際には、このチャレンジでの同様の提出に対して目立たないように十分にランダムに見えます。
LambdaBeta

1
これは「一様にランダムな整数を出力する」というチャレンジからのものです。厳密に言えば、これは有効ではありません
-njzk2

3
厳密に言えば、ここのすべての言語はprngを使用しています。それらのどれも真の均一な乱数を与えません(これにはエントロピーの完全なソースが必要です)。多くはこれよりも均一ですが、log(k)の繰り返しでは顕著ではありません。
ラムダベータ

10

R66 60 56 43 41バイト

function(n)while(print(n))n=sample(n,1)-1

オンラインでお試しください!


私はあなたが必要>0とは思わないし、cat(n,"")(空の文字列)も動作します。
ジュゼッペ

しかしprint、ここでは、引数を返すので、より効率的だと思います:56バイト
ジュゼッペ

また56バイト:k=scan();while(x<-sample(1:k-1,1))k=c(x,k);cat(rev(k),0)
JAD

1
中括弧を削除するのを忘れたので、さらに2バイト節約できます;)オンラインで試してみてください!
digEmAll

2
39バイト:n=scan();while(print(n))n=sample(n,1)-1
djhurio


6

Pepe、25バイト

Pepeは、ユーザーSoakuが作成したプログラミング言語です。

REeErEErReEEreeEREEeEEree 

オンラインでお試しください!

説明:

REeErEErReEEreeEREEeEEree # full program

REeE                      # input as num, in stack 1
    rEE                   # create loop in stack 2 with name 0
       rReEE              # - output and preserve the number in stack 1
            reeE          # - output a newline "\n"
                REEeEE    # - random number by 0 to input
                      ree # goto loop with name 0 if stack 1 is not equal
                            to stack 2

5

Perl 6、18バイト

{$_,(^*).pick...0}

オンラインでお試しください!

値のリストを返す匿名コードブロック。数値が範囲であることを気にしない場合は、次のことができます。

{^$_,^*.pick...0}

17バイトの場合。面白いことに、別の組み込みのランダム関数が、rollこのインスタンスで同じバイト量に対して同じ動作をします。



5

ゼリー 4  3バイト

XƬ0

これは、配列を出力して0を返す単項リンク(関数)です。

オンラインでお試しください!

使い方

XƬ0  Monadic link. Argument: n

XƬ   Pseudo-randomly pick (X) an integer k in [1, ..., n], set n = k, and repeat.
     Do this 'til (Ƭ) the results are no longer unique and return the array of
     unique results, including the initial value of n.
     This stops once X returns k with argument k. The second k will be omitted
     from the return value.
  0  Print the resulting array and set the return value to 0.

4の非常に素晴らしい取り消し線!
ngm

1
通常の4のように4を消すのは嫌です。
デニス

4

Brachylog、8バイト

ẉ?ℕ₁-₁ṙ↰

オンラインでお試しください!

説明

ẉ          Write the input followed by a linebreak
 ?ℕ₁       The input must be in [1, …, +∞)
    -₁ṙ    Generate an integer in [0, …, input - 1] uniformly at random
       ↰   Recursive call with that random integer as the new input

再帰?ℕ₁は、失敗した場合、つまり入力がの場合に停止します0



4

J、13バイト

[:}:? ::]^:a:

地下鉄では、TIOの欠如をおaびします(正確さの欠如がないことを願っています)。

値のリストを出力します。

おそらくAPLのアプローチはもっと短くなるでしょうが、これは私が考えたことです。

使い方

^:a: 収束するまで繰り返し適用し、中間結果を配列に保存します。

?範囲内のランダムな整数[0, K)のためにK 0 0より大きいが、それは、範囲内のランダムな整数を返します(0,1)。浮動小数点数の場合、エラーになります。

::] への入力のエラーをキャッチ ?代わりに、エラーの原因となった入力を出力します。

}: 配列の最後の値を取り除きます(これは、浮動小数点数が出力されないようにするためです)。

オンラインでお試しください!


それは私だけですか、コードは同じ出力を返しますか?
ルイスフェリペデイエスムニョス

@LuisfelipeDejesusMunoz私が説明できるよりもJをよく知っている人はいますが、RNGは常に同じシードから始まると思います。固定シードもありますが、?.私はそれを使用しているとは思いません。
コール

@coleあなたは正しいです。
ジョナ

4

JavaScript(ES6)、38 37バイト

@Arnauldのおかげで-1バイト

f=n=>[n,...n?f(Math.random()*n|0):[]]


math.randomを減らすことはできますか?例:codegolf.stackexchange.com/a/35648/67066
マリー

1
@Marie使用することでnew Date%n、複数の乱数を生成するのに有用であることが十分に速く変化しないため、実際に、ここでは動作しません
ハーマンL

4

C、38バイト

f(k){printf("%d ",k);k?f(rand()%k):0;}

オンラインで試す

非ゴルフ

void f(int k){
    printf("%d ",k);
    if(k)
        f(rand()%k);
}

1
三項演算子を&&;に置き換えることでバイトを保存できます。また、main関数にRNGをシードすることを検討することもできます。オンラインで試してください!
ErikF

1
また、3進数を完全に削除して、エラーで終了することもできます。34バイト
ジョーキング

4

Pyth、4バイト

W
~O

オンラインでお試しください!

これは基本的にアルゴリズムを実装します:

QinputRepeat1.tempQ2.Qunif{0,Q1}3.Print(temp)Untiltemp=0

To translate the Pyth into the algorithm, we can mostly just examine what each character means. Since Pyth is written in prefix notation (i.e. * + 1 2 3 is (1 + 2) * 3) we can start from the left and fill in the arguments as we go.

W begins a traditional while loop. The first statement after it is the loop condition and the second statement after it is the loop body. If the second statement is empty it becomes a no-op. This while works exactly like the Python while, so it will evaluate non-zero integers as True and zero as false.

The first statement after the while begins with the newline character. This corresponds to Pyth's "print and return with a newline" function. This takes one argument, which is then printed and also returned unmodified. This allows us to print the intermediate steps while also performing the needed operations.

この印刷関数に渡される引数~は、少し特別なもので始まります。直後の文字~が変数の場合、2つの引数を取り、それ以外の場合は1つの引数を取ります。以来Oない変数は、~引数を1つしか消費します。~関数+=は、多くの従来の言語でやや似ていますが、最も近い演算子はからのポストインクリメント演算子++ですC。あなたはそれx++x現在の値として使用するようなものになることを知っているかもしれませんが、その後xはなりますx+1~は同じ考えですが、最初の引数の結果が何であれ一般化されます。どの変数に割り当てるかをどのように選択するかについては、後で説明します。

引数~IS O非常に簡単です。1つの引数が整数の場合O returns a value from 0 to one less than that integer uniformly at random.

これでO、引数がないことに気づいたかもしれません。ここでは、Pythインタープリターが推測を親切に記入しますQ。これは変数です。QPythには特別な意味があります。プログラム内に存在する場合、PythプログラムはプログラムQの入力への割り当てから始まります。これは~の引数で発生する最初の変数なので、値を割り当てるQ変数にも~なりました。

「読み取り可能な」プログラムを要約すると、次のようになります。

while print_and_return( assign_variable( Q, unif(0, Q-1) ) ):
    pass

そして、1つのサンプル「ランスルー」は次のようになります。

  1. Q = 5
  2. O3を~返し、5を返します\n returns and prints 5 which is true
  3. Q = 3
  4. O0を~返し、3を\n返し、trueを返し、3を出力します
  5. Q = 0
  6. O無関係なものを~返し、0を\n返し、0を返し、falseを出力します
  7. Q = something irrelevant
  8. Terminate

3

APL (Dyalog Unicode), 12 9 bytes

Anonymous tacit prefix function. Assumes ⎕IO (Index Origin) to be 0, which is default on many systems. Returns the final value (0) in addition to printing while run.

{⌊?⎕←⍵}⍣=

Try it online!

{}⍣= apply the following function until stable:

⎕←⍵ output the argument

? return a uniformly distributed random number in the range 0 through that–1

 round down (because ?0 gives a (0,1) float)


3

C (gcc), 40 42 bytes

Some idiot™ forgot to print the initial value first.

f(K){while(K)printf("%d\n",K,K=rand()%K);}

Don't panic.


You tied me, the question also requires that you print the initial K. Without it I also got 40. You can also get the 42 fully compliant version in a similar way: f(K){while(K)printf("%d\n",K),K=rand()%K;}. Still you got my +1 for an equal solution!
LambdaBeta

Even better: f(K){while(K)printf("%d\n",K,K=rand()%K);}
SIGSTACKFAULT

3

x86 + rdrand, 19 bytes

Straightforward implementation. Takes input K in ecx and outputs to a buffer in ebx.

0000000a <start>:
   a:   0f c7 f0                rdrand %eax
   d:   31 d2                   xor    %edx,%edx
   f:   f7 f1                   div    %ecx
  11:   89 13                   mov    %edx,(%ebx)
  13:   83 c3 04                add    $0x4,%ebx
  16:   89 d1                   mov    %edx,%ecx
  18:   85 c9                   test   %ecx,%ecx
  1a:   75 ee                   jne    a <start>
  1c:   c3                      ret  

3

Python 3, 39 bytes

f=lambda k:print(k)or f(hash('.'*k)%k)

Probably not the most cryptographically secure random number generator but to the human eye it looks random enough...

Try it online!


Notes: 1) the entry gives (usually) different results every time it's run in a new interpreter but may give the same result if run within the same python session. 2) I assume that terminating through an error without explicitly checking for k=0 is acceptable.
Luca Citi

Sorry, but functions must be reusable arbitrarily often in the same environment. Terminating in an error is acceptable though
Jo King

The task requires a uniform random number from the given range. hash() tries to maintain but doesn't guarantee this property. For that task you should use the random module.
David Foerster

With only 57 bytes you can amend your solution to use uniformly random numbers from random.randrange(): from random import*;f=lambda k:print(k)or f(randrange(k))
David Foerster

3

TI-Basic (TI-84 Plus CE), 17 13 bytes

While Ans
Disp Ans
int(randAns
End
Ans

-4 bytes from Misha Lavrov

Takes input in Ans as 50:prgmNAME.

TI-Basic is a tokenized language. All tokens used here are one byte.

Explanation:

While Ans    # 3 bytes, While the number we hold is not zero:
Disp Ans     # 3 bytes,   Display it on its own line
int(randAns  # 4 bytes,   and replace it with a number randomly
                        # chosen from 0 to one less than it (inclusive)
End          # 2 bytes, end While loop
Ans          # 1 byte,  Display (and return) zero

An 11-byte solution suggested by Misha Lavrov that requires pressing enter after each line following the first.

Ans
While Ans
Pause int(randAns
End

1
int(Ansrand is shorter. Also, using Pause instead of Disp, you can make the only statement in the loop be Pause int(Ansrand, which also updates Ans.
Misha Lavrov

3

Python 2, 64 62 60 bytes

from random import*
k=input()
while k:print k;k=randrange(k)

Try it online!


Saved

  • -2 bytes, thanks to Jonathan Allan

"Input must be printed at first"... while 1:print k;k=randint(0,~-k) should work (with an error at the end)
Jonathan Allan

...and then while 1:print k;k=randrange(k) saves two.
Jonathan Allan

1
@JonathanAllan Thanks :), The questions says I can use an empty line instead of 0, so no error.
TFeld

3

C++ (gcc), 98 bytes

#import<cstdio>
#import<cstdlib>
#define d printf("%i ",x 
int p(int x){d);while(x>0)d=rand()%x);}

Try it here!

Usage

int main() {
    p(100);
}

This is my first code golf attempt. Any feedback or remarks are welcome.

Edit: Removed the main function as suggested to make it valid.


1
Hi, and welcome to PPCG :) You do not need to include the sample call in your byte count (i.e. you don't need to write the main function) since we accept functions as valid submissions. Otherwise, your submission is technically not valid since if the input was some two or more digit number the output could be ambiguous. If you just add a space at the end of the format string in your macro you should be fine. Happy golfing!
FryAmTheEggman

Adding the compiler flag -Dd='printf("%i,",x' instead of the #define would save you some bytes (-4), and is allowed as long as you count the bytes towards your result (because it is a non-standard preprocessor directive. You can also leave out the imports (at least with -std=c++98 and -w, which don't count for bytes), and the variable types. So, you'd have p(x){d);while(x>0)d=rand()%x;} and -Dd='printf("%i,",x'.

Also, you should probably check out the Standard Loopholes and Tips for golfing in C, if you haven't already :)

3

><>, 92+2 Bytes

:nao:0=?;0_1>:{:}(?\\
}(?!\$2*1>x~\$+1$*2/\~00:{{:@}
8+1.\~:{:}\+>$1+f
~~@~~47*0.\(a2*1@@?!.

+2B for -v flag

Try it online!

><>'s only source of randomness comes from the 'x' instruction, which sets the instruction pointer's direction to a random value. As such, generating a random number from 0 to n isn't trivial.

I first calculate how many bits are required to represent a number in the range [0,n), then generate random bits to generate a random number. This leaves the possibility that it'll generate a number slightly larger than n, in which case we just discard it and try again.

Explanation:

:nao                              Print the current number followed by a newline
    :0=?;                         If the current n is 0, terminate

Calculate how many random bits we need to be generating:
         0 1                      Initialise the variables for this loop: 
                                      numberOfBits = 0, maxValue = 1
             :{:}(?\              If maxValue >= n, break out of the loop
                 *2               maxValue *= 2
             $+1$                 numberOfBits += 1

Generate the random number:
                     ~            Delete maxValue
                      00          Initialise randomNumber = 0, i = 0
}(?!\                   :{{:@}    If i >= numberOfBits, break out of the (inner) loop
     $2*                          randomNumber *= 2
          _
        1>x~\                     The random bit: If the IP goes up or 
          \+>                     left, it'll be redirected back onto the 'x', 
                                  if it goes down, it adds one to randomNumber
                                  If it goes right, it does nothing to randomNumber

             $1+                  increment i
8+1.            f                 Jump back to the start of the inner loop

After we've generated our number, check that it's actually below n
     ~                            Delete i
      :{:} (      ?               Test that the number is less than n
            a2*1    .             If it's not, jump back to the start 
                                  of the number generation section
  @~~                             Otherwise delete the old value of n, and numberOfBits
     47*0.                        Then jump back to the start of the program

Very nice! I came up with the same idea independently; without whitespace, my solution uses several characters fewer than yours, but you've managed to make a much more compact block of code.
Théophile

2
The current meta consensus is that you don't have to count the bytes used on flags
Jo King

3

MATLAB (49 46 bytes)

@(k)eval('while k;disp(k);k=randi(k)-1;end;0')

Sample output:

>> @(k)eval('while k;disp(k);k=randi(k)-1;end;0')
ans(5)

ans = 

    @(k)eval('while k;disp(k);k=randi(k)-1;end;0')

     5    
     3    
     2    
     1   

ans =    
     0

1
I suppose you can do k=randi(k)-1 for a few bytes less.
Sanchises

2

Retina, 21 bytes

.+
*
L$`.
$.`
+¶<)G?`

Try it online! Explanation:

+

Repeat until the value stops changing (i.e. 0).

¶<)

Print the value before each pass through the loop.

.+
*

Convert to unary.

L$`.
$.`

Create the range and convert to decimal.

G?`

Pick a random element.


2

Pyth, 6 7 bytes

QWQ=OQQ

Try it online!

+1 to print the initial input value.

While Q is truthy, set Q to be a random integer between 0 and Q and print Q.

Not the shortest Pyth answer but I'm just learning and only posting because of the recent discussion about no-one using Pyth any more :)


2
I managed to tie using cumulative reduce but keeping it as a procedural program. Thanks for the motivation to work on a golf :)
FryAmTheEggman

That's cool. Still trying to work out how (why) it works.
ElPedro

By default, both = and ~ use the first variable of an expression as the variable that will be assigned if one isn't specified. For example ~hT will set T to 11 while returning 10. The only other fancy trick is that the newline character prints its input and then returns that value unmodified, so we can have an empty loop body. Let me know if something else is confusing :)
FryAmTheEggman

1
@FryAmTheEggman That's beautiful.
isaacg

1
@isaacg Thanks! I originally meant for it to just be edited in here, but I decided to write something up since I wanted to try MathJax. These kinds of Pyth answers were always my favourite since they feel both intentional but also abusive :)
FryAmTheEggman


2

IBM/Lotus Notes Formula, 48 bytes

o:=i;@While(i>0;i:=@Integer(i*@Random);o:=o:i);o

Field formula that takes input from another field i.

There's no TIO for formula so here's a screenshot of a sample output:

enter image description here



2

PowerShell, 35 bytes

for($a="$args";$a;$a=Random $a){$a}

Try it online!

Full program. Takes input $args, stores it into $a, and enters a for loop. Each iteration we're checking whether $a is still positive (as 0 is falsey in PowerShell). Then we leave $a on the pipeline and move to the next iteration, where we set $a to be the result of Get-Random $a, which returns an integer in the range 0..($a-1).

(Ab)uses the fact that PowerShell outputs an additional trailing newline in lieu of outputting the final zero (allowed by the rules as currently written).


"$args" - nice. I was stuck on $args[0] in this case
mazzy

2

Lua, 58 bytes

p,r=print,...+0 p(r)while r>0 do r=math.random(0,r)p(r)end

Try it online!

For some more Lua love here :)


Hey, you can remove the +0 on the r declaration and move it to the r on the while statement, by doing so you'll use 1 less byte for the space (p,r=print,...p(r)while).
Visckmart
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.