CJam, 16 14 13 ไบต์
0{Kmr(+esmr}g
สิ่งนี้จะทำงานเป็นเวลานานมากเนื่องจากใช้การประทับเวลาปัจจุบัน (ตามลำดับ 10 12 ) เพื่อพิจารณาว่าลูปควรยุติหรือไม่ ฉันใช้สิ่งนี้เป็นข้อเสนอเนื่องจากสั้นที่สุด แต่มีทางเลือก 14 ไบต์สองทางซึ่งมีข้อดีของตัวเอง:
0{esmr(+esmr}g
อันนี้ไม่ได้จำกัด ตามระยะเวลาของ PRNG ตั้งแต่ช่วงของทุกตัวเลขสุ่มขึ้นอยู่กับการประทับเวลาปัจจุบัน ดังนั้นสิ่งนี้ควรสร้างจำนวนเท่าใดก็ได้แม้ว่าความน่าจะเป็นที่จะเป็นลบหรือแม้แต่จำนวนบวกเล็ก ๆ ก็หายไปเล็กน้อย
ด้านล่างเป็นรุ่นที่เทียบเท่าที่ใช้3e5
แทนการประทับเวลา และ20
สำหรับช่วงแรก (เช่นการส่ง 13 ไบต์) มันเร็วกว่ามากและเป็นไปตามกฎทั้งหมด มันเป็นกรณีที่มีข้อ จำกัด ในการรับความน่าจะเป็น 50% สำหรับตัวเลขที่มากกว่า 1,000,000 ขณะที่ยังคงรันไทม์ที่เหมาะสมและมีขนาดรหัสเล็ก คำอธิบายและเหตุผลทางคณิตศาสตร์อ้างอิงถึงรุ่นนี้:
0{Kmr(+3e5mr}g
โดยปกติจะใช้เวลาสองสามวินาทีในการเรียกใช้ คุณสามารถแทนที่5
ด้วย a 2
เพื่อให้ทำงานได้เร็วขึ้น แต่จากนั้นความต้องการของความน่าจะเป็น 50% จะได้รับเพียง 1,000 แทนที่จะเป็น 1,000,000
ฉันเริ่มต้นที่ 0 จากนั้นฉันก็มีลูปที่ฉันมีความน่าจะเป็น 1 / (3 * 10 5 ) ภายในลูปนั้นฉันเพิ่มจำนวนเต็มแบบสุ่มระหว่าง -1 ถึง 18 (รวม) เพื่อผลรวมสะสมของฉัน มีความเป็นไปได้ที่ จำกัด (แม้ว่าจะเล็ก) ว่าจำนวนเต็มแต่ละค่าจะถูกส่งออกโดยที่จำนวนเต็มบวกจะมีโอกาสมากกว่าจำนวนลบ (ฉันไม่คิดว่าคุณจะเห็นค่าลบในช่วงชีวิตของคุณ) การแยกความน่าจะเป็นเล็ก ๆ น้อย ๆ ออกและการเพิ่มเวลาส่วนใหญ่ (และการบวกมากกว่าการลบ) ทำให้มั่นใจได้ว่าเราจะไปได้กว่า 1,000,000
0 "Push a 0.";
{ }g "Do while...";
Kmr "Get a random integer in 0..19.";
( "Decrement to give -1..18.";
+ "Add.";
3e5mr "Get a random integer in 0..299,999. Aborts if this is 0.";
การให้เหตุผลทางคณิตศาสตร์บางอย่าง:
- ในแต่ละขั้นตอนเราเพิ่ม 8.5 โดยเฉลี่ย
- ในการรับ 1,000,000 เราต้องการ 117,647 ขั้นตอนเหล่านี้
ความน่าจะเป็นที่เราจะทำน้อยกว่าจำนวนก้าวนี้คือ
sum(n=0..117,646) (299,999/300,000)^n * 1/300,000
ซึ่งประเมิน0.324402
ว่า ดังนั้นในประมาณสองในสามของกรณีเราจะใช้ขั้นตอนเพิ่มเติม 117,647 ขั้นและแต่ละ 1,000,000 อย่างง่ายดาย
- (โปรดทราบว่านี่ไม่ใช่ความน่าจะเป็นที่แน่นอนเนื่องจากจะมีความผันผวนของค่าเฉลี่ย 8.5 แต่เพื่อให้ได้ 50% เราต้องไปได้ดีกว่า 117,646 ถึงประมาณ 210,000 ขั้นตอน)
- หากมีข้อสงสัยเราสามารถทำให้ตัวหารของความน่าจะเป็นจุดสิ้นสุดสิ้นสุดลงได้อย่างง่ายดาย
9e9
โดยไม่ต้องเพิ่มไบต์ใด ๆ (แต่เป็นปีรันไทม์)
... หรือ 11 ไบต์?
ในที่สุดก็มีรุ่น 11 ไบต์ซึ่งไม่ จำกัด ด้วยระยะเวลาของ PRNG แต่จะมีหน่วยความจำไม่เพียงพอทุกครั้ง มันจะสร้างตัวเลขสุ่มเพียงหนึ่งหมายเลข (ขึ้นอยู่กับการประทับเวลา) แต่ละการวนซ้ำและใช้ทั้งการเพิ่มและการยกเลิก ผลลัพธ์จากการวนซ้ำแต่ละครั้งจะยังคงอยู่ในสแต็กและจะสรุปเฉพาะตอนท้ายเท่านั้น ขอบคุณเดนนิสสำหรับความคิดนี้:
{esmr(}h]:+