俄罗斯轮盘,已重装


32

让我们玩俄罗斯轮盘!

通常,这是编写最短的MOD 6程序的竞赛,但这不是很现实,因为每次单击获胜的机会都会减少。规则如下:

  1. 模拟一个真实的六射手
    • 将一颗子弹放入六个弹药室之一中,然后仅在比赛之前将枪管旋转一次。
    • n次尝试失败的机会是1/6。
    • n次尝试 输球的机会是1 /(6-n)
    • 您保证最多只能尝试6次。
  2. 输:
    • 显示文字 *BANG!*
    • 终止程序。
  3. 获奖情况:
    • “胜利”是指枪不射击,但子弹距离锤子较近。
    • 显示文字 *click*
    • 向用户展示“触发器”以及终止程序的能力(例如,“ ctrl + c”,请参见下文)。
  4. 程序特定:
    • 拉动触发器是某种形式的用户输入,包括第一次尝试。(这可以是击键,单击鼠标等等;不需要文本提示。)
    • 该程序仅允许一个实例,直到被终止。(运行该程序的新实例类似于使桶具有良好的旋转度,即,下次单击失败的概率重置为1/6。)

最短的代码胜出!

排行榜


3
您的假设是错误的-如果您在每次射击后重新旋转子弹,那么第n次尝试失败的机会只有⅙。如果不进行旋转,则输球的机会是第一杆⅙,第二杆⅕,第三杆¼...在第六杆以1结尾。您可以通过“最多只能尝试6次失败”来认识到这一点。
rhialto

2
@ user2956063您忘记了(n-1)/ 6的机会,您永远无法达到第n次尝试,因此不会失败。他们平衡到统一的1/6。
Jacob Raihle 2015年

2
也许那是计算机科学家和统计学家表达概率方式上的差异,然后-对我来说“第n次尝试失败的机率是⅙”,这是恒定的-n是1还是
100。– rhialto

3
为什么没有标题为“重装的俄罗斯轮盘”?
Hand-E-Food

1
@ user2956063:您的概率是有条件的。P(镜头2丢失)= but,但P(镜头2丢失|在镜头1上不输)=⅕。另外,n(隐式地,我将授予您)限制为[1,6],因此100出局。
蒂姆·佩德里克

Answers:


3

Pyth,23个字节

VO6"*click*" w;"*BANG!*

真的很简单。随机次数为0到5的迭代显示单击并请求输入一行,最后是一声巨响。


1
该死的,佩斯!
Cyoce

+3个字节:最后一个字符串应为*BANG!*,而不是BANG
ayane 2015年

14

Ruby,51个字节

[*['*click*']*rand(6),'*BANG!*'].map{|x|gets;$><<x}

取消高尔夫:

[
  *(                        # Unwrap the following array into the outer one
    ['*click*'] * rand(6)   # An array of 0-5 clicks, see Array#*
  ),
  '*BANG!*'                 # The End
].map do |x| # Shortest way to iterate I was able to find
  gets       # Await input
  $> << x    # Shove the output string to `stdout`
end          # Return value is an array of several (0-5) `stdout`s. Who cares.

要么

(['*click*']*rand(6)<<'*BANG!*').map{|x|gets;$><<x}

留给读者阅读。没那么难

  • 再次,荣誉给马丁,这时候一招$><<作为puts替代品。
  • 不输出换行符,但这不是必需的。
  • 越短越简单。所需行为的要点是进行0-5次单击,然后触发。为此,输出会在数组内部累积。
  • 如果输出"*click*"正常(需要的内容最后打印出来),可以替换$><<2个字节。我不确定这是否还会遵守规则。

68 64字节

(另一种方法)

[*0..5].shuffle.find{|x|gets;x<1||puts('*click*')};puts'*BANG!*'

