これは最終的に停止します…


41

入力文字列を指定すると、次のようSにprintのS後に空でない区切り文字が続きます。

  • ステップ1:S持って1/2印刷されているの機会、および1/2終了するプログラムのためのチャンスを。

  • ステップ2:S持って2/3印刷されているの機会、および1/3終了するプログラムのためのチャンスを。

  • ステップ3:S持って3/4印刷されているの機会、および1/4終了するプログラムのためのチャンスを。

  • ステップはnS持ってn/(n+1)印刷されているの機会、および1/(n+1)終了するプログラムのためのチャンスを。

ノート

  • 入力文字列は、言語の文字列タイプで受け入れられる文字のみで構成されます。

  • 常に同じである限り、空でないセパレータを使用できます。Sプログラムが終了する前の最後の印刷の後にセパレーターが印刷されることが期待されます。

  • プログラムは、1/2何かを印刷する前に終了する可能性があります。

  • 末尾の改行は許容されます。

  • あなたの答えは、記述された確率を尊重する真の試みをしなければなりません。明らかに、n大きい場合、これはますます真実になります。回答で確率がどのように計算されるのか(および、それらが仕様を尊重し、疑似乱数性と大きな数の問題を無視する理由)の適切な説明で十分です。

得点

これはであるため、バイト単位の最短回答が優先されます。


区切り文字を空の文字列にすることはできますか?
rturnbull

16
@rturnbullいえいえ、その場合はセパレータがないからです。
致命的

これらを順番に印刷する必要がありますか、それともプログラムが終了したときにすべてを印刷するだけですか?
デニス

@Dennis次々。
致命的

回答:


18

Pyth、7バイト

WOh=hZQ

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

使い方

擬似コード:

while rand_int_below(1 + (Z += 1)):
    print(input)

Pythが再び05AB1Eを破りましたね。
エリックアウトゴルファー

印刷ステートメントは、終了確率とともにそれ自身の確率を必要としませんか?
-tuskiomi

1
@tuskiomi Nah、n /(n + 1)はちょうど1-1 /(n + 1)、または1-(終了の確率)です。
アドラス

29

C#、94 85バイト

私の最初の答え!

using System;s=>{var r=new Random();for(var i=2;r.Next(i++)>0;)Console.Write(s+" ");}

以前の試み(私はそれが好きだったgoto):

using System;s=>{var i=2;var r=new Random();a:if(r.Next(i++)>0){Console.Write(s+" ");goto a;}}

ゴルフをしていない:

using System;
class P
{
    static void Main()
    {
        Action<string> f = s =>
        {
            var r = new Random();
            for (var i = 2; r.Next(i++) > 0;) Console.Write(s + " ");
        };

        f("test");

        Console.ReadKey();
    }
}

注:C#では、Random.Next(N)メソッドは[0、N-1]の範囲の負でない整数を返すため、返される数値が0より大きいことを確認できます。


1
using System;バイトカウントに含める必要があります。rインラインで宣言できますnew Random().Next(i++)。変数に設定する必要はありません。ゴルフ機能の末尾にセミコロンは必要ありません。
TheLethalCoder

1
ああ、素敵な最初の答え!私の試みよりも短かったでしょう:)
TheLethalCoder

@TheLethalCoderご意見ありがとうございます!使用しようとしましたnew Random().Next(i++)が、それを実行しようとすると、結果は常にプログラムが何も印刷せずに停止するか、プログラムが停止しないかのいずれかでした。変数を宣言r=new Random()して使用するとr、OPの要求に従ってプログラムがよりランダムに停止します。
チャーリー

ループが非常にタイトだからです。
TheLethalCoder

2
@TheLethalCoder-はい、8回目のループはジェネレーターのシードが同じになる可能性を意味します。参照:msdn.microsoft.com/en-us/library/system.random.aspx#Instantiate
Erno

12

R、47 46 43バイト

コメントのロビンライダーによる43バイト。

