I am making a program that calculates the most loops of the Collatz conjecture between a range of number (1 - 100,000,000) and I need it to be functional in under 4 minutes on a linux system with the
command gcc -O0 -m32 -Wall -Wextra -Werror -pedantic -o collatz collatz.c.
Any ideas on how to improve the algorithm because after 10,000,000 the program takes too long to complete, keep in mind I can't use multithreading nor pre calculated data.
All answers are welcome, thank you for your time.
// Lets find the longest collatz
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// This function finds how many times it took for a number to reach 1
unsigned long int collatz(uint32_t First_num) {
// steps measures how many times a number needs to reach 1
uint32_t steps = 1;
// This is the loop that applies the rules of the collatz conjecture
while (First_num != 1) {
(First_num % 2 == 0) ? (First_numm >>= 1) : (First_num = (3 * First_num + 1) / 2);
steps++;
}
return steps;
}
// This is the function that calculates the maximum loops a number needs to reach 1
int max(uint32_t First_num, uint32_t Second_num) {
// This "if" determines if the number is correct
if (First_num <= 0 || Second_num <= 0) {
printf("0\n");
}
uint32_t max = 0;
uint32_t max_num = 0;
uint32_t i = First_num;
// This loop is used to find the maximum times the collatz function needs to be used
for (i; i <= Second_num; i++) {
printf("The num %u took the most %ld!!!\n", i, collatz(i));
// This block finds the number with the most loops
if ((collatz(i)) >= max) {
max = collatz(i);
max_num = i;
}
}
printf("The num %u took the most %u !!!\n", max_num, max);
return 0;
}
// This is the main function in which the "max" function is used and the user gives his input and gets his output
int main(int argc, char **argv) {
if (argc != 3) {
printf("Program needs to be called as './prog num1 num2'\n");
return 1;
}
//Users input
uint32_t num1 = atoi(argv[1]);
uint32_t num2 = atoi(argv[2]);
// Users input
max(num1, num2);
return 0;
}
//End of the program
Bug
3 * First_num + 1
readily overflows. Need more work (a wider type). @Eric PostpischilDrop debug output
Avoid re-calculation
Save prior work
(or at least some of it.)
After re-work to prevent overflow:
Empirical: Reverse iteration order
I reversed the order, going from most to least and it took 1/6 less time. (total 3.75 s) TBD why.
Aside: OP's code is loose with types changes. Improved code would avoid that.