我没有对算法进行太多的思考(它可能会更紧凑,但不太清楚),但是我真的很喜欢其中的模型:

  • 一个数组模拟一个桶,其元素是容器的内容物。由于只有一个元素是子弹,因此将其旋转并改组是等效的。
  • 0是一颗子弹。其他数字不是。
  • find查找该块既不是false也不为的第一个返回值nil
  • ||-expression从该块隐式返回。这是一个短路:它将返回其第一个操作数(除非是nilfalse)或第二个操作数(否则)。因此,它要么返回true(if,x<1或者更清晰,但更长x == 0),要么返回值puts,而...
  • puts总是返回nil。是的
  • gets请求输入。仅仅击中Enter就足够了。
  • Ctrl+ C终止程序

划掉64是正常的64?
Cyoce

@Cyoce嗯...是的。应该是。上面的条目已取代了它,但是它基于不同的想法,所以我将其删除。
D端

这是一个双关语
Cyoce

@Cyoce哦,原谅我,第一篇文章以及所有这些,还不了解当地的知识:)
D边

9

JavaScript,64字节

for(i=6;i<7&&prompt();)alert(new Date%i--?"*click*":i="*BANG!*")

说明

要拉动触发器,请在提示中输入任何文本。不输入任何内容或单击“取消”以终止。

for(
  i=6;             // i = number of chambers
  i<7              // i equals "*BANG!*" (not less than 7) if we lost
    &&prompt();    // see if we should do another shot
)
  alert(           // alert the result
    new Date%i--   // use the current time in milliseconds as a random number, this is safe
                   //     to use because the gap between shots is greater than i (max 6ms)
      ?"*click*"   // on win pass "*click*" to alert
      :i="*BANG!*" // on lose alert "*BANG!*" and set i to not less than 7
  )

"*Bang!*"不大于7,但NaN不超过7小
BERGI

@Bergi是的。我重新解释了一下说明,以使其更加清晰。
user81655

6
@Bergi仅在Javascript中才使该声明更接近合理。
MikeTheLiar 2015年

7

Lua,82 75字节

相当长,但是lua中有很多详细信息。

for a=math.random(6),1,-1 do io.read()print(a>1 and"*click*"or"*BANG!*")end

6

LabVIEW,46个LabVIEW原语

创建一个0和1的数组,它具有一个循环以等待单击并输出字符串。最初它表示BANG,因为我在启动之前忘记重设指示器。

另请注意,这是一个gif格式,如果您无法播放/加载图片,请重新打开该页面。


"*click*"如果枪没有射出,我看不到输出在哪里。另外,它输出"bang"还是"*BANG!*"
Katenkyo

这应该是一个gif,但是对我来说它不起作用,这可能是问题所在。是的,这只会
让人大跌眼镜

愚蠢的我忘了在启动之前将字符串重新初始化为空,所以这就是为什么它在启动时显示BANG的原因
Eumel

没问题,我现在看到了gif,看起来效果很好:)
Katenkyo

5

Pyth,31 30 28字节

FN.S6 EI!N"*BANG!*"B"*click*

几乎可以肯定可以改进。输入任意数字可拉动触发器,空白输入可提早终止(出现错误)。

说明:

FN                               for N in...
  .S6                            shuffle(range(6))...
      E                          get a line of input
       I!N                       if N is falsy (i.e. 0)
          "*BANG!*"              implicit output
                   B             break
                    "*click*     else, print click

您的第一个实际上更短,不需要尾随"
FryAmTheEggman 2015年

@FryAmTheEggman哦,对了,忘记了。谢谢!
门把手

另外,我刚刚发现一些愚蠢的东西,FN<any>仍然与完全相同V<any>,应该更改为不使新的高尔夫球手感到困惑...:P
FryAmTheEggman 2015年

1
您可以简单地删除字符.?。没有必要else
贾库比

@FryAmTheEggman让人迷惑不解。有可能过滤掉磨砂膏很棒
Cyoce

5

说真的 27 25字节

