Random integers c++ - c++

I'm trying to produce random integers (uniformly distributed).
I found this snippet on an other forum but it works in a very weird way..
srand(time(NULL));
AB=rand() % 10+1;
Using this method I get values in a cycle so the value increases with every call until it goes down again. I guess this has something to do with using the time as aninitializer?
Something like this comes out.
1 3 5 6 9 1 4 5 7 8 1 2 4 6 7.
I would however like to get totally random numbers like
1 9 1 3 8 2 1 7 6 7 5...
Thanks for any help

You should call srand() only once per program.

Also check out the Boost Random Number Library:
Boost Random Number Library

srand() has to be done once per execution, not once for each rand() call,
some random number generators have a problem with using "low digit", and there is a bias
if you don't drop some number, a possible work around for both issues:
int alea(int n){
assert (0 < n && n <= RAND_MAX);
int partSize =
n == RAND_MAX ? 1 : 1 + (RAND_MAX-n)/(n+1);
int maxUsefull = partSize * n + (partSize-1);
int draw;
do {
draw = rand();
} while (draw > maxUsefull);
return draw/partSize;
}

You can use the the Park-Miller "minimal standard" Linear Congruential Generator (LCG): (seed * 16807 mod(2^31 - 1)). My implementation is here
Random integers with g++ 4.4.5
The C language 'srand()' function is used to set the global variable that 'rand()' uses. When you need a single sequence of random numbers, 'rand()' is more than enough, but oftentimes you need several random number generators. For those cases, my advice would be to use C++ and a class like 'rand31pmc'.
If you want to generate random numbers in a small range, then you can use the Java library implementation available here:
http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt%28int%29

Related

std::mersenne_twister_engine and random number generation

What is the distribution (uniform, poisson, normal, etc.) that is generated if I did the below? The output appears to indicate a uniform distribution. But then, why do we need std::uniform_int_distribution?
int main()
{
std::mt19937_64 generator(134);
std::map<int, int> freq;
const int size = 100000;
for (int i = 0; i < size; ++i) {
int r = generator() % size;
freq[r]++;
}
for (auto f : freq) {
std::cout << std::string(f.second, '*') << std::endl;
}
return 0;
}
Thanks!
Because while generator() is an uniform distribution over [generator.min(), generator.max()], generator() % n is not a uniform distribution over [0, n) (unless generator.max() is an exact multiple of n, assuming generator.min() == 0).
Let's take an example: min() == 0, max() == 65'535 and n == 7.
gen() will give numbers in the range [0, 65'535] and in this range there are:
9'363 numbers such that gen() % 7 == 0
9'363 numbers such that gen() % 7 == 1
9'362 numbers such that gen() % 7 == 2
9'362 numbers such that gen() % 7 == 3
9'362 numbers such that gen() % 7 == 4
9'362 numbers such that gen() % 7 == 5
9'362 numbers such that gen() % 7 == 6
If you are wondering where did I get these numbers think of it like this: 65'534 is an exact multiple of 7 (65'534 = 7 * 9'362). This means that in [0, 65'533] there are exactly 9'362 numbers who map to each of the {0, 1, 2, 3, 4, 5, 6} by doing gen() % 7. This leaves 65'534 who maps to 0 and 65'535 who maps to 1
So you see there is a bias towards [0, 1] than to [2, 6], i.e.
0 and 1 have a slightly higher chance (9'363 / 65'536 ≈ 14.28680419921875 %)‬ of appearing than
2, 3, 4, 5 and 6 (9'362 / 65'536 ≈ 14.2852783203125‬ %).
std::uniformn_distribution doesn't have this problem and uses some mathematical woodo with possibly getting more random numbers from the generator to achieve a truly uniform distribution.
The random engine std::mt19937_64 outputs a 64-bit number that behaves like a uniformly distributed random number. Each of the C++ random engines (including those of the std::mersenne_twister_engine family) outputs a uniformly-distributed pseudorandom number of a specific size using a specific algorithm.
Specifically, std::mersenne_twister_engine meets the RandomNumberEngine requirement, which in turn meets the UniformRandomBitGenerator requirement; therefore, std::mersenne_twister_engine outputs bits that behave like uniformly-distributed random bits.
On the other hand, std::uniform_int_distribution is useful for transforming numbers from random engines into random integers of a user-defined range (say, from 0 through 10). But note that uniform_int_distribution and other distributions (unlike random number engines) can be implemented differently from one C++ standard library implementation to another.
std::mt19937_64 generates a pseudo-random mutually independent sequence of long long / unsigned long long numbers. It is supposed to be uniform but I don't know the exact details of the engine, though, it is one of the best discovered engines thus far.
By taking % n you get an approximation to pseudo-random uniform distribution over integers [0, ... ,n] - but it is inherently inaccurate. Certain numbers have slightly higher chance to occur while others have slightly lower chance depending on n. E.g., since 2^64 = 18446744073709551616 so with n=10000 first 1616 values have a slightly higher chance to occur than the last 10000-1616 values. std::uniform_distribution takes care of the inaccuracy by taking a new random number in very rare cases: say, if the number is above 18446744073709550000 for n=10000 take a new number - it would work. Though, concrete details are up to implementation.
One of the major accomplishments of <random> was the separation of distributions from engines.
I see it as similar to Alexander Stepanov's STL, which separated algorithms from containers through the use of iterators. For random numbers I can do an implementation of the Blum-Blum-Shub single bit generator (engine) and it will still work with all the distributions in <random>. Or, I can do a simple Linear Congruential Generator, x_{n + 1} = a * x_{n} % m, which when correctly seeded can never generate 0. Again, it will work with all the distributions. Likewise, I can write a new distribution and I don't have to worry about the peculiarities of any engine as long as I only use the interface specified by a UniformRandomBitGenerator.
In general, you should always use a distribution. Also, it is time to retire using '%' for generating random numbers.

