Doing this question on SPOJ, trying to implement a sieve and a segmented sieve to get the desired primes. My code is as follows:
//Prime Generator
#include <iostream>
#include <math.h>
#include <cstdio>
using namespace std;
int main() {
//traditional sieve
int squareRoot = sqrt(1000000000);
//printf("%d\n\n", squareRoot);
bool primeList[squareRoot] = {false}; //all primes are marked as true, composite is false
//make entire array true
for (int i = 1; i < squareRoot; i++){
primeList[i] = true;
}
//traditional sieve to find primes first
for (int i = 2; i <= squareRoot; i++){
for (int j = i*i; j <= squareRoot; j+=i){
//composites are marked as false
primeList[j - 1] = false;
}
}
//segmented sieve + output
int a;
scanf("%d", &a);
while (a > 0){
int m, n;
scanf("%d%d", &m, &n);
//if lower than this range, then we can just output the primes we already computed
if (n <= squareRoot){
for (int i = m; i <= n; i++){
if (primeList[i - 1] == true){
printf("%d\n", i);
}
}
printf("\n");
}
//it is beyond this range, so we need to segment sieve
else {
int upperLimit = sqrt(n); //highest we need to divide by
int diff = n - m;
bool myPrimes[diff + 1];
for (int i = 0; i <= diff; i++){
myPrimes[i] = true;
}
for (int i = 2; i <= upperLimit; i++){
if (primeList[i - 1] == true){
int lowest = m/i * i;
while (lowest < m){
lowest += i;
}
while (lowest <= n){
myPrimes[lowest - m] = false;
lowest += i;
}
}
}
for (int i = m; i <= n; i++){
if (myPrimes[i - m] == true){
printf("%d\n", i);
}
}
printf("\n");
}
a--;
}
}
The basic logic I'm trying to do is:
First do a sieve of Eratosthenes to generate all the primes up to the sqrt of 10^9, since 10^9 is the upper limit of n.
If n is below sqrt(10^9), then I do not calculate anything new, just output the appropriate primes from (1).
If n is above sqrt(10^9), then I first calculate sqrt(n), which is the largest number we'd need, as any number bigger would not be divisible in the range [m, n].
Then I'd do the actual sieve, starting from 2, and trying to mark as false all numbers that are a multiple of a prime. I do 'lowest = m/i * i' to get the number that is the closest to m, where lowest <= m. If it is lower than m, then I add until it is just above m. I.E. if m==125 and n == 200, then 125/2 = 62, 62*2 = 124. 124+2 == 126, which would be the first number that is a multiple of 2 in the series [125,200].
Then we output any numbers that have no been marked false.
My issue is it seems my algorithm is correct (to me). I'm more than certain my first sieve works, but it seems that it might falter at generating primes larger than sqrt(10^9). However, from my testing it seems it does generate all the primes (and only primes). Is my algorithm to generate primes too uncertain? Is it a one-off issue with rounding?
My guess is that the error comes from
for (int i = 2; i <= upperLimit; i++){
if (primeList[i - 1] == true){
int lowest = m/i * i;
while (lowest < m){
lowest += i;
}
while (lowest <= n){
myPrimes[lowest - m] = false;
lowest += i;
}
}
}
But I can't tell where. Any tips or pointers would be welcome!
I got the mistake , its in the second case where you are defining myPrimes[diff] = {true} . But think of the where the time when input is like
m = 1 and n > sqrt(1000000000) then it would give 1 as a prime number.
Hope that would make accept you answer.
Related
I have done this :-
int divisors(int div, int i) {
int ans = 0;
for (int j = 1; j * j <= div; j++) {
if (div % j == 0) {
if (div / j == j && j < i)ans++;
else {
if (j < i && div / j < i) {
ans += 2;
}
else if (j < i) {
ans += 1;
}
else {
break;
}
}
}
}
return ans;
}
however this takes O(sqrt(div)) time, i there a way to optimize this?
You haven't said what you will do with this function. If you are going to calculate the number of divisors (less than a limit) for just a few numbers then the approach of using a function like the one you present could well be the best way.
On the other hand if you want to compute this for all numbers (between some limits perhaps) then a better approach might be to calculate this rather like the sieve of Aritosthenes. That is you loop over the divisors d in range, and for each d add 1 to the count for d, 2d, ... these being the only numbers that can be divided by d.
So something along the lines of
void compute( int maxn, int maxd, int* counts)
{ memset( counts, 0, maxn *sizeof *counts);
for( int d=1; d<maxd; ++d)
{ for( int n=d; n<maxn; n+=d)
{ counts[n] += 1;
}
}
}
After calling this counts[n] will hold the number of divisors less than maxd for each n 0,..maxn-1. Note that there are no divisions or modulus operations at all in the code above; these are often much slower than other arithmetic operations.
You cannot go lower than O(sqrt(N)) because in the worst case you take k = N, that time you'll have to traverse till sqrt(N)
#include <iostream>
using namespace std;
int main(){
int ctr = 0;
int count = 1; //Counts the nth prime number
int num = 3;
int div = 2; //Potential factors of the number
while(count <= 1000){
while(div < num){
if(num%div == 0){
ctr += 1; //If ctr is equal to 0, then num is prime
}
div += 1;
}
if(ctr == 0){ //If num is prime, count increases by 1
count += 1;
}
num += 1;
}
cout << num;
}
This is the code that I made to output the 1000th prime number. However, there must be something wrong with my program since it does not output 7919, which is the 1000th prime number.
It usually helps to refactor code like this into functions that have a clearly defined and testable behavior. For instance, the inner part of your code is a 'isPrime' function, and if you define it like this:
bool isPrime(int n) {
int div = 2; //Potential factors of the number
while (div < n) {
if (n % div == 0) {
return false;
}
++div;
}
return div == n;
}
It is easy to test, either through unit testing, or just manually checking if isPrime() works ok.
That makes the rest of the code more easy to write (and more importantly, read):
int primeCount = 0;
int n = 1;
while (primeCount < 1000) {
if (isPrime(n++)) {
++primeCount;
}
}
--n;
std::cout << n << std::endl;
As for why your code doesn't work. You should debug it. Go through line by line and see where it deviates from your expectations. Start out with finding the 3rd prime number, and not the 1000th.
Your isPrime part does not do what it is supposed to. Finding out why isn't hard, and you should definitely do that as a debugging-exercise, and not go with an easy answer from stackoverflow.
#include <stdio.h>
int main(){
int ctr = 0;
int count = 1; //Counts the nth prime number
int num = 3;
int div = 2; //Potential factors of the number
while(count <= 1000){
while(div < num){
if(num%div == 0){
ctr += 1; //If ctr is equal to 0, then num is prime
}
div += 1;
}
if(ctr == 0){ //If num is prime, count increases by 1
count += 1;
}
num += 1;
ctr=0;
div=2;
}
printf("%d",num);
}
I am trying to print the nth number of the series
2,23,235,2357,235711,23571113...
but i am not getting the right output after n=3.
At n=3 it's giving 234 which is wrong
#include<stdio.h>
#include<math.h>
main()
{
unsigned int t, n, p, i, j, d;
int s;
scanf("%d", &t);
if (t <= 10)
{
while (t != 0)
{
scanf("%d", &n);
p = n;
j = 2;
s = 0;
while (p > 0)
{
d = prime(j);
// printf("%d",d);
if (d == 1)
{
s = s + j * pow(10, p - 1);
p--;
j++;
}
else
j++;
}
printf("%d", s);
t--;
}
}
}
int prime(int num)
{
int i, flag = 1, n;
// n=sqrt(num);
for (i = 2; (i <= num / 2) && (flag == 1); i++)
{
if (num % i == 0)
flag = 0;
}
if (flag == 0)
return 0;
else
return 1;
}
I am trying to generate a prime number after each iteration.
So you're generating primes and want to output strings of the concatenated primes.
Write a function filling an array with the first n primes. That's easy.
Then you write an output function like:
for (i = 0; i < n; ++i) {
for (j = 0; j <= i; ++j) {
printf("%d", arr[j]);
}
printf("\n"); /* or any other separator */
}
No trouble any more with large numbers, until you reach primes in the order of magnitude of a billion.
In some low-quality C implementations, the pow function does not return a correct result even when the mathematical result is exactly representable in the floating-point format. E.g., pow(10, 2) may return 99.9999999999999857891452847979962825775146484375 instead of 100.
When a floating-point value that is not an integer is assigned to an integer object, the value is converted to an integer by truncation. Thus, for example, 234.9999847412109375 would become 234.
Generally, you should avoid using floating-point functions such as pow for integer arithmetic. However, for reasonably small values where you know the result of pow should be exactly an integer, you can correct the result by using round: round(pow(10, p - 1)).
Without using any extra space and inbuilt function !
#include<stdio.h>
int isPrime(int p)
{
int i;
for(i=2;i*i<=p;i++)
if(p%i==0)
return 0;
return 1;
}
int main()
{
int n=10,count=0,p=2;
while(count<n)
{
if(isPrime(p))
{
printf("%d",p);
count++;
}
p++;
}
}
even you can get rid of "count" variable by decrementing 'n'. and optimize this code by considering the fact that even numbers are not prime number (or all prime numbers are of the form of 6n+1 or 6n-1 ).
So the point is to have the program find and list all prime numbers between 1 and the number you enter. I'm using number_test as the number tested for prime, and divisor and the number to divide by.
I'm not sure what's wrong, as to me it looks functionally the same as the program posted here: Printing prime numbers from 1 through 100
with some minor changes (inputting a number, changing "i" to less than the number entered).
I've been looking for the past three or four days, and I haven't found anything that really answers this question fully, to the degree I need for class. Any help is much appreciated.
#include iostream
#include conio.h
using namespace std;
void main(void){
//Declare variables
int number_entered;
//Get inputs
cout << "This program lists all prime numbers from 1 through a positive number entered."
<< endl;
cout << "Please enter a positive integer."
<< endl;
cin >> number_entered;
cout << "Displaying all numbers from 1 to " << number_entered
<< endl
<< "Press any key to continue..."
<< endl;
getch();
for(int number_test = 2; number_test < number_entered; number_test++){
for(int divisor = 2; divisor < number_test; divisor++){
if(number_test % divisor == 0){
break;
}
else if(number_test % divisor != 0){
cout << number_test << " ";
break;
}
}
}
getch();
}
You should use the Sieve of Eratosthenes to compute the primes less than n. Begin by making a list of all numbers from 2 to the maximum desired prime n. Then, at each iterative step, the smallest remaining number that hasn't yet been considered is output and all of its multiples are crossed off the list.
function primes(n)
sieve := makeArray(2..n, True)
for p from 2 to n step 1
if sieve(p)
output p
for i from p*p to n step p
sieve[i] := False
This O(n log log n) algorithm is very fast; you should be able to compute the 78498 primes less than a million in less than a second.
A simple C++ Program to find the "N" prime numbers.
#include <iostream >
using namespace std;
int main()
{
int N;
cin >> N;
for (int i = 2; N > 0; ++i)
{
bool isPrime = true ;
for (int j = 2; j < i; ++j)
{
if (i % j == 0)
{
isPrime = false ;
break ;
}
}
if (isPrime)
{
--N;
cout << i << "\n";
}
}
return 0;
}
Just a small suggestion. Since prime numbers are odd, even numbers can be left out.
For example, in below loops, i and j increase by 2 (i +=2) instead of by 1 (i ++).
for (int i=3;i<=numberByUser; i+=2){
for (j=3;j<=i;j +=2){
if (i%j==0){
break;
}
}
i think in your answer any way one time the loop will terminated(i am talking about the loop checking the whether it is prime or not)once it comes out you don't know whether it made the break or not.So try to make a flag variable and check outside.I ope that will work
for(n=lower+1; n<upper; n++)
{
prime = 1;
for(i=2; i<n; i++)
if(n%i == 0)
{
prime = 0;
break;
}
if(prime)
printf("\n\n\t\t\t%d", n);
}
for(int number_test = 2; number_test < number_entered; number_test++){
for(int divisor = 2; divisor < number_test; divisor++){
if(number_test % divisor == 0){
break;
}
else if(number_test % divisor != 0){
cout << number_test << " ";
break;
}
}
}
The above code will not show you the prime numbers, it will just show you the number you entered if/when you run into a divisor that is not a factor of the number. For example, if you enter "9", you will start at 2, which is not a factor of 9, so you will show "9" (incorrectly) as a "prime", when it is not.
The easiest method for testing if a number is a prime is by checking all prime numbers below it's square root to see if they are factors of the given number. If none of them are (then none of the non-prime numbers below the given number will be either), the number is a prime number. If it has at least one prime factor less than or equal to it's square root, it is not prime.
Since you are looking to show all primes in a range of [0, X], you can simply check your list of factors as you go along (or do it in reverse, which is effectively what the Sieve of Eratosthenes does).
When my point was like your one, I wrote this code, it worked. Hope it will help you.
#include <cstdio>
#include <vector>
using namespace std;
vector <int> sn;
bool isPrime(int n) {
if (n <= 1) {
return 0;
}
if (n == 2) {
return true;
}
if (!(n % 2)) {
return false;
}
for (int i = 2; i*i <= n; i++) {
if (!(n % i)) {
return 0;
}
}
return 1;
}
void primeNumbers(int k) {
sn.push_back (2);
int i = 3, j = 1;
for ( ; j < k + 1; i += 2 && j++) {
if (isPrime(i)) {
sn.push_back(i);
}
}
}
int main() {
int i, k;
scanf("%d", &k);
primeNumbers(k);
for (i = 0; i < sn.size(); i++) {
printf("%d ", sn[i]);
}
return 0;
}
int getNumberOfPrimes(int N) {
bool *numbers = new bool[N-1]();
for (int i = 2; i <= N/2; ++i) {
if (numbers[i-2] == true) continue;
for (int j = i+i; j <= N; j = j+i) {
numbers[j-2] = true;
}
}
int count = 0;
for (int i = 0; i < (N-1); ++i) {
if (numbers[i] == false) ++count;
}
delete []numbers;
return(count);
}
Man I guess I have the simplest methode of this all. Hope it works for you!
#include < iostream >
using namespace std;
int main()
{
int n, i, j
cin>>n; //The max limith
for(i=2; i<=2; i++)
{
for(j=1; j<=i/2; j++)
if(i%j!=o)
cout<<i;
}
return 0;
}
If a number has divisors, at least one of them must be less than or equal to the square root of the number. When you check divisors, you only need to check up to the square root, not all the way up to the number being tested.
A number is called digit-increasing if it is equal n + nn + nnn + ... for some digit n between 1 and 9. For example 24 is digit-increasing because it equals 2 + 22 (here n = 2).
Actually, a friend of mine asked me this question and i am stuck thinking about it but couldn't find the exact solution so far. Can anyone help ? I needed the function that returns true if it is digit-increasing else false.
There are only relatively few numbers with this property: Within the range of unsigned long long (64 bits), there are only 172 digit-increasing numbers.
Therefore, in terms of a practical solution, it makes sense to pre-compute them all and put them in a hash. Here is Python code for that:
# Auxiliary function that generates
# one of the 'nnnn' elements
def digits(digit,times):
result = 0
for i in range(times):
result += digit*(10**i)
return result
# Pre-computing a hash of digit-increasing
# numbers:
IncDig = {}
for i in range(1,30):
for j in range(1,10):
number = reduce(lambda x,y:x+y,[digits(j,k) for k in range(1,i+1)])
IncDig[number] = None
Then the actual checking function is just a look-up in the hash:
def IncDigCheck(number):
return (number in IncDig)
This is virtually O(1), and the time and space taken for the pre-calculation is minimal, because there are only 9 distinct digits (zero doesn't count), hence only K*9 combinations of type n + nn + ... for a sum of length K.
General representation is:
n + (n*10 + n) + (n*100+n)...
If number look like sum of same digits then any digit can be represented as
(1+111+...) * base_digit
. Assuming this we can use simple algorithm:
bool isDigitIncreasing(const int num)
{
int n = 1;
int sum = 1; //value to increase n
while (n <= num) {
//if num is (111...) * base_digit and base_digit is < 10
if (num % n == 0 && n * 10 > num) return true;
sum = sum * 10 + 1; //N*10+N where n is 1 as was assumed
n += sum; //next step
}
return false;
}
Simple exhaustive search will work.
def is_digit_increasing_number(x):
# n = 1, 1+11, 1+11+111, ...
n = 1
i = 1
while n <= x:
if x % n == 0 and n * 10 > x:
return True
i += 1
n = n * 10 + i
return False
Simplest possible way is do the addition (bottom-up), I'll use simple for loop:
List<int> numbersSum = new List<int>{1,2,3,4,5,6,7,8,9};
List<int> lastNumber = new List<int>{1,2,3,4,5,6,7,8,9};
for(int i=0;i<= lg n + 1;i++)
{
for(int j=0;j<9;j++)
{
if(list[j] < n)
{
var lastNumberJ = lastNumber[j]*10+j+1;
list[j] += lastNumberJ; // add numbers to see will be same as n.
if (list[j] == n)
return j+1;
lastNumber[j] = lastNumberJ;
}
}
}
return -1;
The important part is you just need at most log n iteration and also you can return sooner if all numbers are bigger than given number, this is O(log n) algorithm.
Here is a python code.The basic logic here is that a digit increasing number if divided by a specific number between 1-9 gives a digit increasing number made of only ones.All the digit increasing numbers of 1 follow a specific pattern ie 12345678...
import sys
for n in range(1,10):
a=1
if k%n!=0:
a=0
else:
g=str(k/n)
j=int(g[0])
for i in range(1,len(g)):
if int(g[i])==j+1:
j=int(g[i])
else:
a=0
break
if a==1:
print "Yes,it is a digit increasing number"
sys.exit(0)
print "No,it is not a digit increasing number"
I have done in this way. Check out once.
int sum = 0, count =0;
bool flag = false;
public bool isDigitIncreasing(int input_number)
{
int n= get_number_of_digit(input_number); // Gets number of digits
int sum = 0;
for(int i=0;i<n;i++)
{
sum = sum*10+1;
count = count + sum;
}
for(int i=1; i<=9;i++)
{
if((input_number)==count*i)
{
flag = true;
break;
}
else
flag = false;
}
return flag;
}
public int get_number_of_digit(int num)
{
int size = 0;
do
{
num = num/10;
size++;
}while(num>0);
return size;
}
Here is the shortest solution
public static int isDigitIncreasing (int n)
{
if(n<10)
{
return 1;
}
for(int i=1;i<=9;i++)
{
int tempsum=i;
int previous=i;
while(tempsum<=n)
{
previous=previous*10 + i;
tempsum=tempsum + previous;
if(tempsum==n)
{
return 1;
}
}
}
return 0;
}
Ambiguitiy: Are the values 1-9 repeating for themselves? (too lazy to google this myself)
If 1-9 are repeating then following should work. If not, and you want the code to work only on values > 10 then you can initialize mult with 10.
int i, mult = 1, result, flag;
for( i=1; i<9; i++ )
{
flag = 0;
while( result < TARGET )
{
result = result+(i*mult);
mult = mult*10;
if( result == TARGET )
{
flag = 1;
break;
}
}
if( flag == 1 )
break;
}
After execution, i must contain the values for which RESULT is a repeating number IF the flag is 1. If flag is zero after execution then the TARGET isn't a repeating number.
I wonder if its possible that a number could be repeating for multiple values, just curious.
Here num is the number and n is the digit
#include<stdio.h>
int f(int num,int n)
{
int d=n;
while(num>0)
{
num-=n;
n=d+n*10;
}
if(num==0)
return 1;
else
return 0;
}
int main()
{
int num;
int n;
int flag;
printf("Enter the number :");
scanf("%d",&num);
printf("Enter the digit :");
scanf("%d",&n);
flag = f(num,n);
if(flag == 1)
printf("It's in n+nn+nnn+...\n");
if(flag ==0)
printf("It's not\n");
return 0;
}
Let d(k) be 1+11+111+...+(11...11) where the last number has k digits. Then d(1)=1, and d(k+1)=10d(k)+k+1.
We want to test if d(k)*i = n, for some k, and for some i=1..9.
If we've computed d(k), then i (if it exists) must be n/d(k). We can check if n/d(k) is correct, by comparing n with ((n/d(k))%10)*d(k). The %10 makes the test fail if i is larger than 9.
This gives us a relatively terse solution: compute subsequent d(k) until they are bigger than n, and at each point check to see if n is a digit-multiple of d(k).
Here's a very lightly code-golfed implementation of that idea:
#include <stdio.h>
int is_digit_increasing(int n) {
for(int d=1,k=1;d<=n;d=d*10+ ++k)if(n==(n/d)%10*d)return 1;
return 0;
}
int main(int argc, char**argv) {
for (int i=0; i<10000; i++) {
if (is_digit_increasing(i)) {
printf("%d\n", i);
}
}
return 0;
}
// Example program
#include <iostream>
#include <string>
int isDigitIncreasingNo(int n) {
if(n<=0)
return 0;
int len = std::to_string(n).length();
int vector1 = 0;
int vector2 = 0;
for(int i=1;i<=len;i++)
vector2 = (vector2*10)+i;
vector1 = vector2/10;
if(n % vector2 == 0 && (n / vector2)<=9 )
return 1;
if(n % vector1 == 0 && (n / vector1)<=9 )
return 1;
return 0;
}
int main()
{
for (int i=0; i<10000000; i++) {
if (isDigitIncreasingNo(i)) {
printf("%d\n", i);
}
}
return 0;
}
public boolean isDigitIncreasing(int number)
{
int sum;
int size=calculateNumberOfDigits(number);
for(int i=1;i<=9;i++)
{
sum=0;
int temp=size;
while(temp>=1)
{
for(int j=temp;j<=1;j--)
{
sum=sum+i*(int)Math.pow(10,j-1);
}
temp--;
}
if(sum==number)
{
return true;//Its a digit increasing
}
}
return false;
}
public int calculateNumberOfDigits(int number)
{
int size=0;
do
{
number=number/10;
size++;
}while(size>0);
return size;
}