soom. กลับไปสุ่มต่อ

สุ่มยุติธรรมไหม

สั้น ๆ คือยุติธรรม ส่วนที่ยาวกว่าอยู่ด้านล่าง พร้อมตัวเลขให้คุณตรวจเองได้

ตัวสุ่มมาจากไหน

ผลทุกครั้งมาจาก crypto.getRandomValues ตัวสุ่มสำหรับงานเข้ารหัสที่เบราว์เซอร์มีให้ ซึ่งดึงความสุ่มจากระบบปฏิบัติการ รู้ผลครั้งก่อนทั้งหมดก็ยังทายครั้งถัดไปไม่ได้

soom ไม่ใช้ Math.random ตัดสินผล ตัวนั้นใช้แค่กับของประดับ เช่น ตัวอักษรที่กลิ้งบนป้ายพลิกระหว่างรอ หรือเสียงที่เพี้ยนนิด ๆ ให้ไม่น่าเบื่อ

แต่ละครั้งได้ตัวเลข 32 บิต คือจำนวนเต็มตั้งแต่ 0 ถึง 4,294,967,295 แล้วจึงแปลงเป็นตัวเลือกของคุณ ขั้นแปลงนี้แหละที่เว็บสุ่มส่วนใหญ่ทำพลาดโดยไม่รู้ตัว

ความลำเอียงจากการหารเอาเศษ

วิธีที่ง่ายที่สุดคือเอาเลขสุ่มไปหารด้วยจำนวนตัวเลือกแล้วใช้เศษ แต่ถ้าจำนวนเลขทั้งหมดหารด้วยจำนวนตัวเลือกไม่ลงตัว ตัวเลือกแรก ๆ จะได้เปรียบ เรียกว่า modulo bias

ย่อให้เห็นภาพ ถ้าตัวสุ่มให้เลข 0 ถึง 9 แค่สิบแบบ และคุณมี 3 ตัวเลือก เศษ 0 มาจาก 0, 3, 6, 9 สี่แบบ ส่วนเศษ 1 กับ 2 ได้แค่สามแบบ ตัวเลือกแรกจึงได้โอกาส 40% แทนที่จะเป็น 33.3%

กับเลข 32 บิตจริง ความต่างเล็กลงมาก แต่ไม่ใช่ศูนย์ และยิ่งรายการยาว ความต่างยิ่งมาก

soom แก้ยังไง

ใช้วิธีทิ้งแล้วสุ่มใหม่ (rejection sampling) หาจำนวนที่ใหญ่ที่สุดที่หารด้วยจำนวนตัวเลือกลงตัว ถ้าเลขที่สุ่มได้เกินจากนั้นก็ทิ้งแล้วสุ่มใหม่ เลขที่เหลือจึงแบ่งให้ทุกตัวเลือกได้เท่ากันพอดี

จากตัวอย่างเดิม ถ้าได้ 9 ก็ทิ้ง เหลือ 0 ถึง 8 ที่แบ่งให้สามตัวเลือกได้ตัวละสามแบบ ของจริงแทบไม่ต้องทิ้งเลย กับ 3 ตัวเลือกมีเลขที่ต้องทิ้งแค่ตัวเดียวจากกว่าสี่พันล้านตัว

// จำนวนเต็มตั้งแต่ 0 ถึง max - 1 โอกาสเท่ากันทุกตัว
function randInt(max) {
  const limit = Math.floor(2 ** 32 / max) * max;
  let x = random32();   // crypto.getRandomValues
  while (x >= limit) x = random32();
  return x % max;
}

เรียงลำดับ แบ่งทีม และสุ่มหลายอัน

  • เรียงลำดับใช้วิธี Fisher–Yates ที่หยิบทีละตำแหน่งจากตัวที่ยังเหลือ ทุกลำดับที่เป็นไปได้จึงมีโอกาสเท่ากัน ไม่ใช่แค่สลับไปมาไม่กี่ครั้ง
  • แบ่งทีมสลับรายชื่อด้วยวิธีเดียวกันก่อน แล้วแจกทีละคนวนไปทุกทีม ทีมจึงต่างกันไม่เกินหนึ่งคน และใครเป็นคนที่เกินมาก็สุ่มเหมือนกัน
  • สุ่มหลายอันพร้อมกันคือหยิบจากหัวรายการที่สลับแล้ว จึงไม่มีตัวไหนซ้ำ
  • คัดออกคือการเรียงลำดับทั้งรายการไว้ก่อน แล้วค่อยเฉลยทีละรอบ ตัวสุดท้ายที่เหลือคือผล

แอนิเมชันไม่ได้ตัดสิน

ผลถูกสุ่มเสร็จตั้งแต่คุณกดปุ่ม ก่อนวงล้อเริ่มหมุน ก่อนลูกบอลกลิ้ง และก่อนคุณขูดบัตร สิ่งที่เห็นบนจอคือการเฉลยผลที่มีอยู่แล้ว กดแรงหรือเขย่าแรงแค่ไหนก็ไม่เปลี่ยนอะไร

ไพ่คว่ำก็เหมือนกัน ไพ่ทุกใบถูกสุ่มมาก่อนคุณเลือก ใบที่คุณเปิดจึงมีโอกาสเท่ากับใบอื่น

ชุดสำเร็จรูปที่มีหลายสิบคำตอบ เครื่องจะวาดแค่บางช่องให้อ่านออก แต่คำตอบถูกสุ่มจากทั้งชุด รายการของคุณเองที่ยาวเกิน 12 ก็เช่นกัน วงล้อเว้นช่องว่างไว้ แต่ทุกรายการยังมีโอกาสเท่ากัน

ทำไมออกซ้ำติดกันได้

การสุ่มที่ยุติธรรมไม่จำผลครั้งก่อน โยนเหรียญแล้วออกหน้าเดิมห้าครั้งติดมีโอกาส 1 ใน 32 ถ้าโยนกันทั้งห้องก็มีคนเจอแน่

ถ้าเครื่องสุ่มไหนพยายามไม่ให้ออกซ้ำ เครื่องนั้นแหละที่ไม่สุ่ม

ใครเปลี่ยนผลได้บ้าง

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