C++: How to generate a random number from an array [duplicate]

This question already has answers here:
How to get a random element from a C++ container?
(9 answers)
Closed 7 years ago.
I´ve an array which stores 5 inputs (int), in a guessing-game.
What I would like to do is to generate a random number (pick one of five numbers which is stored) from that array, can anyone help me with this?
I'm familliar with the rand-fuction but only to pick a random number within a range och numbers, not between 5 inputs...
Use e.g. std::uniform_int_distribution to get a value between 0 and 4 (inclusive) and use that as an index into the array.
Assuming your array object is int arr[5] then you can use one of the following ways depending on C++ version you are using.
All versions of C++:
int random_number = arr[rand() % 5];
Keep in mind that this solution suffers from bias issues. If you want to achive good distribution of generated numbers with this way then read following answer to the same question: https://stackoverflow.com/a/6943003/1289981
Since C++11 (most correct way):
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> uniform_dist(0, 4);
int random_number = arr[uniform_dist(e1)];
Simply use a random number generator to generate a number from 0,1,2,3,4 and use that number as index in your array, obviously.
rand is something that we typically discourage people from using, as it's not thread-safe. However, in your simple case, it should work.
You can simply generate a random number x from 0 to length of an array - 1, and then pick the x-th number from it.
Something like this:
int x = rand() % 5;
cout << inputs[x]; // here is your value
This sounds like course work so without giving you the answer directly, the logic you need to follow is-
Generate a random number that is the in the range of your input array:
0 to ( [number of inputs] - 1 )
in your case that would be 0 to 4.
Make sure to store the random number into a variable e.g. a variable called randonInput
Then you select from the array using the number generated, i.e:
int randomInput = inputArray[randomNumber];
Then you will have the random input stored in the randomInput variable

Fastest way to find the sum of decimal digits

