Російська рулетка, перезавантажена


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-му. Ви визнаєте це за допомогою "Ви гарантовано програєте, максимум, 6 спроб".
rhialto

2
@ user2956063 ви забуваєте, що є (n-1) / 6 шанс, що ви ніколи не досягнете n: th спроби, і таким чином не можете програти. Вони врівноважуються до рівномірної 1/6.
Яків Райхле

2
можливо, це різниця в тому, як комп'ютерні вчені та статистики висловлюють ймовірність тоді - мені "Шанс програти на п’ятій спробі - це", скажімо, це постійний характер - чи n чи 1, чи 100.
rhialto

3
Чому це не було названо "Російська рулетка, перезавантажена"?
Hand-E-Food

1
@ user2956063: Ваші ймовірності умовні . P (програв постріл 2) = ⅙, але P (програв постріл 2 | не програв на кадрі 1) = ⅕. Крім того, nобмежено [явно (я надаю вам) обмеження [1,6], тому 100 не працює.
Тім Педерік

Відповіді:


3

Pyth, 23 байти

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

Дійсно просто. Випадкова кількість ітерацій 0 - 5 відображає клацання та запитує рядок введення з наступним ударом в кінці.


1
чорт ти, піт!
Кіос

+3 байт: останній рядок повинен бути *BANG!*, а неBANG
ayane

14

Рубі, 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}

Ungolfing залишив для читачів. Не так складно

  • Знову ж , престижність Мартіну, на цей раз для приколу з $><<як putsзаміна.
  • Не виводить нові рядки, але цього не потрібно.
  • Чим коротше, тим простіше. Суть необхідної поведінки полягає в тому, щоб зробити 0-5 клацань і потім стріляти. Для цього результати накопичуються всередині масиву.
  • Ще 2 байти можна відтерти, якщо результати, як-от "*click*"нормально (те, що потрібно, надрукується в кінці), замінивши $><<на . Я не був впевнений, чи все одно це буде дотримуватися правил.

68 64 байт

(інший підхід)

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

Я не дуже замислювався над алгоритмом (він може бути ще більш компактним, але не настільки зрозумілим), але мені дуже подобається модель всередині нього:

  • Масив імітує стовбур, у складі якого є елементи камер. Оскільки лише один елемент - це куля, то обертання та переміщення - рівнозначні.
  • 0- куля. Інших цифр немає.
  • findзнаходить перше повернене значення, для якого блоком є ​​ні falseнорм nil.
  • ||-експресія неявно повертається з блоку. Це коротке замикання: він повертає перший операнд (якщо це не nilабо false) або другий ( в іншому випадку). Тож воно або повертає true(якщо x<1або, зрозуміліше, але довше x == 0) або повертає значення puts, тоді як ...
  • putsзавжди повертається nil. Так.
  • getsзапитує введення. EnterДосить просто влучити.
  • Ctrl+ Cприпиняє програму

Перекреслено 64 це нормально 64?
Кіос

@Cyoce uhm ... так. Має бути, певно. Це було витіснене вищезазначеним записом, але воно засноване на іншій ідеї, тому я залишив їх, перекресливши.
D-сторона

це каламбур на це
Cyoce

@Cyoce о, вибачте мене, перший пост і все це, не знаючи краєзнавця :)
D-side

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 Це правда. Я переформулював пояснення, щоб зробити його трохи зрозумілішим.
користувач81655

6
@Bergi тільки в Javascript, це твердження навіть наближається до сенсу.
MikeTheLiar

7

Луа, 82 75 байт

Досить довго, але в луї багато багатослівних.

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

6

LabVIEW, 46 LabVIEW Primitive

Створює масив 0 і один 1, має цикл для очікування кліків і виводить рядок. Спочатку сказано, що BANG, оскільки я забув скинути індикатор перед його запуском.

Також зауважте, що це gif, якщо ви не граєте / завантажуєте для вас, знову відкрийте сторінку.


Я не бачу, куди ви робите вихід, "*click*"якщо пістолет не стріляв. Крім того, це вихід "bang"або "*BANG!*"?
Катенкіо

це має бути gif, але для мене це не грає, це може бути проблемою. І так, це ставить лише удар, це я не читав належним чином, я змінюю це через секунду
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

@FryAmTheEggman О, так, забув про це. Спасибі!
Дверна ручка

Крім того, я щойно помітив щось нерозумне, FN<any>все ще цілком тотожне V<any>, що, мабуть, слід змінити, щоб не плутати нових гольфістів ...: P
FryAmTheEggman

1
Ви можете просто зняти символи .?. Немає потреби в else.
Якубе

@FryAmTheEggman плутати людей - це приголомшливо. Це може бути дивовижним при фільтруванні скрабів .
Кіос

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

Perl 5, 43 байти

Бігайте з perl -p. Стабільний варіант кулі - тобто положення кулі вирішується лише один раз на самому початку.

$i//=0|rand 6;$_=$i--?'*click*':die'*BANG*'

Приємно! Я б змінив заголовок на "Perl 5.10+", оскільки ви використовуєте //=. Крім того, не забудьте порахувати -pсвій рахунок .
ThisSuitIsBlackNot

4

C, 110 74 72 байти

Завдяки Деннісу за те, що він позбувся включених і набагато менше байт.

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 включно, натисніть це друк багато разів, потім надрукуйте чубку . Натисніть клавішу Enter / return, щоб натиснути курок.


