Запустіть проблему Monty Hall


11

Вже виникло питання про моделювання проблеми Monty Hall . Цей інший. Користувач буде грати на Монті Холла проблеми. Ваша програма буде грати роль ведучого. Montybot, якщо вам подобається.

Ось такі кроки:

  1. Виберіть (випадковим чином), хто з трьох дверей ховає приз.
  2. Виведіть візуальний дисплей з трьох дверей. ABCЗробити це буде просто . Або три квадрати. Або що завгодно.
  3. Отримайте вхід, вибравши одну з дверей. Це може бути клацання миші на обраній двері, або введення однієї літери ( B) чи інше.
  4. Відкрийте ще одні двері. Ви не відчиняєте вибрані двері. Ви не відчиняєте двері, ховаючи головний приз. Це може означати, що у вас немає вибору, або це може означати, що у вас є вибір двох. Якщо у вас є вибір двох, виберіть один навмання. Візуально вкажіть, що двері відчинені і що за нею не заховано жодного призу. Для програмного введення / виводу на основі тексту це може бути таким же простим, як і вихід AB0, щоб показати, що двері Cбули відкриті. Не соромтеся бути більш винахідливими. Якщо ви робите програму GUI, ваш вибір дисплея залежить від вас.
  5. Прийняти дані від користувача. Користувач може ввести stickабо switch(або, для програми GUI, натиснути на кнопки або використати вибраний вхід чи будь-що інше). Якщо користувач вводить щось, крім stickабо switch, реалізація не визначена. Робити все, що ви хочете.
  6. Виведіть текст You won!або You lost.
  7. Припиніть прогаму.

Правила:

  1. Коли вам доведеться щось вибрати навмання , не хвилюйтесь про криптографічну випадковість. Будь-яка rand()функція буде виконуватись.
  2. Програма не повинна обманювати. Приз повинен бути на місці до початку гри. Тобто, кроки потрібно виконувати у вказаному порядку: Спочатку виберіть двері, за якими заховати свій приз, а потім попросіть гравця вибрати. Вибір дверей, які потрібно відкрити на кроці 4, має відбутися на кроці 4: вона не вибирається заздалегідь.
  3. Вихід на етапі 6 повинен бути чесним.
  4. Це код гольфу. Найкоротший код виграє.

Я вперше розміщую повідомлення на цьому сайті, але я дуже ховаюся, тому думаю, що я знайомий з вашими нормами.
TRiG

На meta.codegolf.stackexchange.com є нитка для пропозицій щодо питань та дозволу людям вирішувати будь-які проблеми з нею, перш ніж вона буде офіційно розміщена. Я не знаю, чи є щось конкретно не так, що можна було б випрасувати, але це може бути добре знати наступного разу.
підземниймонорельс

Я переглядаю, що переможець буде лише черговою відповідью на гольфскрипт ...
Віктор Стафуса

1
BTW, "бути винахідливим" не добре поєднується з кодовим гольфуванням, оскільки винахідництво споживає деякі байти, а мета кодового гольфу - протилежна цьому.
Віктор Стафуса

Так, @Victor. Бути винахідливим - це не вимога. Я просто (а) не хотів обмежувати це програмами командного рядка, і (б) не мав уявлення, як програма, яка не використовується в командному рядку, повинна здійснювати вибір користувача. Тож я залишив це відповідям. Винахідливість - це варіант, але це не те, що не отримає зайвих очок.
TRiG

Відповіді:


2

APL, 77

p←?3⋄d[e[?⍴e←(⍳3)~p,c←⍞⍳⍨⎕←d←3↑⎕A]]←'_'⋄⎕←d⋄⎕←'You','lost' 'won!'[(c=p)=5=⍴⍞]

Потреби ⎕IO←0. Тестували на Dyalog.

Пояснення

p←?3                       ⍝ p(rize) is a random number between 1 and 3
⎕←d←3↑⎕A                   ⍝ d(oors) is the string 'ABC'; output it
c←d⍳⍞                      ⍝ ask for one of the letters; c(hoice) is its position
o←e[?⍴e←(⍳3)~p,c]          ⍝ o(pen) is a random position except for p and c
d[o]←'_'                   ⍝ replace the o position in the d string with a '_'
⎕←d                        ⍝ output the modified d string
w←(c=p)=5=⍴⍞               ⍝ get choice, if it's stick (5 chars) and c=p, or neither, (w)in 
⎕←'You','lost' 'won!'[w]   ⍝ print the result

Приклади

      p←?3⋄d[e[?⍴e←(⍳3)~p,c←⍞⍳⍨⎕←d←3↑⎕A]]←'_'⋄⎕←d⋄⎕←'You','lost' 'won!'[(c=p)=5=⍴⍞]
ABC
A
AB_
stick
You lost 
      p←?3⋄d[e[?⍴e←(⍳3)~p,c←⍞⍳⍨⎕←d←3↑⎕A]]←'_'⋄⎕←d⋄⎕←'You','lost' 'won!'[(c=p)=5=⍴⍞]
ABC
A
AB_
stick
You won! 

Прекрасна! Але я думаю, що в джерелі є джерело, яке мутує в =поясненні.
TRiG

Дякую, це була помилка, остання помилка, яку я виправив перед публікацією.
Тобія

2

Пітона, 157

