Find the first prime fibonacci number larger than a given minimum [closed] - algorithm

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am trying to solve a problem but getting segmentation fault , not able to find what is wrong
the problem is you have to find the first fibonacci number greater then 227000 which is also a prime , call it X and return the sum of all prime divisors of X+1
#include<iostream>
int main(){
int n = 227000;
int prime[1000000];
std::cout<<"lll";
int i;
for(i = 2; i<1000;i++){
if(!prime[i]) continue;
int j;
for(j=i*i;j<1000000;j+=i){
prime[j] = 0;
}
}
int num = 1;
int nextnum = 1;
int newnum;
while(1){
newnum = num+nextnum;
if(newnum>n && prime[newnum]) break;
num = nextnum;
nextnum = newnum;
}
int sum = 1;
for(int i=2;i<1000000;i++){
if(prime[i] && newnum%i==0){
sum+=i;
}
}
std::cout<<sum;
return 0;
}

One reason you may get a segmentation fault is that you are getting a stack overflow due to placing 1 million integers on the stack.
Another reason is that primes is not initialised so the while loop may go too far and access primes beyond the limits of the array.
To fix this you need to:
Allocate array on the heap (or simply change it to be global)
Initialise your primes array to contain 1's
It would be better if the while loop also guaranteed to terminate or you may access the prime array beyond bounds.
#include<iostream>
int prime[1000000];
int main(){
int n = 227000;
std::cout<<"lll";
int i;
for(i = 2; i<1000000;i++)
prime[i]=1;
for(i = 2; i<1000;i++){
if(!prime[i]) continue;
int j;
for(j=i*i;j<1000000;j+=i){
prime[j] = 0;
}
}
int num = 1;
int nextnum = 1;
int newnum;
while(1){
newnum = num+nextnum;
if(newnum>n && prime[newnum]) break;
num = nextnum;
nextnum = newnum;
}
int sum = 1;
for(int i=2;i<1000000;i++){
if(prime[i] && newnum%i==0){
sum+=i;
}
}
std::cout<<sum;
return 0;
}
UPDATE
By the way, the second loop pointlessly tries to find factors of a prime number newnum.
I suspect the problem is actually to find something like the prime factors of the number (newnum+1) for which the code would change to
int sum = 0;
for(int i=2;i<1000000;i++){
if(prime[i] && (newnum+1)%i==0){
sum+=i;
}
}

I would creating a loop to generate Fibonacci numbers until I found one larger than the input. Then I would check each to see if it's prime. It's much faster than generating a list of prime numbers.
#include<iostream>
#include<math.h>
bool isPrime(int number)
{
for (int i=2;i<=sqrt(number);i++)
if ((number%i)==0) return false;
return true;
}
int main(){
int n = 227000;
int index=1;
int nums[2];
nums[0]=0;
nums[1]=1;
int currentFib = 0;
while (currentFib <=n || !isPrime(currentFib))
{
//Calculate the next fib
index = (index+1)%2;
nums[index] = nums[0]+nums[1];
currentFib = nums[index];
cout<<"Fibb "<<currentFib<<endl;
}
return currentFib;
}
Code returned 514229, which is both prime and a Fibonacci number and greater than 227000.

The prime fibonacci numbers are given at A005478. The smallest prime fibonacci number greater than 227000 is 514229. You might enjoy this entry at my blog.

Related

