เรียกใช้ปัญหา 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. สิ้นสุด progam

กฎ:

  1. เมื่อคุณต้องเลือกสุ่มเลือกไม่ต้องกังวลเกี่ยวกับการสุ่มเข้ารหัส rand()ฟังก์ชั่นใด ๆ ที่จะทำ
  2. โปรแกรมจะต้องไม่โกง รางวัลจะต้องอยู่ในสถานที่ก่อนที่เกมจะเริ่ม กล่าวคือต้องทำตามขั้นตอนตามลำดับที่กำหนดไว้: อันดับแรกเลือกประตูที่จะซ่อนรางวัลของคุณจากนั้นให้ผู้เล่นเลือก ตัวเลือกของประตูที่จะเปิดในขั้นตอนที่ 4 จะต้องเกิดขึ้นในขั้นตอนที่ 4: ไม่ได้เลือกล่วงหน้า
  3. ผลลัพธ์ในขั้นตอนที่ 6 ต้องซื่อสัตย์
  4. นี่คือรหัสกอล์ฟ รหัสที่สั้นที่สุดชนะ

ครั้งแรกที่ฉันโพสต์บนเว็บไซต์นี้ แต่ฉันแฝงตัวมากดังนั้นฉันคิดว่าฉันคุ้นเคยกับบรรทัดฐานของคุณ
TRiG

บน meta.codegolf.stackexchange.com มีหัวข้อสำหรับเสนอคำถามและให้ผู้คนแก้ไขปัญหาใด ๆ ก่อนที่จะโพสต์อย่างเป็นทางการ ฉันไม่รู้ว่ามีอะไรผิดปกติที่นี่ที่อาจถูกรีดออกมาหรือเปล่า แต่มันอาจเป็นการดีที่คุณจะรู้ในครั้งต่อไป
undergroundmonorail

ฉันกำลังดูตัวอย่างว่าผู้ชนะจะเป็นเพียงอีกหนึ่งคำตอบ golfscript ...
วิคเตอร์ Stafusa

1
BTW "การประดิษฐ์" ไม่เป็นไปด้วยดีกับ codegolfing เนื่องจากการประดิษฐ์นั้นใช้เนื้อที่จำนวนหนึ่งไบต์และวัตถุประสงค์ของ codegolfing นั้นตรงกันข้ามกับสิ่งนี้
Victor Stafusa

ใช่ @Victor การเป็นนักประดิษฐ์ไม่ใช่ข้อกำหนด ฉันแค่ (ก) ไม่ต้องการ จำกัด สิ่งนี้ในโปรแกรมบรรทัดคำสั่งและ (b) ไม่รู้ว่าโปรแกรมที่ไม่ใช่บรรทัดคำสั่งควรใช้การเลือกผู้ใช้อย่างไร ดังนั้นฉันจึงทิ้งมันไว้กับผู้ตอบคำถาม การประดิษฐ์เป็นตัวเลือก แต่เป็นสิ่งหนึ่งที่จะไม่เก็บคะแนนพิเศษ
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

ขอบคุณนั่นเป็นตัวพิมพ์ข้อผิดพลาดสุดท้ายที่ฉันแก้ไขก่อนโพสต์
Tobia

2

Python, 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 ตัวละครการสลับการตอบสนองการชนะ / แพ้ในคำสั่งสุดท้ายถ้า / else อนุญาตให้ฉันใช้แบบโมดูโลที่นั่น

รหัส Golfed

$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 ขอบคุณสำหรับสิ่งนั้น แม้ว่ามันจะไม่ยากที่จะนำไปใช้ แต่มันก็เพิ่มบิตของการขยายตัว
Iszi

และเทคนิคต่าง ๆ (การตรวจจับ w หรือการนับตัวอักษร ) ของคุณนั้นสนุกกว่าเดิม
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')

ซอ: http://jsfiddle.net/acbabis/9J2kP/

แก้ไข:ขอบคุณเดฟ


คุณสามารถย่อให้เหลือ 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

@dave นั่นเป็นประโยชน์ ฉันไม่คิดว่าจะใช้ผู้ประกอบการที่นี่ อย่างไรก็ตามฉันไม่สามารถผ่าน Date.now () ได้เพราะตัวเลขสุ่มต้องเป็นอิสระ อย่างไรก็ตามฉันสามารถส่ง Date.now ได้
aebabis

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

@Timtech date.nowผ่านฟังก์ชั่นที่date.now()ผ่านผลของการทำงาน
dave

@ บันทึกโอ้ฉันเข้าใจแล้ว ขอบคุณ :)
Timtech

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.