Generate random values with fixed sum in C++ [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I saw tons of answers to this question on the web but, can you believe me? I still don't get the solution of this problem. I have an array of values. The size of this array is "n". I have also the defined value "sum". What I want is to generate "n" random values in such a way that their sum is equals to "sum", preferably uniformly distributed, otherwise (for example) having the first random number equals to "sum" and the rest equals to zero is not that nice. I need two algorithms which accomplish this task. One with positive Integers and one with positive Floats. Thanks a lot in advance!

First generate n random variables. Then sum them up: randomSum. Calculate coefficient sum/randomSum. Then multiply all random variables with that coefficient.
Integers would pose a problem... Rounding too (probably)

You can generate n numbers with a normal distribution then normalize them to your sum

You can generate n values defined by this : ((Sum - sumOfGeneratedValues) / n - (numberOfGeneatedValue)) -+X (With X maximal deviance)
Example :
SUM = 100 N = 5
+- 10
Rand between 100 - 0 / 5 - 0 --> 20 +-10 (So bewteen 10 and 30)
Value1 = 17;
Rand between 100 - 17 / 5 - 1 ---> 21 +-10 (So between 11 and 31)
... etc
Deviance would make your random uniform :)

you have a loop, where the number of iterations is equal to the number of random numbers you want minus 1. for the first iteration, you find a random number between 0 and the sum. you then subtract that random number from the sum, and on the next iteration you get another random number and subtract that from the sub sum minus the last iteration
its probably more easy in psuedocode
int sum = 10;
int n = 5; // 5 random numbers summed to equal sum
int subSum = sum;
int[] randomNumbers = new int[n];
for(int i = 0; i < n - 2; i++)
{
randomNumbers[i] = rand(0, subSum); // get random number between 0 and subSum
subSum -= randomNumbers[i];
}
randomNumbers[n - 1] = subSum; // leftovers go to the last random number

My C++ is very (very very) rusty. So let's assume you already know how to get a random number between x and y with the function random(x,y). Then here is some psuedocode in some other c derived language:
int n = ....; // your input
int sum = ....; // your input
int[] answer = new int[n];
int tmpsum = 0;
for (int i=0; i < n; i++) {
int exactpart = sum/n;
int random = (exactpart/2) + random(0,exactpart);
int[i] = tmpsum + random > sum ? sum - tmpsum : random;
tmpsum += int[i];
}
int[n-1] += sum - tmpsum;

Related

How do I add the all digit of an integer until its a single digit number?

If my question was not clear. Here's the whole description:
Consider, n = 653; so I would like to add all the three digit like 6+5+3 = 14.
But it still not an one digit number so I'll again do 1+4 = 5. Now it is as expected how can I do it? The 'n' can hold any integer.
I've searched and found how to separate the digits. Than I started to write the code. But I got stuck. I also found something similar to my question but that wasn't clear to me. I'm not sharing my unsolved code because I want to complete it by myself. But also I am helpless. So It'll will be very helpful if you tell me how can I do that. Sorry, if the question doesn't comfort you.
Do you need the result or the process. If all you care is result, then sum of sum of sum ... of digits can be found as:
int num = 653
int sum = num % 9;
if (sum == 0)
sum = 9;
Okay, strategy is to apply here. How many numbers you need to sum up? In your case 3. Let's see for any number:
int sum = 0;
while( (n / 10) != 0 ) // break if the divsion is zero, meaning number go too small
{
sum += (n%10); // tell me about the rest and sum it
n = n / 10; // reduce n by dividing by ten
}
Now set n = sum and repeat. Yes, with a recursion it would be possible or just add another while loop outside.
If the number is smaller than the divisor itself, in case of integers, you obtain 0. With the modulo operation you get the rest of the division.
Using
sum = num % 9;
Seems to be a faster way to do so.

Error when Calculating the Approximate Value of e^x [duplicate]