Runtime error in Cyclic Binary String Question [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 2 years ago.
Improve this question
Today I am solving hackerrank problem and unfortunately, I am stuck on this. Actually, I passed 4 test cases but the rest test case shows runtime error..
Here is my code -
public static String leftrotate(String str, int d) {
String ans = str.substring(d) + str.substring(0, d);
return ans;
}
public static String rightrotate(String str, int d) {
return leftrotate(str, str.length() - d);
}
public static int maximumPower(String s) {
int size = s.length();
int arr[] = new int[size];
for(int i = 0; i < size; i++){
arr[i] = Integer.parseInt(rightrotate(s, i), 2);
}
int max = 0;
for(int i = 0; i < size; i++){
for(int j = 1; j < size; j++){
if(arr[i] % Math.pow(2, j) == 0){
//System.out.println(arr[i] + "power = " +Math.pow(2, j));
if(max < j){
max = j;
}
}
}
}
return max;
}
What means dividable by the largest power of 2?
xyz10000
is dividable by
10000
So a 1 fby 0s. Otherwise it would not be dividable.
If there is no 1, the result is -1.
For rotatation equivalence, you are looking for the longest sequence of 0s which might be situated at front and tail of the sequence.
Now java's BitSet can juggle with bit operations, like find the next bit 1 from a given position.
To recap:
Look at the abstract problem, find the logic
Pick the data structure
Code it
Especially step 1 is very illuminating, yielding a very simple problem.
The key phrase being "the longest sequence of zeros."
I hope I did not spoil the coding.

CodeFight firstDuplicate interview challenge

As per problem statement:
Write a solution with O(n) time complexity and O(1) additional space
complexity. Given an array a that contains only numbers in the range
from 1 to a.length, find the first duplicate number for which the
second occurrence has the minimal index. In other words, if there are
more than 1 duplicated numbers, return the number for which the second
occurrence has a smaller index than the second occurrence of the other
number does. If there are no such elements, return -1
I followed my code according to constraints and still I'm getting time complexity error. Here's my solution:
int firstDuplicate(std::vector<int> a)
{
long long int n = a.size();
int cnt=0;
for(long long int i=0;i<n;i++)
{
//cout<<a[i]<<" "<<cnt<<endl;
if(a[i]==n||a[i]==-n)
{ cnt++;
if(cnt>1)
return n;
}
else if(a[abs(a[i])]<0)
return -a[i];
else
a[a[i]] = -a[a[i]];
}
return -1;
}
Can anyone suggest me better algorithm or whats wrong with this algorithm?
The algorithm for this problem is as follows:
For each number in the array, a, each time we see that number, we make a[abs(a[i]) - 1] negative. While iterating through a, if at some point we find that a[abs(a[i] - 1] is negative, we return a[i]. If we reach the last item in the array without finding a negative number, we return -1.
I feel like, this is what you were trying to get at, but you might have overcomplicated things. In code this is:
int firstDuplicate(std::vector<int> a)
{
for (int i = 0; i < a.size(); i += 1)
{
if (a[abs(a[i]) - 1] < 0)
return abs(a[i]);
else
a[abs(a[i]) - 1] = -a[abs(a[i]) - 1];
}
return -1;
}
This runs in O(n) time, with O(1) space complexity.
You can use the indexes to mark whether an element has occured before or not, if the value at idx is negative then it has already occurred before
int firstDuplicate(std::vector<int> a)
{
long long int n = a.size();
int cnt=0;
for(long long int i=0;i<n;i++)
{
int idx = a[i] - 1;
if(a[idx] < 0){
return a[i];
}
a[idx] *= -1;
}
return -1;
}

How do I compute the sum of differences in C++ given an array of N integers?

Problem Statement: https://www.codechef.com/ZCOPRAC/problems/ZCO13001
My code falls flat with a 2.01 second runtime on test cases 4 and 5. I cannot figure out the problem with my code:-
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int summation(long long int a[], int n, int count)
{
long long int sum=0;
int i;
if(count==n)
return 0;
else
{
for(i=count; i<n; i++)
sum+=a[i]-a[count];
}
return sum+summation(a, n, count+1);
}
int main()
{
int n, i;
long long int sum;
scanf("%d", &n);
long long int a[n];
for(i=0; i<n; i++)
scanf("%lld", &a[i]);
sort(a, a+n);
sum=summation(a, n, 0);
printf("%lld\n", sum);
return 0;
}
Thanks!
First of all you are on the correct track when you are sorting the numbers, but the complexity of your algorithm is O(n^2). What you want is an O(n) algorithm.
I'm only going to give you a hint, after that how you use it is up to you.
Let us take the example given on the site you specified itself i.e. 3,10,3,5. You sort these elements to get 3,3,5,10. Now what specifically are the elements of the sum of the differences in this? They are as follows -
3-3
5-3
10-3
5-3
10-3
10-5
Our result is supposed to be (3-3) + (5-3) + ... + (10-5). Let us approach this expression differently.
3 - 3
5 - 3
10 - 3
5 - 3
10 - 3
10 - 5
43 - 20
This we get by adding the elements on the left side and the right side of the - sign.
Now take a variable sum = 0.
You need to make the following observations -
As you can see in these individual differences how many times does the first 3 appear on the right side of the - sign ?
It appears 3 times so let us take sum = -3*3 = -9.
Now for the second 3 , it appears 2 times on the right side of the - sign and 1 time on the left side so we get (1-2)*3 = -3. Adding this to sum we get -12.
Similarly for 5 we have 2 times on the left side and 1 time on the right side. We get (2-1)*5 = 5. Adding this to sum we get -12+5 = -7.
Now for 10 we have it 3 times on the left side i.e. 3*10 so sum is = -7+30 = 23 which is your required answer. Now what you need to consider is how many times does a number appear on the left side and the right side of the - sign. This can be done in O(1) time and for n elements it takes O(n) time.
There you have your answer. Let me know if you don't understand any part of this answer.
Your code works, but there are two issues.
Using recursion will eventually run out of stack space. I ran your code for n=200000 (upper limit in Code Chef problem) and got stack overflow.
I converted the recursion to an equivalent loop. This hit the second issue - it takes a long time. It is doing 2*10^5 * (2*10^5 - 1) / 2 cycles which is 2*10^10 roughly. Assuming a processor can run 10^9 cycles a second, you're looking at 20 seconds.
To fix the time issue, look for duplicates in team strength value. Instead of adding the same strength value (val) each time it appears in the input, add it once and keep a count of how many times it was found (dup). Then, when calculating the contribution of the pair (i,j), multiply a[i].val - a[j].val by the number of times this combo appeared in raw input, which is the product of the two dup values a[i].dup * a[j].dup.
Here's the revised code, using Strength struct to hold the strength value & the number of times it occurred. I didn't have a handy input file, so used random number generator with range 1,100. By cycling through only the unique strength values, the total number of cycles is greatly reduced.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<random>
using namespace std;
int codechef_sum1(long long int a[], int n, int count)
{
long long int sum = 0;
int i;
if (count == n)
return 0;
else
{
for (i = count; i<n; i++)
sum += a[i] - a[count];
}
return sum + codechef_sum1(a, n, count + 1);
}
int codechef_sum2a(long long int a[], int n)
{
long long int sum = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
sum += (a[i] - a[j]);
return sum;
}
struct Strength
{
long long int val;
int dup;
//bool operator()(const Strength& lhs, const Strength & rhs) { return lhs.val < rhs.val; }
bool operator<(const Strength & rhs) { return this->val < rhs.val; }
};
int codechef_sum2b(Strength a[], int n)
{
long long int sum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++)
sum += (a[i].val - a[j].val) * (a[i].dup * a[j].dup);
}
return sum;
}
int codechef_sum_test(int n)
{
std::default_random_engine generator;
std::uniform_int_distribution<int> distr(1, 100);
auto a1 = new long long int[n];
auto a2 = new Strength [n];
int dup = 0, num = 0;
for (int i = 0; i < n; i++)
{
int r = distr(generator);
a1[i] = r;
int dup_index = -1;
for (int ii = 0; ii < num; ii++)
{
if (a2[ii].val == r)
{
dup++;
dup_index = ii;
break;
}
}
if (dup_index == -1)
{
a2[num].val = r;
a2[num].dup = 1;
++num;
}
else
{
++a2[dup_index].dup;
}
}
sort(a1, a1 + n);
sort(a2, a2 + num);
auto sum11 = codechef_sum1(a1, n, 0);
auto sum12 = codechef_sum2a(a1, n);
auto sum2 = codechef_sum2b(a2, num);
printf("sum11=%lld, sum12=%lld\n", sum11, sum12);
printf("sum2=%lld, dup=%d, num=%d\n", sum2, dup, num);
delete[] a1;
delete[] a2;
return 0;
}
void main()
{
codechef_sum_test(50);
}
Here's my solution with a quicker algorithm.
Everything below is spoilers, in case you wanted to solve it yourself.
--
long long int summation_singlepass(long long int a[], int n)
{
long long int grand_total=0;
long long int iteration_sum, prev_iteration_sum=0;
int i;
for (i = 1; i < n; i++) {
iteration_sum = prev_iteration_sum + i * ( a[i] - a[i-1] );
grand_total += iteration_sum;
prev_iteration_sum = iteration_sum;
}
return grand_total;
}
--
To figure out an algorithm, take a few simple but meaningful cases. Then work through them step by step yourself. This usually gives good insights.
For example: 1,3,6,6,8 (after sorting)
Third element in series. Its sum of differences to previous elements is:
(6-1) + (6-3) = 8
Fourth element in series. No change! Sum of differences to previous elements is:
(6-1) + (6-3) + (6-6) = 8
Fifth element in series. Pattern emerges when compared to formula for third and fourth. Sum of differences to previous elements is:
(8-1) + (8-3) + (8-6) + (8-6) = 16
So it's an extra 2 for each prior element in the series. 2 is the difference between our current element (8) and the previous one (6).
To generalize this effect. Derive the current iteration sum as the previous iteration sum + (i - 1) * ( a[i] - a[i-1] ). Where i is our current (1-based) position in the series.
Note that the formula looks slightly different in code compared to how I wrote it above. This is because in C++ we're working with 0-based indices for arrays.
Also - if you wanted to continue tweaking the solution you posted in OP, change the function return of summation to long long int to handle larger sets without the running total getting chopped.

