undefined behaviour of srand and rand - c

I am trying to generate random number using srand and rand. Here I want to generate specific number of digit. When I am executing my program at some time if I ask to generate 5 digit number number it is not giving me desired output.
My code is
for(k=0;k<n;k++)
{
temp = temp*10;
}
srand(time(NULL));
i = rand()%temp;
printf("%d\n",i);
k = 0;
temp = n;
while(i != 0)
{
arr1[n+k] = i%10;
i = i/10;
n--;
}
Output
Number of digits you want : 5
2031
while loop 1
while loop 3
while loop 0
while loop 2
N is 1
arr1[1] = 10651312
arr1[2] = 2
arr1[3] = 0
arr1[4] = 3
arr1[5] = 1
tell me where is the problem for getting desired number of digits.
Edit
I run that code around 100 times and out of those four time it is not working, rest is fine...

The problem is you're looping on the size of the random number you've generated and not the size of the array. In your example you want five digits but your code has generated a four digit number, 2031. This means that in the iteration of your bottom loop
... n = 2, i = 2: store a[2] = 2, i = 0
... n = 1, i = 0: loop condition failed, a[1] never set
which leaves random garbage in a[1]. If your random number did in fact contain 5 digits, not 4, then it would have completed the loop correctly.
Instead you want to loop over n
for(int j = n; j > 0; --j)
{
arr1[n+j] = i%10;
i = i/10;
}
Note that this is still using the array as 1-based, whereas in c arrays are 0-based, i.e. they start at element 0, i.e. in order to use arr1[5] you need to have malloced or declared 6 array elements or 6*sizeof(int) bytes. Also note that you should use better variable names than temp, and there's no benefit to reusing the variable: your compiler will automatically reuse registers and sort that out for you.

There are several problems here.
First, call srand() once before actually producing random numbers.
Second, your method taking the returned number modulo some power of 10 will, of course, also return numbers that are lower. For example, n%100000 could be anything from 0 to 99999.

n = rand() % (largest - smallest + 1) + smallest;
If you want a 5 digit number, what is the smallest 5 digit number? Do the same for the largest number. That can be used for any number range with no need to fill an array or anything.
Now you just need to figure out how to generate the largest and smallest values for the number of digits specified.
Happy coding!

Related

How to get the x (unknown) digit in a number made by writing natural numbers consecutively :123456789101112

I want to do this in C and I want to do it without using arrays or strings.
I have done it using arrays, but without it I do not know what to do. I am only allowed to use loops and if.
I found this to be an interesting problem and wrote the complete code for it. If you want to do it yourself, then don't look into the code. Here are some hints:
1. We know how many numbers of certain length there are: 9 1-digit numbers, 90 2-digits, 900 3-digits and so on
2. Thus, we can find out how long will be a number made of all 1, 2 and 3 -digit numbers written together: 9*1 + 90*2 + 900*3 = 2889
3. That means that if we are asked to find 253673-th digit, we can say for sure that it's a digit from a 4-digit number, because 253673 > 38889 and 253673 < 488889
4. Now we only need to find that 4-digit number and a digit inside of it.
Now, if you want just a solution, then here's my code, it's in C# though, but it should be really easy to translate if that's not a typo about C:
public static int GetDigit(long digitPosition)
{
if (digitPosition < 10)
return (int) digitPosition;
int N = 1;
long lengthOfNumber = 9;
int amountOfDigits = -1;
while(lengthOfNumber < digitPosition)
{
N++;
// there are 9 one-digit numbers, 90 two-digit numbers, 900 three-digit numbers and so on
int amountOfNumbers = 9 * (int)Math.Pow(10, N - 1);
// length of all N-digit numbers written together
amountOfDigits = amountOfNumbers * N;
// total length of composed number if we add all N-digit numbers
lengthOfNumber += amountOfDigits;
}
// now we know how much digits has the sub-number with target digit inside the composed number
// shift target digit position by removing all numbers below N length
// so if the digitPosition was 14, it will become 5th position in the number created from only 2-digit numbers, because we subtract all 9 1-digit numbers
digitPosition -= lengthOfNumber - amountOfDigits;
// get index of N-digit number that contains target digit, starting from the first N-digit number (for N=3 it's)
long numberIndex = (digitPosition - 1) / N;
// get index of digit inside that number, that is our target digit
long digitIndex = (digitPosition - 1) % N;
// find the number that contains target digit by adding index to the first N-digit number
long targetNumber = 1 * (long)Math.Pow(10, N - 1) + numberIndex;
// shift target digit to the target position
for (int i = 0; i < N - digitIndex - 1; i++)
targetNumber /= 10L;
// digit found
return (int) (targetNumber % 10L);
}