What is the fastest way to find the sum of decimal digits?
The following code is what I wrote but it is very very slow for range 1 to 1000000000000000000
long long sum_of_digits(long long input) {
long long total = 0;
while (input != 0) {
total += input % 10;
input /= 10;
}
return total;
}
int main ( int argc, char** argv) {
for ( long long i = 1L; i <= 1000000000000000000L; i++) {
sum_of_digits(i);
}
return 0;
}
I'm assuming what you are trying to do is along the lines of
#include <iostream>
const long long limit = 1000000000000000000LL;
int main () {
long long grand_total = 0;
for (long long ii = 1; ii <= limit; ++ii) {
grand_total += sum_of_digits(i);
}
std::cout << "Grand total = " << grand_total << "\n";
return 0;
}
This won't work for two reasons:
It will take a long long time.
It will overflow.
To deal with the overflow problem, you will either have to put a bound on your upper limit or use some bignum package. I'll leave solving that problem up to you.
To deal with the computational burden you need to get creative. If you know the upper limit is limited to powers of 10 this is fairly easy. If the upper limit can be some arbitrary number you will have to get a bit more creative.
First look at the problem of computing the sum of digits of all integers from 0 to 10n-1 (e.g., 0 to 9 (n=1), 0 to 99 (n=2), etc.) Denote the sum of digits of all integers from 10n-1 as Sn. For n=1 (0 to 9), this is just 0+1+2+3+4+5+6+7+8+9=45 (9*10/2). Thus S1=45.
For n=2 (0 to 99), you are summing 0-9 ten times and you are summing 0-9 ten times again. For n=3 (0 to 999), you are summing 0-99 ten times and you are summing 0-9 100 times. For n=4 (0 to 9999), you are summing 0-999 ten times and you are summing 0-9 1000 times. In general, Sn=10Sn-1+10n-1S1 as a recursive expression. This simplifies to Sn=(9n10n)/2.
If the upper limit is of the form 10n, the solution is the above Sn plus one more for the number 1000...000. If the upper limit is an arbitrary number you will need to get creative once again. Think along the lines that went into developing the formula for Sn.
You can break this down recursively. The sum of the digits of an 18-digit number are the sums of the first 9 digits plus the last 9 digits. Likewise the sum of the digits of a 9-bit number will be the sum of the first 4 or 5 digits plus the sum of the last 5 or 4 digits. Naturally you can special-case when the value is 0.
Reading your edit: computing that function in a loop for i between 1 and 1000000000000000000 takes a long time. This is a no brainer.
1000000000000000000 is one billion billion. Your processor will be able to do at best billions of operations per second. Even with a nonexistant 4-5 Ghz processor, and assuming best case it compiles down to an add, a mod, a div, and a compare jump, you could only do 1 billion iterations per second, meaning it will take on the order of 1 billion seconds.
You probably don't want to do it in a bruteforce way. This seems to be more of a logical thinking question.
Note - 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = N(N+1)/2 = 45.
---- Changing the answer to make it clearer after David's comment
See David's answer - I had it wrong
Quite late to the party, but anyways, here is my solution. Sorry it's in Python and not C++, but it should be relatively easy to translate. And because this is primarily an algorithm problem, I hope that's ok.
As for the overflow problem, the only thing that comes to mind is to use arrays of digits instead of actual numbers. Given this algorithm I hope it won't affect performance too much.
https://gist.github.com/frnhr/7608873
It uses these three recursions I found by looking and poking at the problem. Rather then trying to come up with some general and arcane equations, here are three examples. A general case should be easily visible from those.
relation 1
Reduces function calls with arbitrary argument to several recursive calls with more predictable arguments for use in relations 2 and 3.
foo(3456) == foo(3000)
+ foo(400) + 400 * (3)
+ foo(50) + 50 * (3 + 4)
+ foo(6) + 6 * (3 + 4 + 5)
relation 2
Reduce calls with an argument in the form L*10^M (e.g: 30, 7000, 900000) to recursive call usable for relation 3. These triangular numbers popped in quite uninvited (but welcome) :)
triangular_numbers = [0, 1, 3, 6, 10, 15, 21, 28, 36] # 0 not used
foo(3000) == 3 * foo(1000) + triangular_numbers[3 - 1] * 1000
Only useful if L > 1. It holds true for L = 1 but is trivial. In that case, go directly to relation 3.
relation 3
Recursively reduce calls with argument in format 1*10^M to a call with argument that's divided by 10.
foo(1000) == foo(100) * 10 + 44 * 100 + 100 - 9 # 44 and 9 are constants
Ultimately you only have to really calculate the sum or digits for numbers 0 to 10, and it turns out than only up to 3 of these calculations are needed. Everything else is taken care of with this recursion. I'm pretty sure it runs in O(logN) time. That's FAAST!!!!!11one
On my laptop it calculates the sum of digit sums for a given number with over 1300 digits in under 7 seconds! Your test (1000000000000000000) gets calculated in 0.000112057 seconds!
I think you cannot do better than O(N) where N is the number of digits in the given number(which is not computationally expensive)
However if I understood your question correctly (the range) you want to output the sum of digits for a range of numbers. In that case, you can increment by one when you go from number0 to number9 and then decrease by 8.
You will need to cheat - look for mathematical patterns that let you short-cut your computations.
For example, do you really need to test that input != 0 every time? Does it matter if you add 0/10 several times? Since it won't matter, consider unrolling the loop.
Can you do the calculation in a larger base, eg, base 10^2, 10^3, etcetera, that might allow you to reduce the number of digits, which you'll then have to convert back to base 10? If this works, you'll be able to implement a cache more easily.
Consider looking at compiler intrinsics that let you give hints to the compiler for branch prediction.
Given that this is C++, consider implementing this using template metaprogramming.
Given that sum_of_digits is purely functional, consider caching the results.
Now, most of those suggestions will backfire - but the point I'm making is that if you have hit the limits of what your computer can do for a given algorithm, you do need to find a different solution.
This is probably an excellent starting point if you want to investigate this in detail: http://mathworld.wolfram.com/DigitSum.html
Possibility 1:
You could make it faster by feeding the result of one iteration of the loop into the next iteration.
For example, if i == 365, the result is 14. In the next loop, i == 366 -- 1 more than the previous result. The sum is also 1 more: 3 + 6 + 6 = 15.
Problems arise when there is a carry digit. If i == 99 (ie. result = 18), the next loop's result isn't 19, it's 1. You'll need extra code to detect this case.
Possibility 2:
While thinking though the above, it occurred to me that the sequence of results from sum_of_digits when graphed would resemble a sawtooth. With some analysis of the resulting graph (which I leave as an exercise for the reader), it may be possible to identify a method to allow direct calculation of the sum result.
However, as some others have pointed out: Even with the fastest possible implementation of sum_of_digits and the most optimised loop code, you can't possibly calculate 1000000000000000000 results in any useful timeframe, and certainly not in less than one second.
Edit: It seems you want the the sum of the actual digits such that: 12345 = 1+2+3+4+5 not the count of digits, nor the sum of all numbers 1 to 12345 (inclusive);
As such the fastest you can get is:
long long sum_of_digits(long long input) {
long long total = input % 10;
while ((input /= 10) != 0)
total += input % 10;
return total;
}
Which is still going to be slow when you're running enough iterations. Your requirement of 1,000,000,000,000,000,000L iterations is One Million, Million, Million. Given 100 Million takes around 10,000ms on my computer, one can expect that it will take 100ms per 1 million records, and you want to do that another million million times. There are only 86400 seconds in a day, so at best we can compute around 86,400 Million records per day. It would take one computer
Lets suppose your method could be performed in a single float operation (somehow), suppose you are using the K computer which is currently the fastest (Rmax) supercomputer at over 10 petaflops, if you do the math that is = 10,000 Million Million floating operations per second. This means that your 1 Million, Million, Million loop will take the world's fastest non-distributed supercomputer 100 seconds to compute the sums (IF it took 1 float operation to calculate, which it can't), so you will need to wait around for quite some time for computers to become 100 so much more powerful for your solution to be runable in under one second.
What ever you're trying to do, you're either trying to do an unsolvable problem in near real-time (eg: graphics calculation related) or you misunderstand the question / task that was given you, or you are expected to perform something faster than any (non-distributed) computer system can do.
If your task is actually to sum all the digits of a range as you show and then output them, the answer is not to improve the for loop. for example:
1 = 0
10 = 46
100 = 901
1000 = 13501
10000 = 180001
100000 = 2250001
1000000 = 27000001
10000000 = 315000001
100000000 = 3600000001
From this you could work out a formula to actually compute the total sum of all digits for all numbers from 1 to N. But it's not clear what you really want, beyond a much faster computer.
No the best, but simple:
int DigitSumRange(int a, int b) {
int s = 0;
for (; a <= b; a++)
for(c : to_string(a))
s += c-48;
return s;
}
A Python function is given below, which converts the number to a string and then to a list of digits and then finds the sum of these digits.
def SumDigits(n):
ns=list(str(n))
z=[int(d) for d in ns]
return(sum(z))
In C++ one of the fastest way can be using strings.
first of all get the input from users in a string. Then add each element of string after converting it into int. It can be done using -> (str[i] - '0').
#include<iostream>
#include<string>
using namespace std;
int main()
{ string str;
cin>>str;
long long int sum=0;
for(long long int i=0;i<str.length();i++){
sum = sum + (str[i]-'0');
}
cout<<sum;
}
The formula for finding the sum of the digits of numbers between 1 to N is:
(1 + N)*(N/2)
[http://mathforum.org/library/drmath/view/57919.html][1]
There is a class written in C# which supports a number with more than the supported max-limit of long.
You can find it here. [Oyster.Math][2]
Using this class, I have generated a block of code in c#, may be its of some help to you.
using Oyster.Math;
class Program
{
private static DateTime startDate;
static void Main(string[] args)
{
startDate = DateTime.Now;
Console.WriteLine("Finding Sum of digits from {0} to {1}", 1L, 1000000000000000000L);
sum_of_digits(1000000000000000000L);
Console.WriteLine("Time Taken for the process: {0},", DateTime.Now - startDate);
Console.ReadLine();
}
private static void sum_of_digits(long input)
{
var answer = IntX.Multiply(IntX.Parse(Convert.ToString(1 + input)), IntX.Parse(Convert.ToString(input / 2)), MultiplyMode.Classic);
Console.WriteLine("Sum: {0}", answer);
}
}
Please ignore this comment if it is not relevant for your context.
[1]: https://web.archive.org/web/20171225182632/http://mathforum.org/library/drmath/view/57919.html
[2]: https://web.archive.org/web/20171223050751/http://intx.codeplex.com/
If you want to find the sum for the range say 1 to N then simply do the following
long sum = N(N+1)/2;
it is the fastest way.

Will this give me proper random numbers based on these probabilities? C++

Code:
int random = (rand() % 7 + 1)
if (random == 1) { } // num 1
else if (random == 2) { } // num 2
else if (random == 3 || random == 4) { } // num 3
else if (random == 5 || random == 6) { } // num 4
else if (random == 7) { } // num 5
Basically I want each of these numbers with each of these probabilities:
1: 1/7
2: 1/7
3: 2/7
4: 2/7
5: 1/7
Will this code give me proper results? I.e. if this is run infinite times, will I get the proper frequencies? Is there a less-lengthy way of doing this?
Not, it's actually slightly off, due to the way rand() works. In particular, rand returns values in the range [0,RAND_MAX]. Hypothetically, assume RAND_MAX were ten. Then rand() would give 0…10, and they'd be mapped (by modulus) to:
0 → 0
1 → 1
2 → 2
3 → 3
4 → 4
5 → 5
6 → 6
7 → 0
8 → 1
9 → 2
10 → 3
Note how 0–3 are more common than 4–6; this is bias in your random number generation. (You're adding 1 as well, but that just shifts it over).
RAND_MAX of course isn't 10, but it's probably not a multiple of 7 (minus 1), either. Most likely its a power of two. So you'll have some bias.
I suggest using the Boost Random Number Library which can give you a random number generator that yields 1–7 without bias. Look also at bames53's answer using C++11, which is the right way to do this if your code only needs to target C++11 platforms.
Just another way:
float probs[5] = {1/7.0f, 1/7.0f, 2/7.0f, 2/7.0f, 1/7.0f};
float sum = 0;
for (int i = 0; i < 5; i++)
sum += probs[i]; /* edit */
int rand_M() {
float f = (rand()*sum)/RAND_MAX; /* edit */
for (int i = 0; i < 5; i++) {
if (f <= probs[i]) return i;
f -= probs[i];
}
return 4;
}
Assuming rand() is good then your code will work with only a very small bias to the lower X numbers, where X is RAND_MAX % 7. It's much more likely that you won't get the desired odds due to the quality of the implementation of rand(). If you find that to be the case then you'll want to use an alternative random number generator.
C++11 introduces the header <random> which includes several quality RNGs. Here's an example:
#include <random>
#include <functional>
auto rand = std::bind(std::uniform_int_distribution<int>(1,7),std::mt19937());
Given this, when you call rand() you will get a number from 1 to 7 each with equal probability. (And you can choose different engines if for different quality and speed characteristics.) You can then use this to implement the if-else conditions your example currently uses with std::rand(). However <random> allows you to do even better using one of their non-uniform distributions. In this case what you want is discrete_distribution. This distribution allows you to explicitly state the weights for each value from 0 to n.
// the random number generator
auto _rand = std::bind(std::discrete_distribution<int>{1./7.,1./7.,2./7.,2./7.,1./7.},std::mt19937());
// convert results of RNG from the range [0-4] to [1-5]
auto rand = [&_rand]() { return _rand() +1; };
int toohigh = RAND_MAX - RAND_MAX%7;
int random;
do {
random = rand();
while (random >= toohigh); //should happen ~0.03% of the time
static const int results[7] = {1, 2, 3, 3, 4, 4, 5};
random = results[random%7];
This should give numbers with a distribution as even as rand can handle, and without the big if switch.
Note this does have a theoretically possible infinite loop, but the statistical odds of it staying in the loop for even are minuscule. The odds of it staying in the loop twice is quite close to the odds of winning the California Super Lotto Jackpot. Even if every person on the planet got five random numbers, it probably wouldn't stay in the loop three times. (Assuming a perfect RNG.)
rand returns pseudo-random integral number:
Notice though that this modulo operation does not generate a truly
uniformly distributed random number in the span (since in most cases
lower numbers are slightly more likely), but it is generally a good
approximation for short spans.
Now, regarding the less-lengthy way, you can use switch-case construction, or a series of conditional operators ?: (which will make your code short and unreadable:).

C++ How I can get random value from 1 to 12? [duplicate]

This question already has answers here:
Generating a random integer from a range
(14 answers)
Closed 6 years ago.
How I can get in C++ random value from 1 to 12?
So I will have 3, or 6, or 11?
Use the following formula:
M + rand() / (RAND_MAX / (N - M + 1) + 1), M = 1, N = 12
and read up on this FAQ.
Edit: Most answers on this question do not take into account the fact that poor PRN generators (typically offered with the library function rand()) are not very random in the low order bits. Hence:
rand() % 12 + 1
is not good enough.
#include <iomanip>
#include <iostream>
#include <stdlib.h>
#include <time.h>
// initialize random seed
srand( time(NULL) );
// generate random number
int randomNumber = rand() % 12 + 1;
// output, as you seem to wan a '0'
cout << setfill ('0') << setw (2) << randomNumber;
to adress dirkgently's issue maybe something like that would be better?
// generate random number
int randomNumber = rand()>>4; // get rid of the first 4 bits
// get the value
randomNumer = randomNumer % 12 + 1;
edit after mre and dirkgently's comments
Is there some significance to the leading zero in this case? Do you intend for it to be octal, so the 12 is really 10 (in base 10)?
Getting a random number within a specified range is fairly straightforward:
int rand_lim(int limit) {
/* return a random number between 0 and limit inclusive.
*/
int divisor = RAND_MAX/(limit+1);
int retval;
do {
retval = rand() / divisor;
} while (retval > limit);
return retval;
}
(The while loop is to prevent skewed results -- some outputs happening more often than others). Skewed results are almost inevitable when/if you use division (or its remainder) directly.
If you want to print it out so even one-digit numbers show two digits (i.e. a leading 0), you can do something like:
std::cout << std::setw(2) << std::setprecision(2) << std::setfill('0') << number;
Edit: As to why this works, and why a while loop (or something similar) is needed, consider a really limited version of a generator that only produces numbers from, say, 0 to 9. Assume further that we want numbers in the range 0 to 2. We can basically arrange the numbers in a table:
0 1 2
3 4 5
6 7 8
9
Depending on our preference we could arrange the numbers in columns instead:
0 3 6
1 4 7
2 5 8
9
Either way, however, we end up with the one of the columns having one more number than any of the others. 10 divided by 3 will always have a remainder of 1, so no matter how we divide the numbers up, we're always going to have a remainder that makes one of the outputs more common than the others.
The basic idea of the code above is pretty simple: after getting a number and figuring where in a "table" like one above that number would land, it checks whether the number we've got is the "odd" one. If it is, another iteration of the loop is executed to obtain another number.
There are other ways this could be done. For example, you could start by computing the largest multiple of the range size that's still within the range of the random number generator, and repeatedly generate numbers until you get one smaller than that, then divide the number you receive to get it to the right range. In theory this could even be marginally more efficient (it avoids dividing the random number to get it into the right range until it gets a random number that it's going to use). In reality, the vast majority of the time, the loop will only execute one iteration anyway, so it makes very little difference what we execute inside or outside the loop.
You can do this, for example:
#include <cstdlib>
#include <cstdio>
#include <time.h>
int main(int argc, char **argv)
{
srand(time(0));
printf("Random number between 1 and 12: %d", (rand() % 12) + 1);
}
The srand function will seed the random number generator with the current time (in seconds) - that's the way it's usually done, but there are also more secure solutions.
rand() % 12 will give you a number between 0 and 11 (% is the modulus operator), so we add 1 here to get to your desired range of 1 to 12.
In order to print 01 02 03 and so on instead of 1 2 3, you can format the output:
printf("Random number between 01 and 12: %02d", (rand() % 12) + 1);
(rand() % 12 + 1).ToString("D2")