Наслідуючи приклад Брюса, ви можете зберегти кілька байт за допомогоюfrom random import*
wnnmaw

Якщо немає чогось іншого, чого мені не вистачає, це один байт економії. Але я візьму! Спасибі!
Стів Екерт

Приємна спроба, я використав ваше рішення як натхнення для мого рішення python 2 ^^
basile-henry


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 має приголомшливі функції кодування гольфу, але назви функцій looooooong.

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

Так, велике спасибі! Я насправді намагався вирішити цю проблему, але не вдалося її правильно відредагувати.
ბიმო

Я вважаю , що ваш байт вважається 112, що ви використовували?
wnnmaw

Також ви можете зберегти 2 байти, зробивши цеa=shuffle([1,0,0,0,0,0])
wnnmaw

1
Наскільки я знаю, перетасування змінює базову структуру даних і нічого не повертає. Я спробував це, в будь-якому випадку дякую. Заголовок (мова та кількість байтів) був написаний ProgramFOX. Але коли я використовую, wcце дає мені 109, який занадто багато, так що це правильно. Як ви рахуєте?
ბიმო

2

Perl 5, 40 байт

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

Запускається без параметрів командного рядка, тригер витягується натисканням Enter.


2

Пітон, 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*")))

Не дуже конкурентоспроможний, але мені подобаються круглі списки:

(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 байти

42 байти + -pваріант командного рядка. Просто натисніть enterдля запуску.

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

Дякуємо Дому Гастінгсу за допомогу! Оригінальна відповідь становила 67 байт:

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

Власне проблема -pполягала в тому, що він вийде, перш ніж викликати останню printзаяву, не знаючи чому. Я спробував це. Крім цього, дивовижні пропозиції, дякую! Мої знання продовжують зростати ...
Codefun64

@DomHastings Також, на жаль, чомусь 0|трюк не спрацював так, як очікувалося, але я збрив деякі байти від нього, друковану заяву та останню заяву, як ви запропонували. Як це виглядає зараз?
Codefun64

@DomHastings Чорт, ти хороший. Я рекомендую поставити це як свою власну відповідь, оскільки ви напевно написали меншу програму, ніж я (у вас на 40 байт порівняно з моїми оригінальними 67!)
Codefun64

Я ціную пояснення! Завжди раді дізнатись більше моєї улюбленої мови сценаріїв! Я ніколи навіть не знав про збільшення префексу, це досить приголомшливо. Дякую :)
Codefun64

Ви дуже раді, раді допомогти!
Дом Гастінгс

1

MATL , 41 байт

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

Щоб натиснути на тригер, введіть не порожній рядок (наприклад, 'try').

Для завершення введіть порожній рядок

Приклади

У цьому випадку тригер був натиснений один раз і ... невдача:

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

У цьому випадку користувач зупинився (зверніть увагу на остаточний порожній ввід) після двох щасливих витяг:

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

Пояснення

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 байти

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

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

Натисніть клавішу Enter, щоб тягнути курок, або ctrl + c, щоб натиснути його.


1

Python 2, 88 84 байт

Це рішення надихається вже даними рішеннями python 3. Я вибрав python 2 для видалення дужок друку, навіть якщо це змінює поведінку input ().

import time
for i in[0]*int(time.time()%6)+[1]:input();print("*click*","*BANG!*")[i]
  • Я використовую модуль часу як випадкову функцію (досить добре для російської рулетки)
  • введення гравця має бути "i", тоді Enter (інакше input () видасть помилку), ця хитрість покладається на те, що вхід може бути "будь-яким".

1

Рубі, 45 + 1 = 46

Не такий розумний, як на стороні D, але трохи коротший.

З прапором командного рядка pзапустіть

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

Користувач може витягнути спусковий гачок із поверненням та вийти з керуванням-c. pзмушує програму працювати в циклі, читаючи рядки з STDIN і виводити $_. Кожен раз, коли він працює, він збільшується $.. Тож під час першого запуску він вибирає випадкове додатне ціле число менше 6, потім 5, потім 4 тощо. На першому 0 ми виводимо вручну та виходимо, до цього часу виводимо неявно.

(і тепер я помічаю, що вже є дуже схожий Perl. Ну добре.)


1

Perl 5, 69 51 49 байт

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

Напевно, є ще якийсь потенціал для гольфу, я розберуся в цьому.

Зміни:

  • Збережено 8 байтів, видаливши $lі деякі крапки з комою, і 10 байт, змінивши <STDIN>на<>
  • Збережено 2 байти завдяки Олегу В. Волкову

1
49:map{<>;print"*click*"}1..rand 6;<>;print"*BANG!*"
Волков Олег Вікторович

@ Олег В.Волков Дякую! Я зараз її відредагую.
ASCIIThenANSI

0

VBA, 126 байт

Версія для гольфу на мінімальних байтах

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

Весела версія, яка робить кнопки більш чіткими для збільшення прийнятності користувачів.

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

Деяка забава зі спеціальними формами, і ви можете зробити досить гладку гру в VBA.


0

APL, 39/65 байт

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

Досить відверта відповідь.


Що означають два байти?
Mego

0

C, 180 байт

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

Моя перша спроба кодового гольфу, можливо, є багато місця для вдосконалення :)


0

Джулія, 71 байт

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

Натисніть, Enterщоб стріляти або Ctrl+, Cщоб вийти. Останній закінчується ан InterruptException.

Безголівки:

# 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.