collatz/main.cpp

58 lines
1.8 KiB
C++

/*
Copyright 2024 ilikecats
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <iostream>
#include "include.hpp" // For optional gmpless building (see Makefile)
// TODO:
// Make disproving mode
// Make no print mode (for speed, implement after disproving mode)
int main(int argc, char* argv[]) {
// If number not provided
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " <number>\n";
exit(1);
}
mpz_t x; // mpz_t is the GMP equiv. of int
mpz_t xmod2; // Store x % 2
mpz_t steps; // Steps taken to get to one
// Init vars (if not disabled init)
#ifndef GMPLESS
mpz_init_set_str(x, argv[1],10);
mpz_init(xmod2);
mpz_init(steps);
#else
x = std::stoll(argv[1]);
steps = 0;
#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
}
mpz_add_ui(steps,steps,1); // steps += 1
std::cout << x << '\n';
}
std::cout << "Steps: " << steps << '\n';
}