Find unique number among 3n+1 numbers [duplicate]

This question already has answers here:
Finding an element in an array that isn't repeated a multiple of three times?
(4 answers)
Closed 7 years ago.
I have been asked this question in an interview.
Given that, there are 3n+1 numbers. n of those numbers occur in triplets, only 1 occurs single time. How do we find the unique number in linear time i.e., O(n) ? The numbers are not sorted.
Note that, if there were 2n+1 numbers, n of which occur in pairs, we could just XOR all the numbers to find the unique one. The interviewer told me that it can be done by bit manipulation.
Count the number of times that each bit occurs in the set of 3n+1 numbers.
Reduce each bit count modulo 3.
What is left is the bit pattern of the single number.
Oh, dreamzor (above) has beaten me to it.
You can invent a 3nary XOR (call it XOR3) operation which operates in base 3 instead of base 2 and simply takes each 3nary digit modulo 3 (when usual XOR takes 2nary digit modulo 2).
Then, if you XOR3 all the numbers (converting them to 3nary first) this way, you will be left with the unique number (in base 3 so you will need to convert it back).
The complexity is not exactly linear, though, because the conversions from/to base 3 require additional logarithmic time. However, if the range of numbers is constant then the conversion time is also constant.
Code on C++ (intentionally verbose):
vector<int> to_base3(int num) {
vector<int> base3;
for (; num > 0; num /= 3) {
base3.push_back(num % 3);
}
return base3;
}
int from_base3(const vector<int> &base3) {
int num = 0;
for (int i = 0, three = 1; i < base3.size(); ++i, three *= 3) {
num += base3[i] * three;
}
return num;
}
int find_unique(const vector<int> &a) {
vector<int> unique_base3(20, 0); // up to 3^20
for (int num : a) {
vector<int> num_base3 = to_base3(num);
for (int i = 0; i < num_base3.size(); ++i) {
unique_base3[i] = (unique_base3[i] + num_base3[i]) % 3;
}
}
int unique_num = from_base3(unique_base3);
return unique_num;
}
int main() {
vector<int> rands { 1287318, 172381, 5144, 566546, 7123 };
vector<int> a;
for (int r : rands) {
for (int i = 0; i < 3; ++i) {
a.push_back(r);
}
}
a.push_back(13371337); // unique number
random_shuffle(a.begin(), a.end());
int unique_num = find_unique(a);
cout << unique_num << endl;
}
byte [] oneCount = new byte [32];
int [] test = {1,2,3,1,5,2,9,9,3,1,2,3,9};
for (int n: test) {
for (int bit = 0; bit < 32; bit++) {
if (((n >> bit) & 1) == 1) {
oneCount[bit]++;
oneCount[bit] = (byte)(oneCount[bit] % 3);
}
}
}
int result = 0;
int x = 1;
for (int bit = 0; bit < 32; bit++) {
result += oneCount[bit] * x;
x = x << 1;
}
System.out.print(result);
Looks like while I was coding, others gave the main idea

