I have a program that displays one random number in file .
#include <iostream>
#include <fstream>
#include <random>
using namespace std;
int main() {
std::ofstream file("file.txt",std::ios_base::app);
int var = rand() % 100 + 1;
file<<var ;
return 0;
}
Results after 4 trial :
1,2 2,20 3,40 1,88
I am looking to not display the numbers . but only there updated average after each try.
Is there any way to calculate the average incrementally ?
Inside the file should exist only the average value :
For example first trial :
1.2
second trial displays the average in the file (1.2+2.2)/2
1.7
Even though it's kind of strange, what you are trying to do, and I'm sure there is a better way of doing it, here's how you can do it:
float onTheFlyAverage()
{
static int nCount=0;
float avg, newAvg;
int newNumber = getRandomNum();
nCount++; //increment the total number count
avg = readLastAvgFromFile(); //this will read the last average in your file
newAvg = avg*(nCount-1)/nCount+ (float)(newNumber)/nCount;
return newAvg;
}
If for some reason you want to keep an average in a file which you provide as input to your program and expect it to keep on averaging numbers for you (a sort of stop and continue feature), you will have to save/load the total number count in the file as well as the average.
But if you do it in one go this should work. IMHO this is far from the best way of doing it - but there you have it :)
NOTE: there is a divide by 0 corner-case I did not take care of; I leave that up to you.
You can use some simple math to calculate the mean values incrementally. However you have to count how many values contribute to the mean.
Let's say you have n numbers with a mean value of m. Your next number x contributes to the mean in the following way:
m = (mn + x)/(n+1)
It's bad for performance to divide and then multiply the average back. I suggest you store the sum and number.
(pseudocode)
// these variables are stored between function calls
int sum
int n
function float getNextRandomAverage() {
int rnd = getOneRandom()
n++;
sum += rnd;
float avg = sum/n
return avg
}
function writeNextRandomAverage() {
writeToFile(getNextRandomAverage())
}
Also it seems strange to me that your method closes the file. How does it know that it should close it? What if the file should be used later? (Say, consecutive uses of this method).
Related
I'm rather new to C++ and I'm trying to implement a simple quadratic congruential random number generator. It seems to work alright but when I test it's period (repeat interval) it doesn't seem to repeat at all. I store the first random number in a variable and then compare the new numbers until the first one is encountered again, and this comparison doesn't ever get triggered. Is my if-statement wrong somehow? Apologies if this is about a stupid bug I can't see.
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class QCG {
public:
int seed;
int m;
int a;
int b;
int c;
QCG(int seed) {
seed = seed;
m = 1162261467;
a = 14348907;
b = 14348908;
c = 65536;
}
int rand() {
seed = (a*(int)pow(seed, 2) + b*seed + c) % m;
return seed;
}
};
//testing repeat interval
int main() {
QCG qcg(1);
//generate the first number and store it
int first = qcg.rand();
int i = 1;
while (true) {
//this gets triggered when the first value is reached again, i.e. when the period is completed
if (qcg.rand() == first) {
std::cout << "success! period is " << i << std::endl;
break;
}
//this gets triggered if the previous condition isn't met by the maximum possible period
if (i == 1162261468) {
std::cout << "failed" << std::endl;
break;
}
++i;
}
return 0;
}
It goes in a 'rho' shape - first there are some unique numbers, then there is a loop. It doesn't loop back to the first number, but to some further number. Look up Pollard's rho algorithm, or Brent's cycle detection algorithm
You can simply set your first random number as any one of repeated numbers in cycles. It could not go back to the first number directly generated from the seed, because the step size is not fixed and the modulus is a prime number.
However, there will eventually be cycles of repeated numbers, even though a cycle does not contain all integers less than the modulus.
...
int first = qcg.rand();
for (int j = 0; j < 100000; j++)
first = qcg.rand();
int i = 1;
while (true) {
...
In this way, you can make it sure there is the cycle.
We've known since the days of von Neumann's "middle-square method" that while all PRNGs eventually cycle, some can contain multiple sub-cycles of different lengths. This is nicely demonstrated in the directed graph side image linked here. As you can see there, and as #maniek pointed out, there can be subsequences that lead to a cycle but whose values are not within the actual cycle. Wikipedia offers several cycle detection algorithms, with implementations in Python.
A PRNG which doesn't have sub-cyclic behavior, i.e., it produces every possible state before repeating, is called a "full cycle" generator. PRNG testing tends to focus more on the existence of subcycles (proving that the generator is not full cycle) rather than the length of the cycle itself, which can be as small as 1.
This is further complicated by the observations in a paper from the 1980's, which noted that true randomness produces duplicate values without reproducing the sequence from that point forward. That concept led to a test showing that a full cycle PRNG producing values in the range (0, 2k) which doesn't produce any duplicates within 3*2k/2 observations is provably non-random at an α=0.01 level. In other words, if you were generating 32 bit integers but hadn't seen any duplicates within the first 200,000 values, an observer could declare the sequence to be non-random with probability > 0.99. As a result, modern PRNGs use a much larger full cycle internal state space, which they collapse to produce a 32 or 64 bit output. This produces duplicate values without leading to a duplicate sequence.
So,
I have a limit, lets say 100 and
I have a vector that is filled with some numbers like 20,60,45 etc.
I need to find the maximum sum possible that is less than limit.
I have tried a couple of things but after trying too much, i just gave up so there is nothing i can show you for now.
Basically i just couldn't find the algorithm.
I tried to add more variables to the function, like totalWeight.
Although I'm supposed to return some totalWeight
int findOptimumLuggageWeight(int weightLimit, vector<int> collectionOfWeights)
{
int numberOfItems = collectionOfWeights.size();
if (){
}
else{
}
}
There is an example of output:
weightLimit = 100
collectionOfWeights = 40,25,20,30,44
Output: 99
This problem is from hackerrank and the link is : https://www.hackerrank.com/challenges/sherlock-and-squares .
The program below prints the count of numbers that are perfect squares within the given range. However, I get an error of time limit exceeded as the constraints for testcases are 1 < testcase < 100 and for 2 integers in the range are 1 < number 1 < 10^9, 1 < number2 < 10^9 .
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include<math.h>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int testcase;
cin>>testcase; //input testcase
while(testcase--)
{
int number1,number2,count=0;
cin>>number1>>number2; //input the limits
for(int i=number1;i<=number2;i++) //check for each number within the limits if it is a proper square
{
if(sqrt(i)==floor(sqrt(i)))
count++;
}
cout<<count<<endl; //print the total count of numbers that are perfect square within the limits
}
return 0;
}
Can someone please tell me how to optimize the problem further. As I am not able to figure out how time complexity can be further reduced.
I'm not going to code it for you. However :
Instead of testing every number, find the first perfect square in the range. Then, increment by one the square root of the perfect square. That gives you the next perfect square. Repeat until you reach the upper limit.
Expected improvement would be around the order of your numbers. If number1 is 1000, you'll be skipping around a thousand number at each step. That should pass easily.
As the number of squares is exactly the difference
between the square root of the next greater square number of number1 and square root of biggest square number below number2, you can use something like
cout << (int) ( floor(sqrt(number2)) - ceil(sqrt(number1)) + 1)
Check if number2 >= number1 and swap them otherwise.
is it copy paste code?
You get from input stream n1 and n2, but after that you using number1 and number2 which are not initialized.
I misstook arrays for vectors, Sorry (array is vektor in swedish)
I would need some help with a program I'm making. It is a assignment so I really need to understand how I do this and not just get the code :P
I need to make a array containing 10 "numbers" (I would like to make them editable when the program is running).
After I'v done this I need to make the program calculate the "average value" of all the numbers "/
Would be pretty neat if you could pick how many numbers you wanted the average value of as well, if anyone could share some knowledge in how I should to that :P
Anyways, I'v tried some code to make the vector that didn't work, I might as well add it here:
int vector[10];
and
vector[0] "number 1: ";
and so on for the input of numbers in the vector.
int sum = vector[0] + vector[1] + ...
cout << "average value is: " << sum/5;
should work for getting the average value though (right?)
I should allso add:
float average(int v[], int n)
to this thing as well, can't really se how though.
Any help/knowledge at all would be awesome! Cheers.
To pick how many numbers you wanted to average:
Native: (G++/Clang) only, not "legal" C++
cin >> num;
int vector[num];
"Correct" native (pointers):
int *vector = new int [num];
"Proper" C++:
#include <vector>
std::vector<int> v(num);
A function like following would work for computing average of an array containing n elements.
float average(int v[], int n)
{
float sum = 0;
for(int i = 0 ; i < n ; i++)
{
sum += v[i]; //sum all the numbers in the vector v
}
return sum / n;
}
You can declare your array as you have done however i do recommend you to name it something else then vector to avoid confusion. About tour issue with changing the numbers in the array you can do this by for example maning a loop going from one to 10 and then make the user enter values for all the fields.
Vektor på svenska = array på engelska (vector är något annat :))
If you want exactly 10 numbers, you can eliminate a lot of overhead by simply using an array. However, assuming you want to use a vector, you can easily find the average taking advantage of its "size" member, as such:
float average(std::vector<int> nums)
{
int sum = 0;
for (unsigned int i = 0; i < nums.size(); i++)
sum += nums[i];
return sum / nums.size();
}
Note that this does assume the sum won't be higher than 2^31-1, IE the highest number a signed integer can represent. To be safer you could use an unsigned and/or 64 bit int for sum, or some arbitrary precision library like gmp, but I'd assume that is all outside the scope of your assignment.
You must declare and array of size 10, which you have done.
Use a loop to get ten inputs from the user.
(for or while loops would do)
Use another loop to calculate the sum of all ten numbers and store it in a variable.
Divide the variable by ten.
This is what you need to do essentially. But, to make your driver program prettier, you can define the following functions:
void GetInput(int *A); //put the input loop here
You can also write any one of the given two functions:
long Sum(int * A) //put the summing loop here
double Average(int * A) //put the summing loop here AND divide the sum by ten
Since you are a beginner I feel obliged to tell you that you don't need to return an array since it isalways passed as a reference parameter. I did not bother to pass the array size as a parameter to any functions because that is fixed and known to be 10 but it will be good practice to do that.
Given a list of numbers in increasing order and a certain sum, I'm trying to implement the optimal way of finding the sum. Using the biggest number first
A sample input would be:
3
1
2
5
11
where the first line the number of numbers we are using and the last line is the desired sum
the output would be:
1 x 1
2 x 5
which equals 11
I'm trying to interpret this https://www.classle.net/book/c-program-making-change-using-greedy-method using stdard input
Here is what i got so far
#include <iostream>
using namespace std;
int main()
{
int sol = 0; int array[]; int m[10];
while (!cin.eof())
{
cin >> array[i]; // add inputs to an array
i++;
}
x = array[0]; // number of
for (int i; i < x ; i++) {
while(sol<array[x+1]){
// try to check all multiplications of the largest number until its over the sum
// save the multiplication number into the m[] before it goes over the sum;
//then do the same with the second highest number and check if they can add up to sum
}
cout << m[//multiplication number] << "x" << array[//correct index]
return 0;
}
if(sol!=array[x+1])
{
cout<<endl<<"Not Possible!";
}
}
Finding it hard to find an efficient way of doing this in terms of trying all possible combinations starting with the biggest number? Any suggestions would be greatly helpful, since i know im clearly off
The problem is a variation of the subset sum problem, which is NP-Hard.
An NP-Hard problem is a problem that (among other things) - there is no known polynomial solution for it, thus the greedy approach of "getting the highest first" fails for it.
However, for this NP-Hard problem, there is a pseudo-polynomial solution using dynamic programming. The problem where you can chose each number more then once is called the con change problem.
This page contains explanation and possible solutions for the problem.