"*BANG!*"6J"*click*"nW,X.

没有在线链接,因为无法通过管道输入进行提示。该程序可以CTRL-C'D随时临阵退缩终止。

说明:

"*BANG!*"6J"*click*"nW,X.
"*BANG!*"                  push "*BANG!*"
         6J                push a random integer in [0,6) (n)
           "*click*"n      push "*click*" n times
                     W     while loop (implicitly closed at EOF):
                      ,X.    get input and discard, pop and print top of stack

4

PHP,52字节

*<?=$n=&rand(0,6-$argi)?click:"BANG!*";$n||@\n?>*

需要 -F命令行选项,计为三个。按下即可扳动扳机Enter

因为-F从字面上来看,每个输入都会再次运行脚本(我不会告诉你),die而类似的操作实际上不会终止,所以我们改为通过抑制运行时错误退出,@\n


样品用量

$ php -F primo-roulette.php

*click*
*click*
*BANG!*
$


4

C,110 74 72字节

感谢Dennis摆脱了include和更少的字节。

main(r){for(r=time(0)%6;getchar(),r--;)puts("*click*");puts("*BANG!*");}
main(r)
{
    for(r=time(0)%6;getchar(),r--;)
        puts("*click*");
    puts("*BANG!*");
}

3

糖果,36字节

