이것은 결국 멈출 것이다…


41

입력 문자열이 주어지면 다음과 같은 방식으로 S인쇄 S하고 비어 있지 않은 구분 기호가옵니다.

  • 1 단계 : S1/2인쇄되는 확률 및 1/2종료 프로그램에 대한 기회를.

  • 2 단계 : S2/3인쇄되는 확률 및 1/3종료 프로그램에 대한 기회를.

  • 3 단계 : S3/4인쇄되는 확률 및 1/4종료 프로그램에 대한 기회를.

  • 단계 n: Sn/(n+1)인쇄되는 확률 및 1/(n+1)종료 프로그램에 대한 기회를.

노트

  • 입력 문자열은 해당 언어의 문자열 유형에서 허용되는 문자로만 구성됩니다.

  • 비어 있지 않은 구분 기호는 항상 같으면 사용할 수 있습니다. S프로그램이 종료되기 전의 마지막 인쇄 후에 분리자가 인쇄 될 것으로 예상 됩니다.

  • 1/2인쇄하기 전에 프로그램이 종료 될 수 있습니다.

  • 후행 줄 바꿈이 허용됩니다.

  • 귀하의 답변은 설명 된 확률을 존중하기 위해 진정으로 시도해야합니다. 분명히, n크면 이것은 사실이 아닙니다. 답에서 확률을 계산하는 방법과 의사 난수 및 큰 숫자 문제를 무시하고 스펙을 존중하는 이유에 대한 적절한 설명만으로 충분합니다.

채점

이것은 이므로 바이트 단위의 최단 답변이 이깁니다.


구분자가 빈 문자열 일 수 있습니까?
rturnbull

16
@rturnbull 글쎄요. 그 경우에는 구분자가 없기 때문입니다.
치명적인

우리는 이들을 하나씩 인쇄해야합니까, 아니면 프로그램이 종료 될 때 모든 것을 인쇄 할 수 있습니까?
Dennis

@Dennis 하나씩.
치명적인

답변:



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가 요청하는대로 프로그램이 더 무작위로 중지됩니다.
Charlie

루프가 너무 빡빡해서 아아.
TheLethalCoder

2
@TheLethalCoder-예, thight 루프는 생성기의 시드가 동일 할 가능성을 의미합니다. 참조 : msdn.microsoft.com/en-us/library/system.random.aspx#Instantiate
Erno

12

R, 47 46 43 바이트

코멘트에서 Robin Ryder로 인해 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 2016 년

@mfloren 네, 여기에있는 다른 모든 답변과 마찬가지로 확률 적이며 종료 될 때마다 종료 확률이 감소하지만 결국 종료됩니다. 아무 것도 인쇄하지 않을 확률은 5입니다! 여러 번 실행하고 출력을 비교하십시오.
rturnbull

function(s)보다 짧은s=scan(,'');
JAD

1
그리고 pryr::f(while(runif(1)<T/(T<-T+1))print(s))더 짧습니다.
JAD

1
@JarkoDubbeldam 불행히도 전역 변수를 수정하고 함수를 한 번만 호출 할 수 있으므로 익명 함수를 사용 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

@ 운명 : 그것은 나를 위해 않습니다. 몇 번 실행 해보십시오. 아무 것도 출력하지 않을 확률이 50 %이므로 "불운"상태 일 수 있습니다.
Emigna 2016 년

11
무작위 작업의 문제를 물려받습니다. 때로는 모든 확률이 당신에게 불리합니다.
J_F_B_M

@J_F_B_M 고유?
Leaky Nun

1
@LeakyNun 아니요, "상속 문제"입니다 (이전 이벤트에서 이벤트가 상속되지 않을 확률). J_F_B_M은 도박꾼의 오류를 분명히 언급하고있었습니다.
aebabis 2018 년

11

자바 스크립트, 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않습니까?
Neil

1
@ Neil 고마워, 4 바이트를 저장했습니다!
토마스 W