s=scan(,"")
while(sample(T<-T+1)-1)print(s)

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

説明

s=scan(,"")  # Takes input from stdin.
             T<-T+1    # T is 1 by default, so this
                       # evaluates to 2, and will increment
                       # at each step.
      sample(T<-T+1)   # Take a sample of size 2, i.e. generate
                       # a list of integers from 1 to 2 in random order
      sample(T<-T+1)-1 # Subtract one from every element of this list.
while(sample(T<-T+1)-1)# while() will treat the first value in this list
                       # as a logical value, i.e. FALSE for zero and TRUE
                       # for nonzero values. The other elements of the list
                       # are ignored, triggering a warning.
                       print(s) # print s

これは終了しますか?
mfloren

@mflorenはい、ここでの他のすべての回答と同様に、確率論的であり、進行するにつれて終了の可能性は減少しますが、最終的には終了します。何も印刷されない可能性が0.5あります!数回実行してみて、出力を比較してください。
rturnbull

function(s)より短いs=scan(,'');
JAD

1
そしてpryr::f(while(runif(1)<T/(T<-T+1))print(s))さらに短いです。
JAD

1
@JarkoDubbeldamは、残念ながら、あなたは(AB)使用することはできませんTし、Fそれが機能を一度だけ呼び出すことができるというグローバル変数や手段を変更して、匿名の機能を持ちます。ここを参照してください:「ソリューション関数は、以前に呼び出された回数に関係なく一貫して実行されます」。
-rturnbull

11

05AB1E、8バイト

