这最终将停止……


41

给定输入字符串SS按以下方式打印,后跟非空分隔符:

  • 步骤1:S1/2机会被打印,并且有1/2程序终止的机会。

  • 步骤2:S2/3机会被打印,并且有1/3程序终止的机会。

  • 步骤3:S3/4机会被打印,并且有1/4程序终止的机会。

  • 步骤nSn/(n+1)机会被打印,并且有1/(n+1)程序终止的机会。

笔记

  • 输入字符串仅包含您语言的字符串类型可接受的字符。

  • 可以使用任何非空分隔符,只要它始终相同即可。预期S在程序终止前的最后一次打印之后将打印分隔符。

  • 该程序有1/2机会在打印任何内容之前终止。

  • 尾随新行是可以接受的。

  • 您的答案必须真正地尝试遵守所述的概率。显然,当n大时,这将越来越不正确。正确解释您的答案中的概率是如何计算的(以及为什么它们尊重规范,而忽略伪随机和大数问题)就足够了。

计分

这是,因此最短的答案以字节为单位。


分隔符可以为空字符串吗?
rturnbull

16
@rturnbull好吧,因为在这种情况下,没有分隔符。
Fatalize

我们是否必须一个接一个地打印它们,还是在程序终止时仅打印所有一个?
丹尼斯,

@丹尼斯一个接一个。
Fatalize

Answers:



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-是的,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

@mfloren是的,就像这里的所有其他答案一样,它是随机的,随着终止的进行,终止的机会会减少,但最终会终止。.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%的机会不输出任何内容,因此您可能不走运。
Emigna

11
随机任务的继承问题。有时候,一切都是不利于您的。
J_F_B_M

@J_F_B_M固有的?
Leaky Nun

1
@LeakyNun不,这是“继承问题”(事件的概率未从先前的事件继承)。J_F_B_M显然是在指赌徒的谬论。
aebabis

11

Javascript,60 58 54字节

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

将输出字符串s。如果程序终止,则打印的分隔符为NaN0

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

f('test')

Math.random()返回介于0和1之间的值。如果该值小于n/(n+1)s则将被打印。

@Neil节省了4个字节


1
为什么不使用n/++n
尼尔

1
@Neil谢谢,保存了4个字节!
Thomas W

2
如果您的环境是浏览器,则可以使用它alert而不是console.log节省6个字节- alert = console.log如果需要,此代码段可以设置为显示非干扰性输出(如果允许-不保存字节,仅有助于保持理智)
Craig Ayre

10

Java 8,72 62 61字节

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

-10个字节,感谢@cliffroot
-1个字节感谢@JollyJoker

定界符是换行符。

说明:

在这里尝试。

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语句中的第二个表达式。
悬崖根

@cliffroot啊,我明白了。
Okx

1
int n=21f/n++工作?
JollyJoker

9

Mathematica,43个字节

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

郑焕敏保存了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 Min

“为”获胜!我也发布了您的答案
J42161217

For[n=1,!n∣Hash[# n++],Print@#]&假设散列是相当随机的,它将也以34字节工作。但是,随机性取决于输入。例如,尝试% /@ Alphabet[]
Kelly Lowder,

8

Clojure,61 56字节

哦,为什么我不首先使用a for?但是实际上必须doseqfor懒惰的评价那样使用学究的方法。

#(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
NikoNyrh

8

> <>124112字节

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

在线尝试!(您也可以在鱼操场上观看它,但是由于某些错误,您必须在第四行的}后面添加a ,并l在代码后添加一堆新行以使其正常运行。)

> <>中的随机性是棘手的。唯一的随机指令是x,它从四个选择(左,右,上和下)中随机选择鱼的方向,因此将其变成概率为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到栈中。到鱼到达塔顶时,烟囱中包含一定数量的0s,并且该数量遵循二项式分布,其中n次试验且p  = 1/2。

如果堆栈的长度为0(概率为1/2 n),程序将停止。如果长度为1(概率为n / 2 n),则鱼将打印输入内容和换行符,并建造塔的另一层。如果长度不一样,鱼将丢弃烟囱并返回塔的底部。实际上,在实际执行某项操作的可能性中,其中n种会打印输入字符串,而其中一种会中止程序,并给出所需的概率。


7

Python 3中72个 69 66字节

  • 感谢Jonathan Allan节省了3个字节:导入简写并从2开始计数。
  • 由于L3viathan节省了3个字节:指向的randint()包含在内,并且在有条件时也缩短了。
from random import*
s=input();i=1
while randint(0,i):print(s);i+=1

在线尝试!


1
有一个设置可以关闭输出缓存- 像这样
Jonathan Allan

2
认为大n表示“关闭”是可以接受的(我无法使英国人适应,“ ...(以及为什么他们尊重规范,不考虑伪随机性和大数问题)...”,而无视-是吗?如果是这样,那么你可以做random()<1/i
乔纳森·艾伦,

1
这不是从概率⅓开始的吗?randint是包容性的。然后,您可以while randint(0,i):print(s);i+=1
将这

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+]|;

在线尝试!

生成随机数x,其中0 <= x < n+1,如果x为0则终止,否则递增n并循环。分隔符为|

说明:

#|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

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
Kit Ham

I'm a little bothered...递归?
Felipe Nardi Batista

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。

也许其他一些语言可以利用这一点。

编辑:修正了我的错误

我想到了一些使其缩小的方法。

编辑:我只是种种错误。将Random退出循环,因为如果对其进行多次评估,它将无法正常工作。

编辑编辑:我摆脱了变量我。我将停止尝试缩小它。不,撒谎。摆脱了另一个字节。



2

C,41个字节

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

假设rand是种子。在线尝试!


“假设rand是种子。” -这是一个有效的假设吗?rand标准要求默认情况下将其固定种子值设置为1,而我所知道的所有实现都只是这样做。如果此功能仅能与其他代码结合使用时遇到的挑战,我认为答案和字节数中必须包含其他代码。
hvd

2

脑力激荡,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)-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/2概率为0,1/6概率为1,1/12概率为2,...


为什么form random import*在底部?
CalculatorFeline

@CalculatorFeline顺序无关紧要。函数定义以任何一种方式起作用。
xnor

@CalculatorFeline为了通过不写f=并将其放置在TIO标头中来丢弃字节
Xcoder先生,2017年

那讲得通。
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());}

我通过使用保存了一个字节 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

Python,75个字节

另一个Python答案要短一些,但我想尝试另一种方法:

from random import*
f=lambda d=1,s=input():randint(0,d)and s+'!'+f(d+1)or''
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.