This question already has answers here:
Calculating e^x without using any functions
(4 answers)
Closed 8 years ago.
I am fairly new to c++ and writing a program to calculate the approximate value of e^x. Given by the formula:
1 + X + X^2/2! + ... + X^n/n! (for values of n from 1-100)
The program calculates the value perfectly until the user enters a number for "xValue" larger than 60 (ie. 61 or greater). I am unsure why this is and would really appreciate some feedback:
void calculate_sum(CalculateEx& numberSum)
{
double factoralSum;
numberSum.xTotal = numberSum.xValue;
numberSum.xTotal++;
for (double counter = 2; counter <= 100; counter++)
{
factoralSum = 1;
for (double factoral = 1; factoral <= counter; factoral++)
{
factoralSum *= factoral;
}
numberSum.xNextValue = pow(numberSum.xValue, counter) / factoralSum;
numberSum.xTotal += numberSum.xNextValue;
}
return;
}
Don't calculate the next row element from scratch, store the previous one, x^(n+1)/(n+1)! == (x^n)/n! * x/(n+1). This way you won't have to store values of x^n and especially n! separately (they are simply too big to fit in any reasonable type), whereas the values of x^n/n! converge to 0 as n rises.
Doing something like this would do:
double prevValue = 1;
sum = prevValue;
for (size_t power = 1; power < limit; ++power) {
prevValue *= x / (n + 1);
sum += prevValue;
}
Even a double can only fit so many digits. The computer always has a limit.
I know nothing about scientific computing, but I suppose if you wanted greater precision you might have to find a quad-precision floating point number or something.
Your program is attempting to calculate numbers that are out of the range of normal doubles. You can verify this by printing the value of factoralSum after the loop in which it is computed. If you insist on using the Taylor expansion, you may want to check the value of DBL_MAX in <float.h>
Java has a class called BigDecimal, which lets you create numbers with arbitrarily large precision. In C++, you may want to reference this question: Is there a C++ equivalent to Java's BigDecimal?

