แก้ไขฟังก์ชั่นการสุ่มที่ผิดปกติ


18

เพื่อนมีการ์ดเสริมในคอมพิวเตอร์ของพวกเขาซึ่งสร้างหมายเลขสุ่มอย่างสมบูรณ์แบบตั้งแต่ 1 ถึง 5 รวม โชคไม่ดีที่พวกมันหกโคล่าลงบนมันและตอนนี้มันสร้างเพียง 2 ตัวสำหรับตัวเลขทั้งหมดจาก 1 ถึง 4 โชคดีที่การสุ่มนั้นถูกเก็บรักษาไว้ แต่ 2 มีความน่าจะเป็น 80% และ 5 มีความน่าจะเป็น 20% และไม่มี 1's, 3's หรือ 4's สร้างแล้ว ใช้แหล่งที่มาแบบสุ่มนี้ (เรียกมันว่าBrokenRand()หรือสิ่งที่คล้ายกัน) เขียนตัวสร้างตัวเลขสุ่มที่ใช้งานได้ซึ่งสร้างตัวเลขตั้งแต่ 1 ถึง 5 โดยมีความน่าจะเป็น 20% เท่ากันกับการสุ่มสมบูรณ์แบบเช่นเดียวกับต้นฉบับ

โปรแกรมที่สั้นที่สุดชนะ คะแนนโบนัสที่มอบให้สำหรับจำนวนการโทรขั้นต่ำBrokenRandอย่างเป็นกลางโดยการให้คำปรึกษาโดยมุ่งเน้นด้านการบริการลูกค้าที่คัดสรรโดยกลุ่มคนโดยแยกตามอายุและเพศ - เช่นฉัน

คำตอบ:


10

JavaScript - 69 ตัวอักษร

สิ่งนี้ใช้เครื่องมือระบาย von Neumannเพื่อสร้างบิตที่ไม่เอนเอียง ขั้นตอนวิธีการทั่วไปนอกจากนี้ยังมีการอธิบายไว้ในเว็บไซต์ HotBits สามบิตใช้เพื่อจัดรูปแบบตัวเลขจาก 0 ถึง 7 หมายเลขทั้งหมด 5 ขึ้นไปจะถูกยกเลิกและ 1 จะถูกเพิ่มลงในแต่ละส่วนที่เหลือก่อนที่จะพิมพ์ ฉันทำแบบจำลองแสดงให้เห็นว่านี้ไม่ได้ลำเอียงอย่างหนัก

คุณต้องจัดเตรียมฟังก์ชั่นของคุณเองr()เพื่อเข้าถึง RNG

 for(;;v<5&&alert(v+1))for(v=i=0;i<3;a-b&&(v*=2,v+=a<b,i++))b=r(a=r())

มันทำได้ดีมากจริงๆ! ฉันชอบวิธีการลัดวงจรค่าที่เพิ่ม
snmcdonald

คุณสามารถสร้าง 7 บิตและดึงหมายเลขสุ่ม 3 หมายเลขเพื่อลดการเรียกไปยัง BrokenRand แต่น่าจะมีค่าใช้จ่ายเพิ่มขึ้นอีกสองสามครั้ง
gnibbler

5

สกาล่า 79 ตัวอักษร:

// preparation: 
val r = util.Random 
def defektRNG = if (r.nextInt (5) == 0) 5 else 2 

(1 to 20).foreach (_ => print (" " + defektRNG))
// first impression:
// 2 2 2 2 2 2 2 5 2 2 5 2 2 2 5 2 2 2 2 2

def rnd : Int = { val k = (1 to 5).map (_ => defektRNG)
  if (k.sum == 13) k.findIndexOf (_ == 5) + 1 else rnd } 

// first impression:
(1 to 20).foreach (_ => print (" " + rnd))             
// 3 3 2 3 5 2 2 5 1 1 3 4 3 2 5 3 3 1 5 4
// control:
(1 to 50000).map (_ => rnd).groupBy (identity) .map (_._2.length) 
// scala.collection.immutable.Iterable[Int] = List(10151, 9997, 9971, 9955, 9926)

ตอนนี้สำหรับสนามกอล์ฟตัวจริง defektRNG นามแฝงที่แตกหัก Rand ถูกเปลี่ยนชื่อเป็น b

def r:Int={val k=(1 to 5).map(_=>b)
if(k.sum==13)k.findIndexOf(_==5)+1 else r} 

มันทำงานอย่างไร: บ่อยครั้งที่ b ส่งคืนลำดับ 2s แต่ถ้าคุณโทรไป 5 ครั้งคุณจะจบด้วย 4x2 และ 1x5 เป็นเหตุการณ์ที่เป็นไปได้มากที่สุดอันดับที่สองและสามารถเป็น 5-2-2-2-2, 2-5-2-2 -2, 2-2-5-2-2, 2-2-2-5-2 และ 2-2-2-2-5