Algorithm to find k smallest numbers in an array in same order using O(1) auxiliary space

For example if the array is arr[] = {4, 2, 6, 1, 5},
and k = 3, then the output should be 4 2 1.
It can be done in O(nk) steps and O(1) space.
Firstly, find the kth smallest number in kn steps: find the minimum; store it in a local variable min; then find the second smallest number, i.e. the smallest number that is greater than min; store it in min; and so on... repeat the process from i = 1 to k (each time it's a linear search through the array).
Having this value, browse through the array and print all elements that are smaller or equal to min. This final step is linear.
Care has to be taken if there are duplicate values in the array. In such a case we have to increment i several times if duplicate min values are found in one pass. Additionally, besides min variable we have to have a count variable, which is reset to zero with each iteration of the main loop, and is incremented each time a duplicate min number is found.
In the final scan through the array, we print all values smaller than min, and up to count values exactly min.
The algorithm in C would like this:
int min = MIN_VALUE, local_min;
int count;
int i, j;
i = 0;
while (i < k) {
local_min = MAX_VALUE;
count = 0;
for (j = 0; j < n; j++) {
if ((arr[j] > min || min == MIN_VALUE) && arr[j] < local_min) {
local_min = arr[j];
count = 1;
}
else if ((arr[j] > min || min == MIN_VALUE) && arr[j] == local_min) {
count++;
}
}
min = local_min;
i += count;
}
if (i > k) {
count = count - (i - k);
}
for (i = 0, j = 0; i < n; i++) {
if (arr[i] < min) {
print arr[i];
}
else if (arr[i] == min && j < count) {
print arr[i];
j++;
}
}
where MIN_VALUE and MAX_VALUE can be some arbitrary values such as -infinity and +infinity, or MIN_VALUE = arr[0] and MAX_VALUE is set to be maximal value in arr (the max can be found in an additional initial loop).
Single pass solution - O(k) space (for O(1) space see below).
The order of the items is preserved (i.e. stable).
// Pseudo code
if ( arr.size <= k )
handle special case
array results[k]
int i = 0;
// init
for ( ; i < k, i++) { // or use memcpy()
results[i] = arr[i]
}
int max_val = max of results
for( ; i < arr.size; i++) {
if( arr[i] < max_val ) {
remove largest in results // move the remaining up / memmove()
add arr[i] at end of results // i.e. results[k-1] = arr[i]
max_val = new max of results
}
}
// for larger k you'd want some optimization to get the new max
// and maybe keep track of the position of max_val in the results array
Example:
4 6 2 3 1 5
4 6 2 // init
4 2 3 // remove 6, add 3 at end
2 3 1 // remove 4, add 1 at end
// or the original:
4 2 6 1 5
4 2 6 // init
4 2 1 // remove 6, add 1 -- if max is last, just replace
Optimization:
If a few extra bytes are allowed, you can optimize for larger k:
create an array size k of objects {value, position_in_list}
keep the items sorted on value:
new value: drop last element, insert the new at the right location
new max is the last element
sort the end result on position_in_list
for really large k use binary search to locate the insertion point
O(1) space:
If we're allowed to overwrite the data, the same algorithm can be used, but instead of using a separate array[k], use the first k elements of the list (and you can skip the init).
If the data has to be preserved, see my second answer with good performance for large k and O(1) space.
First find the Kth smallest number in the array.
Look at https://www.geeksforgeeks.org/kth-smallestlargest-element-unsorted-array-set-2-expected-linear-time/
Above link shows how you can use randomize quick select ,to find the kth smallest element in an average complexity of O(n) time.
Once you have the Kth smallest element,loop through the array and print all those elements which are equal to or less than Kth smallest number.
int small={Kth smallest number in the array}
for(int i=0;i<array.length;i++){
if(array[i]<=small){
System.out.println(array[i]+ " ");
}
}
A baseline (complexity at most 3n-2 for k=3):
find the min M1 from the end of the list and its position P1 (store it in out[2])
redo it from P1 to find M2 at P2 (store it in out[1])
redo it from P2 to find M3 (store it in out[0])
It can undoubtedly be improved.
Solution with O(1) space and large k (for example 100,000) with only a few passes through the list.
In my first answer I presented a single pass solution using O(k) space with an option for single pass O(1) space if we are allowed to overwrite the data.
For data that cannot be overwritten, ciamej provided a O(1) solution requiring up to k passes through the data, which works great.
However, for large lists (n) and large k we may want a faster solution. For example, with n=100,000,000 (distinct values) and k=100,000 we would have to check 10 trillion items with a branch on each item + an extra pass to get those items.
To reduce the passes over n we can create a small histogram of ranges. This requires a small storage space for the histogram, but since O(1) means constant space (i.e. not depending on n or k) I think we're allowed to do that. That space could be as small as an array of 2 * uint32. Histogram size should be a power of two, which allows us to use bit masking.
To keep the following example small and simple, we'll use a list containing 16-bit positive integers and a histogram of uint32[256] - but it will work with uint32[2] as well.
First, find the k-th smallest number - only 2 passes required:
uint32 hist[256];
First pass: group (count) by multiples of 256 - no branching besides the loop
loop:
hist[arr[i] & 0xff00 >> 8]++;
Now we have a count for each range and can calculate which bucket our k is in.
Save the total count up to that bucket and reset the histogram.
Second pass: fill the histogram again,
now masking the lower 8 bits and only for the numbers belonging in that range.
The range check can also be done with a mask
After this last pass, all values represented in the histogram are unique
and we can easily calculate where our k-th number is.
If the count in that slot (which represents our max value after restoring
with the previous mask) is higher than one, we'll have to remember that
when printing out the numbers.
This is explained in ciamej's post, so I won't repeat it here.
---
With hist[4] and a list of 32-bit integers we would need 8 passes.
The algorithm can easily be adjusted for signed integers.
Example:
k = 7
uint32_t hist[256]; // can be as small as hist[2]
uint16_t arr[]:
88
258
4
524
620
45
440
112
380
580
88
178
Fill histogram with:
hist[arr[i] & 0xff00 >> 8]++;
hist count
0 (0-255) 6
1 (256-511) 3 -> k
2 (512-767) 3
...
k is in hist[1] -> (256-511)
Clear histogram and fill with range (256-511):
Fill histogram with:
if (arr[i] & 0xff00 == 0x0100)
hist[arr[i] & 0xff]++;
Numbers in this range are:
258 & 0xff = 2
440 & 0xff = 184
380 & 0xff = 124
hist count
0 0
1 0
2 1 -> k
... 0
124 1
... 0
184 1
... 0
k - 6 (first pass) = 1
k is in hist[2], which is 2 + 256 = 258
Loop through arr[] to display the numbers <= 258 in preserved order.
Take care of possible duplicate highest numbers (hist[2] > 1 in this case).
we can easily calculate how many we have to print of those.
Further optimization:
If we can expect k to be in the lower ranges, we can even optimize this further by using the log2 values instead of fixed ranges:
There is a single CPU instruction to count the leading zero bits (or one bits)
so we don't have to call a standard log() function
but can call an intrinsic function instead.
This would require hist[65] for a list with 64-bit (positive) integers.
We would then have something like:
hist[ 64 - n_leading_zero_bits ]++;
This way the ranges we have to use in the following passes would be smaller.

For looping an array?

Just starting to grasp the ropes on c-programming, but I'm trying to create a function that can compute numbers from a given base to a decimal format.
(base_to_int)
For example,
digits1[] = {2, 3, 4, 5} in base 10 = 5432
and
digits2[] = {5, 6, 7} in base 8 = 501
it looks like when I try to run a for loop through, it doesn't seem to be computing it, and I keep getting the last digit in the array (for digits1, the answer for the output I keep getting is "5")...
why can't I run a for loop through the array?
CODE:
ndigits = number of digits in the array, digits = array, base = the base the array number is in.
int base_to_int(int ndigits, int* digits, int base)
{
for (int n = 0 ; n <= ndigits - 1 ; n++)
{
int a = digits[n];
return a * pow(base,n);
}
}
for this code, I keep getting the output "2" when I try to compile it.
You're returning the first result of the calculations, remember, return ends the execution of the function and simply returns the value, so you're having only one iteration and not looping and summing all values, your code is equivalent to:
return digits[0] * pow(base,0);
Change
return a * pow(base, n);
to
sum += a * pow(base, n)
You should return sum outside the loop, when you finish the calculations (don't forget to initialize sum to 0 outside the loop).
As Maroun Maroun said,when you write the return statement,the function returns and never computes the later part.

Code to generate bell curve is only creating data at even indexes. Why?

I'm writing some code to use random numbers to create a bell curve.
The basic approach is as follows:
Create an array of 2001 integers.
For some number of repeats, do the following:
• Start with a value of 1000 (the center-value)
• Loop 1000 times
• Generate a random number 0 or 1. If the random number is zero, subtract 1 from the value. If it's 1, add 1 to the value.
• Increment the count in my array at the resulting index value.
So 1000 times, we randomly add 1 or subtract 1 from a starting value of 1000. On average, we'll add 1 and subtract one about as often, so the outcome should be centered around 1000. Values greater or less than 1000 should be less and less frequent. A value at index 0 or index 1 would require a "coin toss" with the same result 1000 times in a row... a VERY unlikely event that is still possible.
Here is the code I came up with, written in C with a thin Objective C wrapper:
#import "BellCurveUtils.h"
#implementation BellCurveUtils
#define KNumberOfEntries 1000
#define KPinCount 1000
#define KSlotCount (KPinCount*2+1)
static int bellCurveData[KSlotCount];
+(void) createBellCurveData;
{
NSLog(#"Entering %s", __PRETTY_FUNCTION__);
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
int entry;
int i;
int random_index;
//First zero out the data
for (i = 0; i< KSlotCount; i++)
bellCurveData[i] = 0;
//Generate KNumberOfEntries entries in the array
for (entry =0; entry<KNumberOfEntries; entry++)
{
//Start with a value of 1000 (center value)
int value = 1000;
//For each entry, add +/- 1 to the value 1000 times.
for (random_index = 0; random_index<KPinCount; random_index++)
{
int random_value = arc4random_uniform(2) ? -1: 1;
value += random_value;
}
bellCurveData[value] += 1;
}
NSTimeInterval elapsed = [NSDate timeIntervalSinceReferenceDate] - start;
NSLog(#"Elapsed time = %.2f", elapsed);
int startWithData=0;
int endWithData=KSlotCount-1;
for (i = 0; i< KSlotCount; i++)
{
if (bellCurveData[i] >0)
{
startWithData = i;
break;
}
}
for (i = KSlotCount-1; i>=0 ; i--)
{
if (bellCurveData[i] >0)
{
endWithData = i;
break;
}
}
for (i = startWithData; i <= endWithData; i++)
printf("value[%d] = %d\n", i, bellCurveData[i]);
}
#end
The code does generate a bell-shaped curve. However, the array entries with odd indexes are ALL zero.
Here is some sample output:
value[990] = 23
value[991] = 0
value[992] = 22
value[993] = 0
value[994] = 20
value[995] = 0
value[996] = 25
value[997] = 0
value[998] = 37
value[999] = 0
value[1000] = 23
value[1001] = 0
value[1002] = 26
value[1003] = 0
value[1004] = 20
value[1005] = 0
value[1006] = 28
value[1007] = 0
value[1008] = 23
value[1009] = 0
value[1010] = 26
I have gone over this code line-by-line, and do not see why this is. When I step through it in the debugger, I get values that bounce around by single steps, starting at 1000, dropping to 999, incrementing to 1001, and various values even and odd. However, after 1000 iterations, the result of value is always even. What am I missing here?!?
I realize this isn't a typical SO development question, but I'm stumped. I cannot see what I am doing wrong. Can somebody explain these results?
//For each entry, add +/- 1 to the value 1000 times.
for (random_index = 0; random_index<KPinCount; random_index++)
{
int random_value = arc4random_uniform(2) ? -1: 1;
value += random_value;
}
For any two iterations of this loop, there are three potential outcomes:
random_value is zero both times, in which case "value" decreases by 2.
random_value is one both times, in which case "value" increases by 2.
random_value is zero once and one once, in which case "value" is unchanged.
Therefore, if the loop runs an even number of times (i.e. KPinCount is an even number), the parity of "value" will never change. Since it begins as an even number (1000), it ends as an even number.
Edit: If you want to resolve the problem but keep the same basic approach, then rather than starting with value = 1000 and running 1000 iterations in which you either add or subtract one, perhaps you could start with value = 0 and run 2000 iterations in which you add either one or zero. I'd have posted this as a comment to the discussion above, but can't comment since I just registered.
Youe immediate problem is at
for (random_index = 0; random_index < KPinCount; random_index++)
{
int random_value = arc4random_uniform(2) ? -1: 1;
value += random_value;
}
Because KPinCount is defined as 1000 (an even number), at the end of the loop, value will have changed by a multiple of 2.
Maybe try with KPinCount varying between 999 and 1000???
Ok, I've gotten some very useful feedback on this project.
To summarize:
If you always add or subtract one from a value, and do it twice, the possibilities are:
+1 +1 = even change
+1 -1 = no (even) change
-1 -1 = even change
Thus in that case the value always changes by 0 or 2, so result is always an even number.
Likewise, if you always apply an odd number of +1/-1 value changes, the resulting value will always be odd.
A couple of solutions were proposed.
Option 1: (The change I used in my testing) was before calculating each value, randomly decide to loop either 999 or 1000 times. That way half the time the result will be even and the other half of the time the value will be odd.
This has the effect that the spread of the graph will be infinitesimally narrower, because half of the time the possible range of values will be less by +/- 1.
Option 2 was to generate 3 random values, and add +1,0, or -1 to the value based on the result.
Option 3, suggested by #rhashimoto in the comments to one of the other answers, was to generate 4 random values, and add +1,0, 0, or -1 to the value based on the result.
I suspected that options 2 and 3 would cause a narrower spread of the curve because for 1/3 or 1/4 of the possible random values on each iteration, the value would not change, so the average spread of values would be smaller.
I've run a number of tests with different settings, and confirmed my suspicions.
Here are graphs of the different approaches. All sample graphs are plots of 1,000,000 points, with the graph clamped to values ranging from 800 to 1200 since there are never values outside that range in practice. The green bars on the graph are at the center point and +/- 50 steps
First, option 1, which randomly applies either 999 or 1000 +/-1 changes to the starting value:
Option 2, 1000 iterations of applying 3 random possible changes, -1,0, or +1:
And option 3, 1000 iterations of applying 4 random possible changes, -1,0, 0, or +1, as suggested by rhashimoto in the comments to pmg's answer:
And overlaying all the graphs on top of each other in Photoshop:
I have created graphs using a much larger number of points (100 million instead of 1 million) and the graphs are much smoother and less "jittery", but the shape of the curve is for all practical purposes identical. Applying a modest rolling average to the results from a one-million iteration graph would no doubt yield a very smooth curve.

How does this Codechef Factorial Solution in C work?

I'm trying to understand how this code:
#include<stdio.h>
int main()
{
int j,p,k;
long long int n,i;
scanf("%lld",&n);
for(k=n;k>=1;k--)
{
p=0;
scanf("%lld",&i);
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
printf("%d\n",p);
}
return 0;
}
solves this Codechef problem: http://www.codechef.com/problems/FCTRL
What I'm having troubles understanding is how this loop works:
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
Why is the j variable set to 5 and could someone walk me trough this loop if I would give the value of 60 to the i variable?
Thanks so much!
In short the problem is to find the number of zeroes of a factorial of number between 1 to 1000000000.
Now take a pencil and a paper. Start with 1. From 1 to 4 there is no 0. First 0 occurs at 5!. The next is at 10! and then at 15!, 20!, ...... This means that number of zeroes increases at the interval of 5.
Coming to the loop
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
See the i is stand for N here (see the question). Since number of zeroes increases at the interval of 5, j is initialized to 5 and j will be incremented as a multiple of 5 .
Now the simple rule is that the number of trailing zeros in the decimal representation of N! is simply the multiplicity of the prime factor 5 in N!.
In the statement p=p+i/j;, same rule is followed. The author of the program incremented j by 5 till N/j >= 5 leaving N (i.e i) here as it is.
N = i = 30
p = 30/5 + 30/(5*5) = 6 // 30/25 is 1 and does not satisfying the condition N/j >= 5
This algorithm makes more sense if you understand the method they are using to find the number of trailing zeros of a factorial which is outlined in Trailing zero Factorial and in Factorials and Trailing Zeroes. Basically relies on the insight that you need to account for all the products of 5 and 2 in the factorial expansion to discover how many zeros there will be in the end.
The algorithm to finding the number of trailing zeros in x! boils down to to:
Finding successive powers of 5
Dividing x by the result add the truncated result to the total
Stop when the result of division is less than 1 or in this specific case we know this will happen when the result is greater than x
So if go back to the code we can find the following steps:
step 3
| step 1
V V
for (j=5;j<=i;j*=5)
{
p=p+i/j; // step 2
}
This piece of code:
p=0;
scanf("%lld",&i);
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
counts the number of factor 5 in all the integers in [1, i] and stores the result in p.
Loop 1: j=5, p+=i/5 counts numbers that are divisible by 5 in the range [1, i]
Loop 2: j=25, p+=i/25 counts numbers that are divisible by 25 in the range [1, i] (notice that such numbers have been already counted once in loop 1)
Loop 3: j=125, p+=i/125 counts numbers that are divisible by 125 in the range [1, i] (notice that such numbers have been already counted twice in loop 1 and 2)
....

Resources