Single number as xy coordinates [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm using a very specific random number generator to produce numbers between 0 and 2^20. I am trying to access elements of a two dimensional array using this number.
Because myArray[x][y] can be represented as myArray[x*a + y] (where 'a' is the number of elements in the second dimension), shouldn't I be able to turn my single random number into 2-dimensional coordinates? The array in question is 2^10 by 2^10 exactly, so I thought it would be:
int random = randomize(); //assigned a random value up to 2^20
int x = floor(random / pow(2, 10));
int y = random % pow(2, 10);
myArray[x][y] = something(); //working with the array
The arrays elements are not being accessed as predicted and some are not being accessed at all. I suspect a bug in my logic, I've checked my program's syntax.
No I can't use two random numbers to access the array.
No I can't use a one dimensional array.
Just checking this would be the correct math. Thank you.
In C++ ^ is a binary bitwise XOR operator, not a power operator.
An idiomatic expression for obtaining powers of 2 in C++ is 1 << n, so you can rewrite your expression like this:
int x = floor(random / (1<<10));
int y = random % (1<<10);
The reason the left shift by n works like raising 2 to the power of n is the same that adding n zeros to one in a base-ten system multiplies the number by n-th power of ten.
2^10 isn't 1024 in C++.
Because in c++ ^ is XOR (a bitwise operator ) c++ operators
include <math.h> /* pow */
int main ()
{
int random = randomize(); //assigned a random value up to 2^20
int x = floor(random / pow(2,10));
int y = random % pow(2,10);
myArray[x][y] = something(); //working with the array
return 0;
}
Hope this helps.

Optimizing algorithm to find number of six digit numbers satisfying certain property

Problem: "An algorithm to find the number of six digit numbers where the sum of the first three digits is equal to the sum of the last three digits."
I came across this problem in an interview and want to know the best solution. This is what I have till now.
Approach 1: The Brute force solution is, of course, to check for each number (between 100,000 and 999,999) whether the sum of its first three and last three digits are equal. If yes, then increment certain counter which keeps count of all such numbers.
But this checks for all 900,000 numbers and so is inefficient.
Approach 2: Since we are asked "how many" such numbers and not "which numbers", we could do better. Divide the number into two parts: First three digits (these go from 100 to 999) and Last three digits (these go from 000 to 999). Thus, the sum of three digits in either part of a candidate number can range from 1 to 27.
* Maintain a std::map<int, int> for each part where key is the sum and value is number of numbers (3 digit) having that sum in the corresponding part.
* Now, for each number in the first part find out its sum and update the corresponding map.
* Similarly, we can get updated map for the second part.
* Now by multiplying the corresponding pairs (e.g. value in map 1 of key 4 and value in map 2 of key 4) and adding them up we get the answer.
In this approach, we end up checking 1K numbers.
My question is how could we further optimize? Is there a better solution?
For 0 <= s <= 18, there are exactly 10 - |s - 9| ways to obtain s as the sum of two digits.
So, for the first part
int first[28] = {0};
for(int s = 0; s <= 18; ++s) {
int c = 10 - (s < 9 ? (9 - s) : (s - 9));
for(int d = 1; d <= 9; ++d) {
first[s+d] += c;
}
}
That's 19*9 = 171 iterations, for the second half, do it similarly, with the inner loop starting at 0 instead of 1, that's 19*10 = 190 iterations. Then sum first[i]*second[i] for 1 <= i <= 27.
Generate all three-digit numbers; partition them into sets based on their sum of digits. (Actually, all you need to do is keep a vector that counts the size of the sets). For each set, the number of six-digit numbers that can be generated is the size of the set squared. Sum up the squares of the set sizes to get your answer.
int sumCounts[28]; // sums can go from 0 through 27
for (int i = 0; i < 1000; ++i) {
sumCounts[sumOfDigits(i)]++;
}
int total = 0;
for (int i = 0; i < 28; ++i) {
count = sumCounts[i];
total += count * count;
}
EDIT Variation to eliminate counting leading zeroes:
int sumCounts[28];
int sumCounts2[28];
for (int i = 0; i < 100; ++i) {
int s = sumOfDigits(i);
sumCounts[s]++;
sumCounts2[s]++;
}
for (int i = 100; i < 1000; ++i) {
sumCounts[sumOfDigits(i)]++;
}
int total = 0;
for (int i = 0; i < 28; ++i) {
count = sumCounts[i];
total += (count - sumCounts2[i]) * count;
}
Python Implementation
def equal_digit_sums():
dists = {}
for i in range(1000):
digits = [int(d) for d in str(i)]
dsum = sum(digits)
if dsum not in dists:
dists[dsum] = [0,0]
dists[dsum][0 if len(digits) == 3 else 1] += 1
def prod(dsum):
t = dists[dsum]
return (t[0]+t[1])*t[0]
return sum(prod(dsum) for dsum in dists)
print(equal_digit_sums())
Result: 50412
One idea: For each number from 0 to 27, count the number of three-digit numbers that have that digit sum. This should be doable efficiently with a DP-style approach.
Now you just sum the squares of the results, since for each answer, you can make a six-digit number with one of those on each side.
Assuming leading 0's aren't allowed, you want to calculate how many different ways are there to sum to n with 3 digits. To calculate that you can have a for loop inside a for loop. So:
firstHalf = 0
for i in xrange(max(1,n/3),min(9,n+1)): #first digit
for j in xrange((n-i)/2,min(9,n-i+1)): #second digit
firstHalf +=1 #Will only be one possible third digit
secondHalf = firstHalf + max(0,10-|n-9|)
If you are trying to sum to a number, then the last number is always uniquely determined. Thus in the case where the first number is 0 we are just calculating how many different values are possible for the second number. This will be n+1 if n is less than 10. If n is greater, up until 18 it will be 19-n. Over 18 there are no ways to form the sum.
If you loop over all n, 1 through 27, you will have your total sum.

How can I find the number of ways a number can be expressed as a sum of primes? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Generating the partitions of a number
Prime number sum
The number 7 can be expressed in 5 ways as a sum of primes:
2 + 2 + 3
2 + 3 + 2
2 + 5
3 + 2 + 2
5 + 2
Make a program that calculates, in how many ways number n can be
expressed as a sum of primes. You can assume that n is a number
between 0-100. Your program should print the answer in less than a
second
Example 1:
Give number: 7 Result: 5
Example 2:
Give number: 20 Result: 732
Example 3:
Give number: 80 Result: 10343662267187
I've been at this problem for hours. I can't figure out how to get n from (n-1).
Here are the sums from the first 30 numbers by a tree search
0 0 0 1 2 2 5 6 10 16 19 35 45 72 105 152 231 332 500 732 1081 1604 2351 3493 5136 7595 11212 16534 24441
I thought I had something with finding the biggest chain 7 = 5+2 and somehow using the knowledge that five can be written as 5, 3+2, 2+3, but somehow I need to account for the duplicate 2+3+2 replacement.
Look up dynamic programming, specifically Wikipedia's page and the examples there for the fibonacci sequence, and think about how you might be able to adapt that to your problem here.
Okay so this is a complicated problem. you are asking how to write code for the Partition Function; I suggest that you read up on the partition function itself first. Next you should look at algorithms to calculate partitions. It is a complex subject here is a starting point ... Partition problem is [NP complete] --- This question has already been asked and answered here and that may also help you start with algorithms.
There're several options. Since you know the number is between 0-100, there is the obvious: cheat, simply make an array and fill in the numbers.
The other way would be a loop. You'd need all the primes under 100, because a number which is smaller than 100 can't be expressed using the sum of a prime which is larger than 100. Eg. 99 can't be expressed as the sum of 2 and any prime larger than 100.
What you also know is: the maximum length of the sum for even numbers is the number divided by 2. Since 2 is the smallest prime. For odd numbers the maximum length is (number - 1) / 2.
Eg.
8 = 2 + 2 + 2 + 2, thus length of the sum is 4
9 = 2 + 2 + 2 + 3, thus length of the sum is 4
If you want performance you could cheat in another way by using GPGPU, which would significantly increase performance.
Then they're is the shuffling method. If you know 7 = 2 + 2 + 3, you know 7 = 2 + 3 + 2. To do this you'd need a method of calculating the different possibilities of shuffling. You could store the combinations of possibilities or keep them in mind while writing your loop.
Here is a relative brute force method (in Java):
int[] primes = new int[]{/* fill with primes < 100 */};
int number = 7; //Normally determined by user
int maxLength = (number % 2 == 0) ? number / 2 : (number - 1) / 2; //If even number maxLength = number / 2, if odd, maxLength = (number - 1) / 2
int possibilities = 0;
for (int i = 1; i <= maxLength; i++){
int[][] numbers = new int[i][Math.pow(primes.length, i)]; //Create an array which will hold all combinations for this length
for (int j = 0; j < Math.pow(primes.length, i); j++){ //Loop through all the possibilities
int value = 0; //Value for calculating the numbers making up the sum
for (int k = 0; k < i; k++){
numbers[k][j] = primes[(j - value) % (Math.pow(primes.length, k))]; //Setting the numbers making up the sum
value += numbers[k][j]; //Increasing the value
}
}
for (int x = 0; x < primes.length; x++){
int sum = 0;
for (int y = 0; y < i; y++){
sum += numbers[y];
if (sum > number) break; //The sum is greater than what we're trying to reach, break we've gone too far
}
if (sum == number) possibilities++;
}
}
I understand this is complicated. I will try to use an analogy. Think of it as a combination lock. You know the maximum number of wheels, which you have to try, hence the "i" loop. Next you go through each possibility ("j" loop) then you set the individual numbers ("k" loop). The code in the "k" loop is used to go from the current possibility (value of j) to the actual numbers. After you entered all combinations for this amount of wheels, you calculate if any were correct and if so, you increase the number of possibilities.
I apologize in advance if I made any errors in the code.