diff --git a/Makefile b/Makefile index c485a24..0973499 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,10 @@ default: - g++ main.cpp -o collatz + cp withgmp.hpp include.hpp + g++ -Wall -Wextra -pedantic -Werror -lgmp -lgmpxx main.cpp -o collatz strip collatz + rm include.hpp +gmpless: + cp nongmp.hpp include.hpp + g++ -Wall -Wextra -pedantic -Werror main.cpp -o collatz + strip collatz + rm include.hpp diff --git a/README.md b/README.md index 3ae914f..4b594c1 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,14 @@ # Collatz conjecture solver ### (x%2==0) ? x/=2 : x=x*3+1; -### You probably want the GMP version for arbitrarily big numbers. Get it from the [GMP branch](https://git.sdf.org/ilikecats/collatz/src/branch/gmp). +Program to solve the [Collatz conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture). -Program to solver the [Collatz conjecture](https://en.wikipedia.org/wiki/Collatz_conjecture). +To build: +- With GMP: Run `make -j1` (any more than `-j1` doesn't really do anything, there's four things to do and they can't be put out of order). +- Without GMP: Run `make gmpless -j1` (see above parenthetical statement). Algorithm: - Start with number. - If number is even, divide by two. - If number is odd, multiply by three and add one. - Repeat. - -To figure out if it will repeat, save all the previous numbers, and check if the current number is one of those. -If it is, that means it will repeat, and you have disproved the Collatz conjecture. So far, though, nobody has disproven it up to 2^68. diff --git a/main.cpp b/main.cpp index 712105f..7f86a13 100644 --- a/main.cpp +++ b/main.cpp @@ -15,7 +15,7 @@ */ #include -#include +#include "include.hpp" // For optional gmpless building (see Makefile) // TODO: // Make disproving mode @@ -27,13 +27,26 @@ int main(int argc, char* argv[]) { std::cout << "Usage: " << argv[0] << " \n"; exit(1); } - long long x { std::stoll(argv[1]) }; - std::cout << x << '\n'; - while (x != 1) { - if (x % 2 == 0) - x /= 2; - else if (x % 2) - x = x*3+1; + mpz_t x; // mpz_t is the GMP equiv. of int + mpz_t xmod2; // Store x % 2 + // Init vars (if not disabled init) +#ifndef GMPLESS + mpz_init_set_str(x, argv[1],10); + mpz_init(xmod2); +#else + x = std::stoll(argv[1]); +#endif + // Output x + std::cout << x << '\n'; // impacted section of code + // while x != 1 (mpz_cmp_ui is >0 if x>1, ==0 if x==1, and <0 if x<1, so !=0 means if not equal) + while (mpz_cmp_ui(x,1) != 0) { + mpz_mod_ui(xmod2,x,2); // xmod2 = x % 2 + if (mpz_cmp_ui(xmod2,0) == 0) { // If xmod2 == 0 + mpz_cdiv_q_ui(x,x,2); // x /= 2 + } else { // If xmod2 != 0 + mpz_mul_ui(x,x,3); // x *= 3 + mpz_add_ui(x,x,1); // x += 1 + } std::cout << x << '\n'; } } diff --git a/nongmp.hpp b/nongmp.hpp new file mode 100644 index 0000000..e75f283 --- /dev/null +++ b/nongmp.hpp @@ -0,0 +1,11 @@ + +#include + +// Make it build gmpless +#define mpz_t long long +#define GMPLESS +#define mpz_cmp_ui(a,b) (a != b) +#define mpz_mod_ui(a,b,c) a = b % c +#define mpz_cdiv_q_ui(a,b,c) a = b / c +#define mpz_mul_ui(a,b,c) a = b * c +#define mpz_add_ui(a,b,c) a = b + c diff --git a/withgmp.hpp b/withgmp.hpp new file mode 100644 index 0000000..6fbb4de --- /dev/null +++ b/withgmp.hpp @@ -0,0 +1 @@ +#include \ No newline at end of file