Expand a random range from 1–5 to 1–7

前端 未结 30 2836
一个人的身影
一个人的身影 2020-11-22 07:29

Given a function which produces a random integer in the range 1 to 5, write a function which produces a random integer in the range 1 to 7.

  1. What is a simple so
30条回答
  •  长发绾君心
    2020-11-22 08:24

    Here's my answer:

    static struct rand_buffer {
      unsigned v, count;
    } buf2, buf3;
    
    void push (struct rand_buffer *buf, unsigned n, unsigned v)
    {
      buf->v = buf->v * n + v;
      ++buf->count;
    }
    
    #define PUSH(n, v)  push (&buf##n, n, v)
    
    int rand16 (void)
    {
      int v = buf2.v & 0xf;
      buf2.v >>= 4;
      buf2.count -= 4;
      return v;
    }
    
    int rand9 (void)
    {
      int v = buf3.v % 9;
      buf3.v /= 9;
      buf3.count -= 2;
      return v;
    }
    
    int rand7 (void)
    {
      if (buf3.count >= 2) {
        int v = rand9 ();
    
        if (v < 7)
          return v % 7 + 1;
    
        PUSH (2, v - 7);
      }
    
      for (;;) {
        if (buf2.count >= 4) {
          int v = rand16 ();
    
          if (v < 14) {
            PUSH (2, v / 7);
            return v % 7 + 1;
          }
    
          PUSH (2, v - 14);
        }
    
        // Get a number between 0 & 25
        int v = 5 * (rand5 () - 1) + rand5 () - 1;
    
        if (v < 21) {
          PUSH (3, v / 7);
          return v % 7 + 1;
        }
    
        v -= 21;
        PUSH (2, v & 1);
        PUSH (2, v >> 1);
      }
    }
    

    It's a little more complicated than others, but I believe it minimises the calls to rand5. As with other solutions, there's a small probability that it could loop for a long time.

提交回复
热议问题