สิ่งเหล่านี้มีเหมือนกันว่าผลรวมคือ 4 * 2 + 5 = 13 ดัชนีห้าตัวแรกสามารถใช้เพื่อกำหนดหมายเลขสุ่มที่ถูกต้อง หากมีมากกว่าหรือน้อยกว่าหนึ่ง 5 ให้ผลรวมมากกว่าหรือต่ำกว่า 13 ทำซ้ำ

ตัวนับใน 'rnd' aka 'r' สามารถแสดงจำนวนการโทรที่จำเป็นโดยเฉลี่ยในการสร้างตัวเลข มีการโทรไปยังหมายเลข 121 200 หมายเลขสำหรับสุ่ม 50000 หมายเลขซึ่งไม่น่าประทับใจ :)


3

> <> (ปลา) - 55 ไบต์

อัปเดตเพื่อใช้อัลกอริทึมเดียวกับ @user ที่ไม่รู้จักในคำตอบแบบสกาล่าของเขา

<? v = + d &: I & + &: I & + &: I & + &: I &: ฉัน
 0
 > 1 + $ 5 (vnao;
 ^ <

คาดว่าเครื่องกำเนิดที่ชำรุดจะเชื่อมต่อกับ stdin; นี่คือฉันสคริปต์หลามใช้ รหัสตรงกับข้อมูลจำเพาะของปลาในปัจจุบัน แต่ผมใช้รุ่นที่แก้ไขของล่ามเก่า

bash:$ for i in $(seq 1000); do ./bad_rand.py | ./myfish.py rand.fish; done >res.txt
bash:$ for i in $(seq 5); do echo -n "$i : "; grep -c $i res.txt; done
1 : 193
2 : 204
3 : 198
4 : 206
5 : 199

ฉันจะทำตัวอย่างที่ใหญ่กว่า แต่มันช้า


2

GolfScript ขนาด 23 ไบต์

คำตอบที่ล่าช้า แต่เนื่องจากสิ่งนี้เพิ่งจะปรากฏขึ้นในหน้าแรก ...

0{;[{r}5*].5?)\5-,4-}do

ใช้วิธีเดียวกับการแก้ปัญหา Scala ผู้ใช้ไม่รู้จัก สันนิษฐานว่าสร้างตัวเลขสุ่มลำเอียงจะได้รับเป็น subroutine GolfScript ชื่อr; คุณสามารถกำหนด RNG แบบเอนเอียงที่เหมาะสมได้ด้วยตัวคุณเองเช่น:

{5rand!3*2+}:r;

นี่คือการทดสอบอย่างรวดเร็วที่แสดงให้เห็นถึงการขาดอคติ น่าเสียดายที่เซิร์ฟเวอร์ GolfScript ออนไลน์นั้นช้าดังนั้นฉันต้องตัดการสาธิตให้เหลือเพียง 100 ตัวอย่างเพื่อให้เสร็จตรงเวลา ถ้าวิ่งทดสอบในประเทศกับล่าม GolfScriptลองเพิ่ม100*ไปหรือแม้กระทั่ง1000*10000*

(เซิร์ฟเวอร์ GolfScript บางครั้งก็สุ่มค้างและหมดเวลาอยู่ดีถ้าเกิดเหตุการณ์นี้ให้คุณลองแก้ไขอีกครั้งโดยปกติมันเกิดขึ้นกับรหัสอื่นด้วยและเกิดขึ้นบนเซิร์ฟเวอร์ไม่ใช่ในคอมพิวเตอร์ของตัวเองดังนั้นฉันจึงมั่นใจ ว่าเป็นปัญหากับเซิร์ฟเวอร์ไม่ใช่กับรหัสของฉัน)


-1

javascript, 160 ตัวอักษรโดยไม่ลดความสามารถในการอ่าน การเพิ่มประสิทธิภาพ aka

function giveRandom(){
    var result = Math.floor(5 * Math.random()) + 1;
    while(BrockenRand() != 5){
        result = Math.floor(5 * Math.random()) + 1;
    }
    return result;
}

@ snmcdonald - บางส่วนนั้นไม่ใช่ตัวพิมพ์ผิดมันเป็นวิธีในการปรับปรุง js random โดยตัวกำเนิดการสุ่มที่สมบูรณ์แบบที่อนุมัติเท่านั้น (สุ่มทั้งหมด!) 20% ผลลัพธ์
www0z0k

สนใจอธิบายว่าBrockenBand()คืออะไร
Mateen Ulhaq

6
ฉันคิดว่าคุณพลาดจุด
cthom06

@muntoo - ความหมายBrockenRand
www0z0k

บันทึกสองสามไบต์ด้วยวิธีนี้:function giveRandom(){return Math.ceil(Math.random()*5)}
user300375
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.