Permutation with repetition without allocate memory

I'm looking for an algorithm to generate all permutations with repetition of 4 elements in list(length 2-1000).
Java implementation
The problem is that the algorithm from the link above alocates too much memory for calculation. It creates an array with length of all possible combination. E.g 4^1000 for my example. So i got heap space exception.
Thank you
Generalized algorithm for lazily-evaluated generation of all permutations (with repetition) of length X for a set of choices Y:
for I = 0 to (Y^X - 1):
list_of_digits = calculate the digits of I in base Y
a_set_of_choices = possible_choices[D] for each digit D in list_of_digits
yield a_set_of_choices
If there is not length limit for repetition of your 4 symbols there is a very simple algorithm that will give you what you want. Just encode your string as a binary number where all 2 bits pattern encode one of the four symbol. To get all possible permutations with repetitions you just have to enumerate "count" all possible numbers. That can be quite long (more than the age of the universe) as a 1000 symbols will be 2000 bits long. Is it really what you want to do ? The heap overflow may not be the only limit...
Below is a trivial C implementation that enumerates all repetitions of length exactly n (n limited to 16000 with 32 bits unsigned) without allocating memory. I leave to the reader the exercice of enumerating all repetitions of at most length n.
#include <stdio.h>
typedef unsigned char cell;
cell a[1000];
int npack = sizeof(cell)*4;
void decode(cell * a, int nbsym)
{
unsigned i;
for (i=0; i < nbsym; i++){
printf("%c", "GATC"[a[i/npack]>>((i%npack)*2)&3]);
}
printf("\n");
}
void enumerate(cell * a, int nbsym)
{
unsigned i, j;
for (i = 0; i < 1000; i++){
a[i] = 0;
}
while (j <= (nbsym / npack)){
j = 0;
decode(a, nbsym);
while (!++a[j]){
j++;
}
if ((j == (nbsym / npack))
&& ((a[j] >> ((nbsym-1)%npack)*2)&4)){
break;
}
}
}
int main(){
enumerate(a, 5);
}
You know how to count: add 1 to the ones spot, if you go over 9 jump back to 0 and add 1 to the tens, etc..
So, if you have a list of length N with K items in each spot:
int[] permutations = new int[N];
boolean addOne() { // Returns true when it advances, false _once_ when finished
int i = 0;
permutations[i]++;
while (permutations[i] >= K) {
permutations[i] = 0;
i += 1;
if (i>=N) return false;
permutations[i]++;
}
return true;
}

Resources