from random import*
C=choice
I=raw_input
p='\n> '
a='ABC'
g=C(a)
i=I(a+p)
print'You '+'lwoosnt!'[(i==g)^('w'in I(a.replace(C(list(set(a)-{g,i})),'_')+p))::2]

Приклад:

$ python monty.py
ABC
> A
AB_
> switch
You won!

2

PowerShell: 192 174

Зміни від оригіналу:

  • -8 символів Оскільки візуальне відображення дверей може бути "будь-яким", я зрозумів, що можу зберегти деякі символи (зокрема, апострофи, необхідні для визначення рядків), використовуючи цифри замість літер.
  • -8 Персонажі Спеціально вибираючи одноцифрові, прості номери для представлення дверей, я міг би використовувати коротший оператор модуля замість фактичного оператора порівняння, коли мені потрібно було відповідати дверям, щоб визначити можливий вибір господаря або заміну дверей гравця. ( Коротко пояснено тут. )
  • -2 Персонажі Поміняючи відповіді на виграш / програш у фіналі, якщо заява / інше дозволило мені також використовувати модульний трюк.

Кодекс для гольфу

$w=($d=3,5,7)|random;357;$p=read-host;-join$d-replace($h=$d|?{$_%$w-and$_%$p}|random),0;if((read-host)-match'w'){$p=$d|?{$_%$p-and$_%$h}}if($p%$w){'You lost'}else{'You won!'}

Код без гольфу з коментарями

# Set up an array of doors ($d), and choose one to be the winner ($w).
$w=($d=3,5,7)|random;

# Show doors.
357;

# Get input and save player's choice ($p).
$p=read-host;

# Join the doors into one string, replacing the host's choice ($h) with a zero, and display them again.
-join$d-replace
(
    # Host will randomly choose a door from those which are not evenly divisible by $w or $p.
    $h=$d|?{$_%$w-and$_%$p}|random
 ),0;

# Get input from player. If it contains a 'w', switch doors.
# While this is generally a sloppy way to distinguish 'switch' from 'stick', it is allowed by the rules.
# "If the user enters anything other than stick or switch, the implementation is undefined. Do whatever you want."
if((read-host)-match'w')
{
    # Player will switch doors to one which is not evenly divisible by the $h or the original $p.
    $p=$d|?{$_%$p-and$_%$h}
}

# Announce the result.
# If $p is not evenly divisible by $w, player has lost. Otherwise, they have won.
if($p%$w){'You lost'}else{'You won!'}

# Variables cleanup - not included in golfed code.
rv w,d,p,h

Мені подобається, якщо він містить хитрість 'w' .
TRiG

Між іншим, я спочатку казав, що якщо введенням було щось інше, ніж "палиця" або "перемикач", програма повинна припинитися, але я змінив свою думку перед публікацією.
TRiG

@TRiG Дякую за це. Хоча це було б не важко здійснити, це додало б трохи набряку.
Іссі

І різноманітні трюки (ваше виявлення чи підрахунок символів ) все-таки цікавіше.
TRiG

0

Javascript, 221 197

(function(q,r,s,t,u,v){f='ABC';d=[0,1,2];b=q()%3;a=r(f);d.splice(a,1);(a==b)?(r(f[d[q()%2]])==t)?s(u):s(v):(r(f[d[(d[0]==b)+0]])!=t)?s(u):s(v)})(Date.now,prompt,alert,'stick','You won!','You lost')

Він використовує два виклики до Date.now () для випадковості з підказкою між ними, щоб гарантувати затримку. Вхід користувача - це індекс на основі 0 (правило було сказано "що завгодно"). Наступне попередження говорить про те, які двері були відчинені. Ось трохи довша версія, яка дає відповідь перед тим, як користувач вибере, щоб переконатися, що вона не обманює:

(function(q,r,s,t,u,v){f='ABC';d=[0,1,2];b=q()%3;s('ans:'+b);a=r(f);d.splice(a,1);(a==b)?(r(f[d[q()%2]])==t)?s(u):s(v):(r(f[d[(d[0]==b)+0]])!=t)?s(u):s(v)})(Date.now,prompt,alert,'stick','You won!','You lost')

Fiddle: http://jsfiddle.net/acbabis/9J2kP/

EDIT: Дякую Дейв


Ви могли б скоротити його до 197: (function(q,r,s,t,u,v){f='ABC';d=[0,1,2];b=q%3;a=r(f);d.splice(a,1);(a==b)?((r(f[d[q%2]])==t)?s(u):s(v)):(r(f[d[(d[0]==b)+0]])!=t)?s(u):s(v)})(Date.now(),prompt,alert,'stick','You won!','You lost')
Дейва

@dave Це корисно. Я не думав використовувати тут термінального оператора. Я не можу передавати Date.now (), тому що випадкові числа повинні бути незалежними. Я можу, однак, передати Date.now.
аебабіс

@acbabis "I can't pass Date.now() ... I can, however, pass Date.now"???
Timtech

@Timtech date.nowпередає функцію, date.now()передає результат функції
Dave

@dave О, я розумію. Дякую :)
Timtech

0

PHP> = 5,4, 195 192

$r=[0,1,2];unset($r[$p=rand(0,2)]);$d='012';echo"$d\n";fscanf(STDIN,"%d",$c);unset($r[$c]);$d[array_rand($r)]='_';echo"$d\n",!fscanf(STDIN,"%s",$s),'You '.($s=='switch'^$c==$p?'won!':'lost.');

Вихід:

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