[NÌL.R#,

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

説明

[         # start loop
 NÌL      # push range [1 ... current_iteration+2]
    .R    # pick a random number
      #   # if true (1), exit loop
       ,  # print input

@Fatalize:それは私のためです。数回実行してみてください。何も出力しない可能性が50%あるため、「不運」だったかもしれません。
エミグナ

11
ランダムタスクの継承の問題。時にはすべてのオッズがあなたに反することがあります。
J_F_B_M

@J_F_B_M固有?
リーキー修道女

1
@LeakyNunいいえ、それは「継承問題」です(イベントの確率は以前のイベントから継承されません)。J_F_B_Mは明らかに、ギャンブラーの誤acyを指していました。
aebabis

11

Javascript、60 58 54バイト

f=(s,n=1)=>Math.random()<n/++n?console.log(s)+f(s,n):0

文字列を出力しますs。プログラムが終了した場合に出力されるセパレータはNaNまたは0です。

f=(s,n=1)=>Math.random()<n/++n?console.log(s)+f(s,n):0

f('test')

Math.random()その値が下にある場合に0と1の間の値を返しn/(n+1)、次いでspritnedされるであろう。

@Neilのおかげで4バイト節約


1
なぜ使用しないのn/++nですか?
ニール

1
@Neilありがとう、4バイト節約しました!
トーマスW

2
ご使用の環境がブラウザだった場合は、使用できるalertの代わりにconsole.log6つのバイトを保存するために-スニペットを設定することができalert = console.log、必要に応じて非目障りな出力を表示します(許可されている場合-バイトは保存されません、ただ1人の正気を保つことができます)
クレイグ・アイレ

10

Java 8、72 62 61バイト

s->{for(int n=2;Math.random()<1f/n++;System.out.println(s));}

@cliffrootのおかげで-10バイト。@JollyJokerの
おかげで-1バイト。

区切り文字は改行です。

説明:

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

s->{                          // Method with String parameter and no return-type
  for(                        //  Loop
    int n=2;                  //   Start `n` on 2
    Math.random()<1f/n++;     //   Continue loop as long as a random decimal (0.0-1.0)
                              //   is smaller than 1/`n` (and increase `n` by 1 afterwards)
    System.out.println(s)     //   Print the input-String
  );                          //  End of loop
}                             // End of method

2
現時点ではチェックできませんが、条件ブロックif内にfor条件を入れないのはなぜですか?
クリフルート

@cliffrootそれはあるforループ。
Okx

1
@Okx私は、forループが明示的に必要ないように、ループが終了する条件を意味しましたreturn。forステートメント内の2番目の式。
クリフルート

@cliffrootああ、わかりました。
Okx

1
int n=21f/n++動作しますか?
ジョリージョーカー

9

Mathematica、43バイト

(n=1;While[RandomInteger@n>0,Print@#;n++])&

JungHwan Minは1バイトを節約し(上記)、より良いものを提案しました(下)

Mathematica、37バイト

For[n=1,RandomInteger@n++>0,Print@#]&

1
RandomInteger@n!=0RandomInteger@n<1この場合と同じで、とn++マージできますRandomInteger@n。また、For(ほとんど常に)よりも短くなっているWhile:-5バイトFor[n=1,RandomInteger@n++>0,Print@#]&
JungHwan分

「のために」勝ちます!私もあなたの答えを投稿
-J42161217

For[n=1,!n∣Hash[# n++],Print@#]&ハッシュがかなりランダムであると仮定すると、34バイトでも機能します。ただし、ランダム性は入力に依存します。例えば試す% /@ Alphabet[]
ケリーLowder

8

Clojure、61 56バイト

そもそもなぜ一緒に行かないのfor?しかし、実際には、怠に評価さdoseqれるように、つまらないものを使用する必要がありますfor

#(doseq[n(range):while(>(rand-int(+ n 2))0)](println %))

元の:

#(loop[n 2](if(>(rand-int n)0)(do(println %)(recur(inc n)))))

(>(+(rand-int n)2)0)常に真実ではありませんか?
クリフルート

良いキャッチ、私はインクリメントするつもりでしたn
ニコニール

8

> <>124 112バイト

i:0( ?v
 &5a ~/
&p0[^ >"\_\^x0!>"0&1+:&p1&:&p2&:&p3&:&p4&:&p0&1+:&p3&:&p4&:
=?v[/!}l]:?!;1
{:   ?^  >
:o>_ {:?!^

オンラインでお試しください!(また、魚の遊び場で見ることもできますが、いくつかのバグのため、4行目に}後を追加し、l適切に機能させるためにコードの後に​​改行を追加する必要があります。)

ランダム性は、> <>では扱いにくいです。唯一のランダムな命令はでx、4つの選択肢(左、右、上、下)から魚の方向をランダムに選択するため、それを確率1 / nで何かに変えるのは簡単ではありません。

このコードの方法は、> <>の自己変更機能を使用して、コードの下にランダム性の塔を構築することです。したがって、たとえば、第4段階では、コードは次のようになります。

i:0( ?v
 &5a ~/
&p0[^ >"\_\^x0!>"0&1+:&p1&:&p2&:&p3&:&p4&:&p0&1+:&p3&:&p4&:
=?v[/!}l]:?!;1
{:   ?^  >
:o>_ {:?!^
>!0x^
\  _\
>!0x^
\  _\
>!0x^
\  _\
>!0x^
\  _\

魚は塔の底から始まります。塔の各レベルで、x2つの鏡の間に閉じ込められているため、魚は左または右にしか逃げられません。これらの方向のいずれかは、魚をタワーの次のレベルに送りますが、左に行くと0スタックにプッシュされます。魚が塔の最上部に到達するまでに、スタックにはいくつかの0s が含まれ、この数はn回の試行とp  = 1/2の二項分布に従います。

スタックの長さが0(確率1/2 n)の場合、プログラムは停止します。長さが1(確率n / 2 n)の場合、魚は入力と改行を印刷し、タワーの別のレベルを構築します。長さがそれ以外の場合、魚はスタックを破棄し、タワーの底に戻ります。実際には、実際に何かをする可能性のうち、そのうちのn個が入力文字列を出力し、そのうちの1つがプログラムを停止し、必要な確率を与えます。


7

Pythonの372の 69 66バイト

  • Jonathan Allanのおかげで3バイト節約されました:速記をインポートし、カウントを2から開始します。
  • L3viathanのおかげで3バイト節約されました:指摘されたrandint()は包含的であり、またwhile条件も短縮されました。
from random import*
s=input();i=1
while randint(0,i):print(s);i+=1

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


1
出力キャッシュをオフにする設定があります- そのように
ジョナサンアラン

2
私は考えてそれはnが大きい(私は、ギアで英語脳を得ることができない「...(と、なぜ彼らはスペックを尊重し、擬似ランダム性と大きな数字の問題を無視して)...」無視のための「オフ」であることを許容できるのです-もしそうなら、あなたはすることができますrandom()<1/i
ジョナサンアラン

1
これは確率withで始まりませんか?randint包括的です。その後、その行をwhile randint(0,i):print(s);i+=1
-L3viathan

1
同じソリューションを思いついたばかりです。
エソランジングフルーツ

TIOリンクを更新しました。現在、バイトカウントは浮動小数点バージョンと同じです。
ジョナサンアラン

6

QBIC19 17バイト

ドロップ=1、条件を切り替え、2バイトを節約

{p=p+1~_rp||?;\_X

説明

{       Infinitely DO
p=p+1   Add 1 to p (p starts as 0, so on first loop is set to 1, then 2 etc...)
~       IF
  _rp|| a random number between 0 and p
        (implicitly: is anything but 0)
?;      THEN print A$ (which gets read from the cmd line)
\_X     ELSE QUIT
        END IF and LOOP are auto-added at EOF

6

Braingolf、23バイト

#|V12[R!&@v!r?<1+>1+]|;

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

乱数発生する場合、終了、そうでなければインクリメント0 及びループ。セパレーターはx0 <= x < n+1xn|

説明:

#|V12[R!&@v!r?<1+>1+]|;  Implicit input of commandline args to stack
#|                       Push |
  V                      Create stack2 and switch to it
   12                    Push 1, then 2
     [..............]    Do-While loop, will run indefinitely unless conditional skips
                         Closing bracket
      R                  Return to stack1
       !&@               Print entire stack without popping
          v              Switch to stack2
           !r            Generate random number 0 <= x < n where n is last item on stack
             ?           If last item is greater than 0..
              <          ..Move first item to end of stack
               1+        ..and increment, this is the loop counter number
                 >       ..Move back
                  1+     ..and increment, this is the upper range of the RNG
                    ]    ..end loop
                     |   Endif
                      ;  Suppress implicit output

6

アリス、18バイト

/?!\v
\iO/>]qhUn$@

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

説明

/     Reflect to SE. Switch to Ordinal.
i     Read all input as a string and push it to the stack.
!     Store the string on the tape.
/     Reflect to E. Switch to Cardinal.
>     Ensure that the IP moves east. This begins the main loop.

  ]   Move the tape head to the right. We'll be using the tape head's 
      position as a counter variable. Note that this tape head is independent
      of the one used in Ordinal mode to point at the input string.
  q   Push the tape head's position to the stack.
  h   Increment it (so that it's 2 initially).
  U   Get a uniformly random number in [0,n).
  n   Logical NOT. Gives 1 with probability 1/n and 0 otherwise.
  $@  Terminate the program if we got a  1.
  \   Reflect to NE. Switch to Ordinal.
  ?   Retrieve the input from the tape.
  O   Print it with a trailing linefeed.
  \   Reflect to E. Switch to Cardinal.

v     Send the IP south where it runs into the > to start the next
      loop iteration.



3

、14バイト

A²γW‽γ«θ_A⁺γ¹γ

オンラインでお試しください!リンクは、コードの詳細バージョンです。_セパレータとして使用します。注:出力キャッシュは無効になっていますので、デニスのサーバーを叩かないでください!


3

MATL、9バイト

`G@QYrq]x

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

説明

`        % Do...while
  G      %   Push input
  @      %   Push iteration index k, starting at 1
  QYrq   %   Random integer uniformly distributed in {0, 1, ..., k}. This is the
         %   loop condition. If non-zero (which occurs with probability k/(1+k))
         %   proceed with next iteration; else exit loop
]        % End
x        % Delete, as there are one too many strings. Implicitly display the stack

3

Perl 6の 50の41 38 36  26バイト

{put $_//last for (($,$_),*⊎$_...*).map(*.pick)}

それを試してみてください

{eager ->{(++$).rand>.5??.put!!last}...*}

それを試してみてください

{eager ->{(++$).rand>.5??.put!!0}...0}

それを試してみてください

{eager ->{(++$).rand>.5&&.put}...!*}

それを試してみてください

.put while (++$/).rand>.5

-nコマンドライン引数付き)

それを試してみてください


3

Python 3、55バイト

v=s=input();i=2
while hash(v)%i:print(s);i+=1;v=hash(v)

説明

ランダムにインポートする必要をなくすために、Pythonプロセスが起動されるたびに(少なくともMacOSでは)ハッシュビルトインがランダムにシードされるという事実を利用しました。最後のハッシュの各ハッシュは、一連の疑似ランダム整数を生成する必要があります。

ハッシュは、擬似ランダムに十分である場合は、モジュロはi確率でゼロです1/i

ノート

私は冗長なハッシュに少し悩んでいますが、Pythonで一時的な割り当てや条件付きの割り当てがなければ、少し立ち往生しています。


反復ハッシュが常に乱数の全領域をカバーするのか、それとも潜在的にサイクルでスタックするのかを知っていますか?ほとんどのプログラミング言語は、人々が意図的にハッシュ衝突を引き起こすことを避けるために、ランダム化されたハッシュアルゴリズムを使用していますが、ハッシュアルゴリズムのランダム性の保証がPRNGのランダム性とどのように比較されるかはわかりません。

それは公平なポイントです。そして、確認するには、Pythonハッシュ実装の分析が必要になります(より徹底的なチェックなしで)。私はそれはそれはないかもしれないチャンスがあるのも、楽しみのソリューションだと思った100%の擬似ランダム= P
キットハム

I'm a little bothered...再帰?
フェリペナルディバティスタ

3

C#

これは、トップC#回答と同じ長さですが、次のとおりです。

using System;s=>{var x=(1<<31)/new Random().Next();for(;++x>0;)Console.Write(s+" ");}

一部の数学では正しい確率が得られることを指摘したかっただけです。

int.MaxValue/new Random().Next()-1

と同等です

(int)(1 / new Random().NextDouble()) - 1;

そして、関数f(x)= 1 / x-1は次のとおりです。

f(1)= 0

f(1/2)= 1

f(1/3)= 2

f(1/4)= 3

したがって、1/2は0に切り捨てられるチャンス、1/6は1に切り捨てられるチャンス、1 //(n + 1)(n + 2)はnに切り捨てられるチャンスです。

多分他の言語がこれを利用するかもしれません。

編集:私の間違いを修正

小さくするために何かを考えました。

編集編集:私はあらゆる種類の間違いです。複数回評価された場合は機能しないため、ランダムからループを引き出しました。

編集編集編集:変数iを取り除きました。今、縮小しようとするのをやめるつもりです。いや、嘘をついた。別のバイトを取り除きました。



2

C、41バイト

n;f(char*s){for(n=1;rand()%++n;puts(s));}

randシードされていると仮定します。オンラインでお試しください!


「想定されてrandいる」-それは妥当な仮定ですか?rand標準では、デフォルトで1の固定シード値を持つことが要求されており、私が知っているすべての実装はまさにそれを行います。この関数が他のコードと組み合わせたときにチャレンジが要求することだけを行う場合、他のコードを回答とバイトカウントに含める必要があると思います。
hvd

2

braingasm、22バイト

編集:同じバイト数ですが、新しいテープのL模倣機能に忍び込むことができることに気付きました。

,[>,]>L+[+$rzQ>[.>]:>]

0セパレータとして使用します。このように動作します:

,[>,]                   Read a byte and move to next cell until end of input.
     >                  After the loop we're in an empty cell;
                          Leave it empty and move to the next.
      L                 Set tape limit here:
                          The tape will then wrap around if we move further.
       +                Increase current cell by one.
                          This cell will be our counter.
        [            ]  Loop until the counter is zero.
                          That won't happen, so it's an infinite loop.
         +              Increase again, so the first time the counter is 2.
          $r            Get a random number, 0 <= r > current cell
            zQ          Quit the program if that random number was 0
              >         Wrap around to the start of the tape.
               [.>]     Print the input stored on the tape
                          The loop will stop at the blank cell.
                   :    Print the blank cell as a number ("0")
                    >   Go to the next (last) cell

2

Python、54バイト

lambda s:int(1/random()-1)*(s+'|')
from random import*

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

コピー数を生成floor(1/p)-1有するp均一単位区間から選択されます。コピーの数であるn場合1/p-1の間にあるnn+1するとき発生しました、1/(n+2) < p < 1/(n+1)。これは確率1/(n+1)-1/(n+2)またはで起こり1/((n+1)*(n+2)ます。これは、出力の所望の確率であるnコピー:1/20のPROB、1/61のPROB、1/122のPROB、...


なぜform random import*一番下にあるのですか?
電卓

@CalculatorFeline順序は関係ありません。関数定義はどちらの方法でも機能します。
-xnor

書き込まないでバイトに落下するために@CalculatorFeline f=TIOヘッダーでそれをして置くこと
氏Xcoder

それは理にかなっている。
電卓

2

C ++、97 96 57バイト

ここでcodegolfの私の最初の試み:)

#include<iostream>
int main(){std::string S;std::cin>>S;int i=1;while(rand()%++i)puts(S.data());}

を使用して1バイトを保存しました for

#include<iostream>
int main(){std::string S;std::cin>>S;for(int i=1;rand()%++i;)puts(S.data());}

誰もインクルードをカウントしないため、39バイトを節約しました

void p(string S){for(int i=1;rand()%++i;)puts(S.data());}

食べない

#include <iostream>
int main()
{
  // Create and read string from inputstream
  std::string S;
  std::cin >> S;       

  // rand % i: create random int in range [0, i-1]
  // Zero is seen as false and all positive int as true
  int i = 1;
  while (rand() % ++i) 
    puts(S.data());    
}

コマンドラインから引数として文字列を取ることができます
-Maliafo

デフォルトで含まれているコンパイラを見つけない限り、インクルードはカウントされます
フェリペナルディバティスタ

2

F#、161バイト

間違いなくゴルフに最適な言語ではありませんが、試してみることにしました(F#については何も知らないので、答えを改善するためのヒントは大歓迎です)。

let f s=
 let r,z=System.Random(),(<>)0
 let p _=printfn"%s"s
 seq {for i in 2|>Seq.unfold(fun i->Some(i,i+1))do yield r.Next(i)}|>Seq.takeWhile z|>Seq.iter p

以下で実行:

[<EntryPoint>]
let main argv =
    "test" |> f
    0

セパレータとして新しい行を書き込みます。



2

JS(ES6)、47バイト

x=>{for(i=1;Math.random()<i/(i+1);i++)alert(x)}

他のES6の回答とは異なり、これはforループを使用し、再帰ではなく爆弾を警告します。プログラムの停止時に出力されるセパレーターは未定義です。



1

Python、75バイト

他のPythonの答えは短いですが、別の方法で試してみたかったです。

from random import*
f=lambda d=1,s=input():randint(0,d)and s+'!'+f(d+1)or''
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.