2
환경이 브라우저 인 경우 6 바이트를 저장 하는 alert대신 사용할 수 있습니다 console.log. 스 니펫은 alert = console.log원하는 경우 방해하지 않는 출력을 표시하도록 설정할 수 있습니다 (허용 된 경우 바이트를 저장하지 않으면 하나만 제정 할 수 있습니다)
Craig Ayre

10

자바 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

@cliffroot이 있다 에서 for루프.
Okx

1
@Okx for루프가 명시 적으로 필요하지 않도록 조건을 의미 했습니다 return. for 문 내부의 두 번째 표현식입니다.
cliffroot

@ cliffroot 아, 이해합니다.
Okx

1
겠습니까 int n=21f/n++사용할 수 있습니까?
JollyJoker

9

수학, 43 바이트

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

JungHwan Min은 1 바이트를 절약하고 (위) 더 나은 것을 제안했습니다 (아래)

수학, 37 바이트

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

1
RandomInteger@n!=0이 경우와 동일하며 RandomInteger@n<1n++병합 할 수 있습니다 RandomInteger@n. 또한 For(거의 항상) While: -5 바이트 보다 짧습니다 .For[n=1,RandomInteger@n++>0,Print@#]&
JungHwan Min

"에 대한"승리! 나도 당신의 답변을 게시했습니다
J42161217

For[n=1,!n∣Hash[# n++],Print@#]&해시가 상당히 임의적이라고 가정하면 34 바이트에서 작동합니다. 그러나 임의성은 입력에 따라 다릅니다. 예를 들어 시도% /@ Alphabet[]
Kelly Lowder

8

클로저, 61 56 바이트

아 왜 내가 처음에 함께 가지 않았 for습니까? 그러나 실제로 pedantic 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)항상 true?
cliffroot

아 잘 잡아라, 나는 증가하는 것을 의미했다 n!
NikoNyrh

8

> <> , 124 112 바이트

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

온라인으로 사용해보십시오! ( 물고기 놀이터 에서도 볼 수 있지만 몇 가지 버그로 인해 네 번째 줄에 }이후 를 추가 l하고 코드 뒤에 줄 바꿈을 추가하여 올바르게 작동해야합니다.)

> <>에서는 임의성이 까다 롭습니다. 유일한 임의 명령은이며 x, 이는 4 가지 선택 (왼쪽, 오른쪽, 위 및 아래)에서 물고기의 방향을 무작위로 선택하므로이를 1 / n 확률로 무언가로 바꾸는 것은 간단하지 않습니다.

이 코드가 수행하는 방식은> <>의 자체 수정 기능을 사용하여 코드 아래에 임의의 타워를 빌드하는 것이므로 예를 들어 코드는 다음과 같습니다.

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

물고기는 탑의 바닥에서 시작합니다. 타워의 각 레벨에서 x두 거울 사이에 갇혀 있으므로 물고기는 왼쪽이나 오른쪽으로 만 탈출 할 수 있습니다. 이 방향 중 하나를 사용하면 물고기를 탑의 다음 레벨까지 올릴 수 있지만 왼쪽으로 0이동하면 a 를 쌓아 올립니다 . 물고기가 탑 꼭대기에 도달 할 때까지 스택에는 몇 개의 0s 가 들어 있으며이 숫자 는 n 개의 시행과 p  = 1/2 로 이항 분포 를 따릅니다 .

스택 길이가 0 (확률이 1/2 n 인 경우 )이면 프로그램이 중지됩니다. 길이가 1 (확률 n / 2 n ) 인 경우, 물고기는 입력과 개행을 인쇄하고 다른 레벨의 타워를 만듭니다. 길이가 다른 것이면 물고기는 스택을 버리고 탑의 바닥으로 돌아갑니다. 실제로 실제로 수행 할 수있는 가능성 중에서 n 개가 입력 문자열을 인쇄하고 그 중 하나가 프로그램을 정지시켜 필요한 확률을 제공합니다.


7

파이썬 3 , 72 69 66 바이트

from random import*
s=input();i=1
while randint(0,i):print(s);i+=1

온라인으로 사용해보십시오!


1
- 설정은 출력 캐시를 해제 할 수있다 과 같이
조나단 앨런

2
나는 큰 n에 대해 "해제"될 수 있다고 생각 한다 (나는 영어 뇌를 장비에 넣을 수 없다. 그렇다면?) 그렇다면 가능 random()<1/i합니다.
Jonathan Allan

1
이것이 확률 ⅓으로 시작하지 않습니까? randint포함됩니다. 그런 다음 줄을while randint(0,i):print(s);i+=1
3

1
방금 같은 해결책을 생각해 냈습니다.
Esolanging 과일

업데이트 된 TIO 링크. 이제 바이트 수는 부동 소수점 버전과 동일합니다.
Jonathan Allan

6

QBIC , 19 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이면 종료 하고 그렇지 않으면 증분 및 반복 x되는 난수를 생성 합니다. 분리기는0 <= 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

Alice , 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⁺γ¹γ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. _구분자로 사용합니다 . 참고 : 출력 캐싱이 비활성화되어 있으므로 Dennis 서버를 망치지 마십시오!


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

파이썬 3 , 55 바이트

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

설명

무작위 가져 오기를 줄이기 위해 파이썬 프로세스가 시작될 때마다 (적어도 MacOS에서는) 해시 내장이 무작위로 시드된다는 사실을 악용했습니다. 마지막 해시의 각 해시는 일련의 의사 난수 정수를 생성해야합니다.

해시가 의사 난수 인 경우 모듈러스 i는 확률이 0입니다 1/i.

노트

나는 여분의 해시에 약간 신경을 쓰지 만 파이썬에서 do-while 또는 조건부 할당이 없으면 조금 붙어 있습니다.


반복 해싱이 항상 임의의 숫자의 전체 공간을 포함하는지 또는 잠재적으로 순환에 걸릴 수 있는지 알고 있습니까? 오늘날 대부분의 프로그래밍 언어는 의도적으로 해시 충돌을 일으키는 사람들을 피하기 위해 무작위로 해시 알고리즘을 사용하지만 해시 알고리즘의 임의성이 PRNG와 어떻게 비교되는지 확실하지 않습니다.

그것은 좋은 지적입니다. 확실하지 않습니다. 파이썬 해시 구현에 대한 분석이 필요합니다 (더 철저한 점검없이). 나는 그것이 100 % 의사 난수 = p가 아닐 수도있는 재미있는 해결책이라고 생각했다.
Kit Ham

I'm a little bothered...재귀?
Felipe Nardi Batista

3

씨#

이것은 최고 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 바이트

편집 : 동일한 바이트 수이지만 새로운 테이프 Limit 기능을 몰래 엿볼 수 있음을 깨달았습니다 .

,[>,]>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

파이썬 , 54 바이트

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

온라인으로 사용해보십시오!

같은 매수를 생성 floor(1/p)-1p균일 단위 간격에서 선택. 사본의 수는 n1/p-1사이에 폭포 nn+1때 발생하는 1/(n+2) < p < 1/(n+1). 이것은 확률 1/(n+1)-1/(n+2)또는로 발생합니다 1/((n+1)*(n+2). 이것은 n사본 을 출력 할 확률입니다 : 1/2prob 0, 1/6prob 1, 1/12prob 2 ...


form random import*바닥에 있습니까?
CalculatorFeline

@CalculatorFeline 순서는 중요하지 않습니다. 함수 정의는 어느 쪽이든 작동합니다.
xnor

@CalculatorFeline 바이트를 쓰지 않고 f=TIO 헤더 에 넣지 않음 으로써 바이트로 떨어 뜨리기
Mr. Xcoder

말이 되네요
CalculatorFeline

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

포함 된 컴파일러는 기본적으로 포함되어있는 컴파일러를 찾지 않으면 계산됩니다.
Felipe Nardi Batista

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

파이썬, 75 바이트

다른 파이썬 답변은 더 짧지 만 다른 방법으로 시도하고 싶었습니다.

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.