程序的大约一半是要打印的文本:(

:6H_(=b"*click*"(;):=)"*BANG!*\n"(;)

长表:

getc
digit6 rand range0  # build a range from 0 .. rand#
while
  popA              # these are the *click* instances  
  stack2
  "*click*"
  while
    printChr
  endwhile
  getc
  popA
endwhile
"*BANG!*\n"         # out of luck
while
  printChr
endwhile

3

Python 3,95个字节

这也是我第一次尝试高尔夫运动,也是在Python 3中。我发誓布鲁斯,我不是同一个人。

from random import*
for a in range(randint(0,5)):input();print("*click*")
input();print("*bang*")

取消高尔夫:

from random import*
for a in range(randint(0,5)):
    input()
    print("*click*")
input()
print("*bang*")

生成一个介于0和5之间(含0和5)的随机数,多次打印单击,然后打印bang。按Enter /返回键来扳动扳机。


按照Bruce的示例,您可以使用from random import*
wnnmaw

除非我缺少其他东西,否则节省了一个字节。但是我接受!谢谢!
史蒂夫·埃克特

很好的尝试,我用您的解决方案作为python 2解决方案的灵感^^
basile-henry 2015年

3

PlatyPar26 25字节

6#?;wT"*click*"O;"*BANG!*

说明:

6#?;                        ## random integer [0,6)
    w           ;           ## while stack.last
     T                      ## stack.last--
      "*click*"O            ## alert "*click*"
                 "*BANG!*   ## alert "*BANG!*"

在线尝试


2

Emacs Lisp,94 89字节

(set'b(%(random)6))(dotimes(a(+ b 1))(read-string"")(message(if(eq a b)"BANG""*click*")))

取消高尔夫:

(set 'b (% (random) 6))
(dotimes (a (+ b 1))
  (read-string"")
  (message (if (eq a b) "BANG" "*click*")))

2

R,86 80 77字节

和往常一样,R具有出色的功能来编写高尔夫球代码,但功能名称不多。

sapply(sample(0:5),function(n){!n&&{cat('*BANG!*');q()};readline('*click*')})

2

Python 2中,108个 104 102 100 98字节

我第一次打高尔夫球:

from random import*
a=[1]+[0]*5
shuffle(a)
for i in a:input();print("*click*","*BANG!*")[i];" "[i]

也许我应该补充一点,该程序在丢失时不会正确终止,它只会引发异常(导致终止):

Traceback (most recent call last):
  File "russian_roulette.py", line 4, in <module>
    for i in a:input();print("*click*","*BANG!*")[i];" "[i]
IndexError: string index out of range

欢迎来到编程难题和代码高尔夫球!当您发布代码高尔夫球答案时,请提供语言名称和字节数(我在这里为您进行了编辑)。谢谢!
ProgramFOX 2015年

是的,非常感谢!我实际上是在尝试解决该问题,但是在您之前没有正确对其进行编辑。
2015年

我得到的字节数为112,您使用了什么?
wnnmaw

另外,您可以执行以下操作来节省2个字节a=shuffle([1,0,0,0,0,0])
wnnmaw 2015年

1
据我所知,随机播放会更改基础数据结构,并且不会返回任何内容。我尝试过了,还是谢谢。标题(语言和字节数)由ProgramFOX编写。但是当我使用wc它时,会给我109太多,所以是正确的。你怎么算?
2015年

2

Perl 5,40个字节

<>,print"*$_*"for(click)x rand 5,'BANG!'

在不使用命令行选项的情况下运行,按即可拉动扳机Enter


2

Python,81字节

import time
for i in["*click*"]*(int(time.time())%6)+["*BANG!*"]:input();print(i)

受Ruby(51)和Python解决方案启发


1

Common Lisp, 109

(do(g(b(nthcdr(random 6)#1='(t()()()()() . #1#))))(g)(read-char)(princ(if(setf g(pop b))"*BANG!*""*click*")))

Not very competitive, but I like circular lists:

(do (;; auxiliary variable x
     x
     ;; initialize infinite barrel, rotate randomly
     (b (nthcdr (random 6) #1='(t()()()()() . #1#))))

    ;; we end the loop when x is T (a bullet is fired)
    (x)

  ;; press enter to shoot
  (read-char)

  ;; pop from b, which makes b advance down the list. The popped value
  ;; goes into x and is used to select the appropriate string for
  ;; printing.
  (princ
   (if (setf x(pop b))
       "*BANG!*"
       "*click*")))

1

Perl 5, 43 bytes

42 bytes + -p command line option. Just press enter to trigger.

$_=0|rand 7-$.<++$i?die"*BANG!*":"*click*"

Thanks to Dom Hastings for his help! Original answer was 67 bytes:

$i++;$a=$i>=int(rand(6));print$_=$a?'*BANG!*':'*click*';last if($a)

Actually the problem with -p was that it would exit before calling the last print statement, not sure why. I've tried it. Other than that, awesome suggestions, thanks! My knowledge continues to grow...
Codefun64

@DomHastings Also, unfortunately, for some reason the 0| trick didn't work as expected, but I did shave some bytes off of it, the print statement and the last statement like you suggested. How does it look now?
Codefun64

@DomHastings Damn, you are good. I recommend putting that as your own answer, since you definitely wrote a smaller program than I (you have 40 bytes compared to my original 67!)
Codefun64

I appreciate the explanation! Always happy to learn more of my favorite scripting language! I never even knew about the prefex incrementing, that's pretty awesome. Thanks :)
Codefun64

You're very welcome, glad to have helped!
Dom Hastings

1

MATL, 41 bytes

6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x

To pull the trigger, input a non-empty string (such as 'try').

To terminate, input an empty string

Examples

In this case the trigger was pulled once and... bad luck:

>> matl
 > 6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x
 > 
> try
*BANG!*

In this case the user stopped (note the final empty input) after two lucky pulls:

>> matl
 > 6Yr`j?t@=?'*BANG!*'DT.}'*click*'DT]}T.]]x
 > 
> try
*click*
> try
*click*
> 

Explanation

6Yr                  % random avlue from 1 to 6    
`                    % do...while  
  j                  % input string
  ?                  % if nonempty
    t                % duplicate the orignal random value
    @                % loop iteration index  
    =                % are the equal?
    ?                % if so             
      '*BANG!*'D     % display string
      T.             % unconditional break                                     
    }                % else
      '*click*'D     % display string
      T              % true value, to go on with do...while loop
    ]                % end if               
  }                  % else                                                    
    T.               % unconditional break
  ]                  % end                                                     
]                    % end                                                     
x                    % delete original random value

1

Perl 6,  58   53 bytes

for ^6 .pick(*) {get;say <*BANG!* *click*>[?$_];!$_&&last} # 58 bytes

$ perl6 -pe '$///=^6 .pick;$_=$/--??"*click*"!!say("BANG!")&&last' # 52+1= 53 bytes

Press enter to pull the trigger, or ctrl+c to put it down.


1

Python 2, 88 84 bytes

This solution is inspired by the python 3 solutions already given. I chose python 2 to remove the print parenthesis even though this changes the behavior of input().

import time
for i in[0]*int(time.time()%6)+[1]:input();print("*click*","*BANG!*")[i]
  • I am using modulo of the time as a random function (good enough for russian roulette)
  • the player input should be "i" then Enter (otherwise input() will throw an error), this trick relies on the fact that the input can be "whatever".

1

Ruby, 45+1=46

Not as clever as D-side's but slightly shorter.

With command-line flag p, run

rand(7-$.)<1?(puts'*BANG*';exit):$_='*click*'

The user can pull the trigger with return and leave with control-c. p causes the program to run in a loop, reading lines from STDIN and outputting $_. Each time it runs, it increments $.. So on the first run, it chooses a random positive integer less than 6, then 5, then 4, and so on. On the first 0, we output manually and exit, until then we output implicitly.

(and now I notice that there's already a very similar Perl. Oh well.)


1

Perl 5, 69 51 49 bytes

map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*"

There is probably some more golfing potential, I will look into this.

Changes:

  • Saved 8 bytes by removing $l and some semicolons, and 10 bytes by changing <STDIN> to <>
  • Saved 2 bytes thanks to Oleg V. Volkov

1
49: map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*"
Oleg V. Volkov

@OlegV.Volkov Thanks! I'll edit it in now.
ASCIIThenANSI

0

VBA, 126 bytes

Golf Version for Minimal Bytes

Sub S()
r=Int(5*Rnd())
e:
a=MsgBox("")
If a=1 Then: If i=r Then MsgBox "*BANG!*" Else: MsgBox "*click*": i=i+1: GoTo e
End Sub

Fun Version that Makes The Buttons more Clear for Increased User Acceptance.

Sub RR()
r = Int(5 * Rnd())
e:
a = MsgBox("Are you Feeling Lucky?", 4)
If a=6 Then: If i=r Then MsgBox "*BANG!*", 16 Else: MsgBox "*click*", 48: i=i+1: GoTo e
End Sub

Some Fun with Custom Forms and You could make a pretty Slick Game in VBA.


0

APL, 39/65 bytes

{⍞⊢↑⍵:⍞←'*BANG*'⋄∇1↓⍵⊣⍞←'*click*'}6=6?6

Pretty straightforward answer.


What do the two byte counts mean?
Mego

0

C, 180 Bytes

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){srand(time(NULL));int r,i=6;while(i!=1){getchar();r=rand()%i;if(r){puts("CLICK");}else{puts("BANG");exit(0);}i--;}}

My first attempt at code golf, there's probably a lot of room for improvement :)


0

Julia, 71 bytes

b=rand(1:6);while b>0 readline();print(b>1?"*click*":"*BANG!*");b-=1end

Press Enter to fire or Ctrl+C to quit. The latter ends with an InterruptException.

Ungolfed:

# Set an initial bullet location
b = rand(1:6)

while b > 0
    # Read user input
    readline()

    # Check the location
    if b > 1
        print("*click*")
    else
        print("*BANG!*")
    end

    b -= 1
end

0

Lua, 73 bytes

q=io.read q()for i=2,math.random(6)do print"*click*"q()end print"*BANG!*"
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.