I'm new to C++. I'm trying to statistically determine the value of Pi based on Ernesto Cesaro's Theorem using the computer system's random number generator. But what I have done now can input a seed number and generate 100 pseudo random numbers and then estimate the value of pi. The generator can generate different group of Pseudo random numbers. However the confusion is I always get the estimate of pi for 2.8284 with no change. Here is the code:
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
int seed;
cout << "input a seed number: " << endl;
cin >> seed;
srand(seed);
int i, a[100];
for (i = 0; i < 100; i++)
a[i] = rand() % 100 + 1;
cout << "The generated random numbers are: " << endl;
for (i = 0; i < 100; i++)
cout << a[i] << "\t";
int m, n, j, r;
int sum = 0;
for (j = 0; j < 100; j++)
{
m = a[j];
n = a[j + 1];
j = j + 2;
do
{
r = m%n;
m = n;
n = r;
} while (r != 0);
if (n = 1)
sum = sum + 1;
}
double Pi, p;
p = 300 / sum;
Pi = sqrt(p);
cout << "The estimate value of Pi is: " << Pi << endl;
system("pause");
return 0;
}
Note that Cesaro's theorem states that given two random integers, x and y, the probability that gcd(x, y) = 1 is 6/(Pi^2). And PRNG used affects how close the resulting estimate is to Pi(3.1416).
There are several issues with your code.
Issue #1:
if (n = 1)
It should be if (n == 1) or else you are assigning 1 to n and always evaluating to true.
Issue #2:
n = r;
} while (r != 0);
if (n == 1)
If you think about it, the loop will end only when r is 0, but then n will also be 0 because of the last line of the loop. So n will never be equal to 1. You probably want if (m == 1).
Issue #3:
for (j = 0; j < 100; j++)
{
...
j = j + 2;
You are incrementing the j in the for line and in the loop body. You just need one.
for (j = 0; j < 100; j += 2)
{
//no j increment
Issue #4:
p = 300 / sum;
That is an integer division, because both numbers are integers. You want foating point: p = 300.0 / sum;.
With those changes I'm getting about 3.16.
You have two errors in the algorithm. (not four :p )
First - the numbers are coprime when gcd is not greater than 1, also you should check m value not n (see rodrigo's answer). So you need to change if to this:
if (m <= 1)
sum = sum + 1; // ++sum;
Second error is your estimator: p = 300 / sum;. Why do you use 300? The correct one is:
float pi = sqrt ( 6.f * iterations / sum) // from p = 6 / pi^2
where iterations in your code is 34 (because you change j-index in the loop body).
The problem is you've got the wrong shape. Instead of the ratio of the circumference of a circle to it's diameter (pi), you successfully estimated the ratio of the circumference of a square to it's diagonal.
i.e. a square with side 1 has a circumference of 4 and it's diagonal would be:
sqrt(1^2+1^2) = sqrt(2)
The ratio of circumference to diagonal would therefore be:
4:sqrt(2) = 2.8284
Just change the square to a circle and you should be right.
Related
In the following code I'm trying to find find the highest p (p is integer) number where 45^p is a divisor of n! (n is integer).
int n = 14;
long long unsigned int fact = 1;
for(int i = 1; i <= n; i++){
fact *= i;
}
bool until = true;
int ans;
// for goes until x is greater half of factorial
for(int i = 1; until; i++){
long long unsigned int x = 1;
for(int j = 1; j <= i; j++){
x *= 45;
}
if(fact/2 < x){
until = false;
}
else{
if(fact % x == 0){
ans = i;
}
}
}
cout << ans;
}
However, when I'm trying to end the loop at where x is greater than the half of factorial, it just keeps going on until 45^7 for some reason and it should stop at 45^5, where the number is lesser than half of n!. Why does this happen?
P.D: I'm not saying the program doesn't return the number I want (it returns ans = 2, which is true), but it's just pointless to keep on calculating x.
If you need the biggest value, starting from x = 45 and with x > fact / 2 the only way out of the loop, you have to get to at least the logarithm in base 45 of n! / 2.
And that's a limit of 7 because 45**6 <= 14! / 2 and 45**7 > 14! / 2.
Pen and pencil as suggested by #Raymond Chen is the way to go.
Here's a piece of code from a udemy course that I am currently taking that uses the pigeon hole principle to find a number made up of 0's and 1's divisible by the number n.
void findNumber(int n) {
int cur_rem = 0;
for(int i = 1; i <= n; i++) {
cur_rem = (cur_rem * 10 + 1) % n;
if(cur_rem == 0) {
for(int j = 1; j <= i; j++)
cout << 1;
return;
}
if(fr[cur_rem] != 0) {
for(int j = 1; j <= i - fr[cur_rem]; j++)
cout << 1;
for(int j = 1; j <= fr[cur_rem]; j++)
cout << 0;
return;
}
fr[cur_rem] = i;
}
}
So, in this code we actually first take the numbers 1,11,111,...,111..1(n times) and see if they are divisible by the given integer n. If they are not divisible then we find the 2 numbers within 1,11,111,...111..1(n times) with the same remainder when divided by the number n and subtract them to get the number that is divisible by n. So, I understand the theory part but I did not understand one line of the code.
Can someone please explain to me this line of code: cur_rem = (cur_rem * 10 + 1) % n; how can we get the remainder of the current number by multiplying the remainder of the previous number by 10 and then adding 1 and then finding the mod by dividing the sum by the given integer n?
Suppose the last number 111... (we'll call it m), had remainder r.
m % n = r
m = kn + r
Now the next number, 111..., call it m', is one digit longer than m.
m' = 10 m + 1
m' % n = (10 m + 1) % n
= (10(kn + r) + 1) % n
= (10 kn + 10r + 1) % n
= ( 10r + 1) % n
Question is as follows :
Given two numbers n and k. For each number in the interval [1, n], your task is to calculate its largest divisor that is not divisible by k. Print the sum of all these divisors.
Note: k is always a prime number.
t=3*10^5,1<=n<=10^9, 2<=k<=10^9
My approach toward the question:
for every i in range 1 to n, the required divisors is i itself,only when that i is not a multiple of k.
If that i is multiple of k, then we have to find the greatest divisor of a number and match with k. If it does not match, then this divisor is my answer. otherwise, 2nd largest divisor is my answer.
for example,take n=10 and k=2, required divisors for every i in range 1 to 10 is 1, 1, 3, 1, 5, 3, 7, 1, 9, 5. sum of these divisors are 36. So ans=36.
My code,which works for a few test cases and failed for some.
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
ll div2(ll n, ll k) {
if (n % k != 0 || n == 1) {
return n;
}
else {
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
ll aa = n / i;
if (aa % k != 0) {
return aa;
}
}
}
}
return 1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, k;
cin >> n >> k;
ll sum = 0, pp;
for (pp = 1; pp <= n; pp++) {
//cout << div2(pp, k);
sum = sum + div2(pp, k);
}
cout << sum << '\n';
}
}
Can someone help me where I am doing wrong or suggest me some faster logic to do this question as some of my test cases is showing TIME LIMIT EXCEED
after looking every possible explanation , i modify my code as follows:
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n, i;
ll k, sum;
cin >> n >> k;
sum = (n * (n + 1)) / 2;
for (i = k; i <= n; i = i + k) {
ll dmax = i / k;
while (dmax % k == 0) {
dmax = dmax / k;
}
sum = (sum - i) + dmax;
}
cout << sum << '\n';
}
}
But still it is giving TIME LIMIT EXCEED for 3 test cases. Someone please help.
Like others already said, look at the constraints: t=3*10^5,1<=n<=10^9, 2<=k<=10^9.
If your test has a complexity O(n), which computing the sum via a loop has, you'll end up doing a t * n ~ 10^14. That's too much.
This challenge is a math one. You'll need to use two facts:
as you already saw, if i = j * k^s with j%k != 0, the largest divisor is j;
sum_{i=1}^t i = (t * (t+1)) / 2
We start with
S = sum(range(1, n)) = n * (n+1) / 2
then for all number of the form k * x we added too much, let's correct:
S = S - sum(k*x for x in range(1, n/k)) + sum(x for x in range(1, n/k))
= S - (k - 1) * (n/k) * (n/k + 1) / 2
continue for number of the form k^2 * x ... then k^p * x until the sum is empty...
Ok, people start writing code, so here's a small Python function:
def so61867604(n, k):
S = (n * (n+1)) // 2
k_pow = k
while k_pow <= n:
up = n // k_pow
S = S - (k - 1) * (up * (up + 1)) // 2
k_pow *= k
return S
and in action here https://repl.it/repls/OlivedrabKeyProjections
In itself this is more of a mathematical problem:
If cur = [1..n], as you have already noticed, the largest divisor = dmax = cur is, if cur % k != 0, otherwise dmax must be < cur. From k we know that it is at most divisible into other prime numbers... Since we want to make sure that dmax is not divisible by k we can do this with a while loop... whereby this is certainly also more elegantly possible (since dmax must be a prime number again due to the prime factorization).
So this should look like this (without guarantee just typed down - maybe I missed something in my thinking):
#include <iostream>
int main() {
unsigned long long n = 10;
unsigned long long k = 2;
for (auto cur_n = decltype(n){1}; cur_n <= n; cur_n++)
{
if (cur_n % k != 0) {
std::cout << "Largest divisor for " << cur_n << ": " << cur_n << " (SELF)" << std::endl;
} else {
unsigned long long dmax= cur_n/k;
while (dmax%k == 0)
dmax= dmax/k;
std::cout << "Largest divisor for " << cur_n << ": " << dmax<< std::endl;
}
}
}
I wonder if something like this is what One Lyner means.
(Note, this code has two errors in it, which are described in the comments, as well as can be elucidated by One Lyner's new code.)
C++ code:
#include <vector>
#include <iostream>
using namespace std;
#define ll long long int
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int t;
cin >> t;
while (t--) {
ll n;
ll k, _k, result;
vector<ll> powers;
cin >> n >> k;
result = n * (n + 1) / 2;
_k = k;
while (_k <= n) {
powers.push_back(_k);
_k = _k * k;
}
for (ll p : powers) {
ll num_js = n / p;
result -= num_js * (num_js + 1) / 2 * (p - 1);
int i = 0;
while (p * powers[i] <= n) {
result += powers[i] * (p - 1);
i = i + 1;
}
}
cout << result << '\n';
}
}
I'm working on problem 9 in Project Euler:
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
The following code I wrote uses Euclid's formula for generating primes. For some reason my code returns "0" as an answer; even though the variable values are correct for the first few loops. Since the problem is pretty easy, some parts of the code aren't perfectly optimized; I don't think that should matter. The code is as follows:
#include <iostream>
using namespace std;
int main()
{
int placeholder; //for cin at the end so console stays open
int a, b, c, m, n, k;
a = 0; b = 0; c = 0;
m = 0; n = 0; k = 0; //to prevent initialization warnings
int sum = 0;
int product = 0;
/*We will use Euclid's (or Euler's?) formula for generating primitive
*Pythagorean triples (a^2 + b^2 = c^2): For any "m" and "n",
*a = m^2 - n^2 ; b = 2mn ; c = m^2 + n^2 . We will then cycle through
*values of a scalar/constant "k", to make sure we didn't miss anything.
*/
//these following loops will increment m, n, and k,
//and see if a+b+c is 1000. If so, all loops will break.
for (int iii = 1; m < 1000; iii++)
{
m = iii;
for (int ii = 1; n < 1000; ii++)
{
n = ii;
for (int i = 1; k <=1000; i++)
{
sum = 0;
k = i;
a = (m*m - n*n)*k;
b = (2*m*n)*k;
c = (m*m + n*n)*k;
if (sum == 1000) break;
}
if (sum == 1000) break;
}
if (sum == 1000) break;
}
product = a * b * c;
cout << "The product abc of the Pythagorean triplet for which a+b+c = 1000 is:\n";
cout << product << endl;
cin >> placeholder;
return 0;
}
And also, is there a better way to break out of multiple loops without using "break", or is "break" optimal?
Here's the updated code, with only the changes:
for (m = 2; m < 1000; m++)
{
for (int n = 2; n < 1000; n++)
{
for (k = 2; (k < 1000) && (m > n); k++)
{
sum = 0;
a = (m*m - n*n)*k;
b = (2*m*n)*k;
c = (m*m + n*n)*k;
sum = a + b + c;
if ((sum == 1000) && (!(k==0))) break;
}
It still doesn't work though (now gives "1621787660" as an answer). I know, a lot of parentheses.
The new problem is that the solution occurs for k = 1, so starting your k at 2 misses the answer outright.
Instead of looping through different k values, you can just check for when the current sum divides 1000 evenly. Here's what I mean (using the discussed goto statement):
for (n = 2; n < 1000; n++)
{
for (m = n + 1; m < 1000; m++)
{
sum = 0;
a = (m*m - n*n);
b = (2*m*n);
c = (m*m + n*n);
sum = a + b + c;
if(1000 % sum == 0)
{
int k = 1000 / sum;
a *= k;
b *= k;
c *= k;
goto done;
}
}
}
done:
product = a * b * c;
I also switched around the two for loops so that you can just initialize m as being larger than n instead of checking every iteration.
Note that with this new method, the solution doesn't occur for k = 1 (just a difference in how the loops are run, this isn't a problem)
Presumably sum is supposed to be a + b + c. However, nowhere in your code do you actually do this, which is presumably your problem.
To answer the final question: Yes, you can use a goto. Breaking out of multiple nested loops is one of the rare occasions when it isn't considered harmful.
I've been working on a Rabin-Karp string matching function in C++ and I'm not getting any results out of it. I have a feeling that I'm not computing some of the values correctly, but I don't know which one(s).
Prototype
void rabinKarp(string sequence, string pattern, int d, int q);
Function Implementation
void rabinKarp(string sequence, string pattern, int d, int q)
{
//d is the |∑|
//q is the prime number to use to lessen spurious hits
int n = sequence.length(); //Length of the sequence
int m = pattern.length(); //Length of the pattern
double temp = static_cast<double> (m - 1.0);
double temp2 = pow(static_cast<double> (d), temp); //Exponentiate d
int h = (static_cast<int>(temp2)) % q; //High Order Position of an m-digit window
int p = 0; //Pattern decimal value
int t = 0; //Substring decimal value
for (int i = 1; i < m; i++) { //Preprocessing
p = (d*p + (static_cast<int>(pattern[i]) - 48)) % q;
t = (d*t + (static_cast<int>(sequence[i])-48)) % q;
}
for (int s = 0; s < (n-m); s++) { //Matching(Iterate through all possible shifts)
if (p == t) {
for (int j = 0; j < m; j++) {
if (pattern[j] == sequence[s+j]) {
cout << "Pattern occurs with shift: " << s << endl;
}
}
}
if (s < (n-m)) {
t = (d*(t - ((static_cast<int>(sequence[s+1]) - 48)*h)) + (static_cast<int>(sequence[s + m + 1]) - 48)) % q;
}
}
return;
}
In my function call I pass 2359023141526739921 as the sequence, 31415 as the pattern, 10 as the radix, and 13 as the prime. I expect there to be one actual match and one spurious hit, but I never get the output statement from the matching part of the function. What am I doing wrong?
Thanks in Advance, Madison
The big gotcha in coding the Rabin Karp is the modulo operator. When two numbers X and Y are congruent modulo Q then (X % Q) should equal (Y % Q) but on the C++ compiler you're using they will only be equal if X and Y are both positive or both negative. If X is positive and Y is negative then (X % Q) will be positive and (Y % Q) will negative. In fact (X % Q)-Q == (Y % Q) in this case.
The work around is to check for negative values after each modulo and if there are any to add q to the variable, so your preprocessing loop becomes :
p = (d*p + pattern[i]) % q;
if ( p < 0 ) p += q;
t = (d*t + sequence[i]) % q;
if ( t < 0 ) t += q;
t in the main loop needs to have a similar check added.
Unless you've redefined ^, it is computing xor, not exponentiation. Also, you should be careful about overflowing the maximum value of an int before you perform %.