From 62c2920d1fb35d8f5075c9be74ccf94b19bcdf7a Mon Sep 17 00:00:00 2001 From: Honey Ranjan 12219884 <119494046+honeyranjan1@users.noreply.github.com> Date: Mon, 7 Apr 2025 14:19:18 +0530 Subject: [PATCH] Update euler-0042.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Constant Name and Value Changed const int NoTriangle = 0; → const int NotTriangle = -1; Triangle Check Logic Modified Old: n = sqrt(2 * x); → Checks if n(n+1)/2 == x New: Solves using n = (-1 + sqrt(1 + 8x)) / 2 with full discriminant check Return Value on Invalid Triangle Old: Returns NoTriangle (0) if not a triangle New: Returns NotTriangle (-1) if not a triangle Condition in main() Updated Old: if (getTriangle(sum) != NoTriangle) New: if (getTriangle(sum) != NotTriangle) Mathematical Accuracy Old Code: Uses approximation (sqrt) New Code: Uses exact formula with perfect square and integer check --- euler-0042.cpp | 106 +++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 56 deletions(-) diff --git a/euler-0042.cpp b/euler-0042.cpp index 4fa5de8..05f803f 100644 --- a/euler-0042.cpp +++ b/euler-0042.cpp @@ -68,81 +68,75 @@ #include #include -const int NoTriangle = 0; -// return triangle index or -1 if not a triangle number +const int NotTriangle = -1; + +// Return triangle index or -1 if not a triangle number int getTriangle(unsigned long long x) { - unsigned long long n = sqrt(2*x); + // Solve n(n+1)/2 = x => n^2 + n - 2x = 0 + // Discriminant D = 1 + 8x + unsigned long long d = 1 + 8 * x; + unsigned long long sqrtD = static_cast(std::sqrt(d)); + + if (sqrtD * sqrtD != d) + return NotTriangle; + + if ((-1 + sqrtD) % 2 != 0) + return NotTriangle; - // if n it truely the right answer then t(n) = x - unsigned long long check = n * (n + 1) / 2; - if (x == check) - return n; - else - return NoTriangle; + return static_cast((-1 + sqrtD) / 2); } -// read a single word from STDIN, syntax: "abc","def","xyz" +// Read a single word from STDIN, syntax: "ABC","DEF",... std::string readWord() { - std::string result; - while (true) - { - // read one character - char c = std::cin.get(); - // no more input ? - if (!std::cin) - break; + std::string result; + while (true) + { + char c = std::cin.get(); + if (!std::cin) + break; - // ignore quotes - if (c == '"') - continue; - // finish when a comma appears - if (c == ',') - break; + if (c == '"') + continue; + if (c == ',') + break; - // nope, just an ordinary letter (no further checks whether c in 'A'..'Z') - result += c; - } - return result; + result += c; + } + return result; } int main() { //#define ORIGINAL #ifdef ORIGINAL + unsigned int triangleWords = 0; + while (true) + { + std::string word = readWord(); + if (word.empty()) + break; - unsigned int triangleWords = 0; - while (true) - { - // read next word - auto word = readWord(); - if (word.empty()) - break; + unsigned int sum = 0; + for (char c : word) + sum += c - 'A' + 1; - unsigned int sum = 0; - // A = 1, B = 2, ... - for (auto c : word) - sum += c - 'A' + 1; // all words contain only uppercase letters without spaces or other characters - - // another "triangle word" ? - if (getTriangle(sum) != NoTriangle) - triangleWords++; - } - std::cout << triangleWords << std::endl; + if (getTriangle(sum) != NotTriangle) + triangleWords++; + } + std::cout << triangleWords << std::endl; #else - - unsigned int tests; - std::cin >> tests; - while (tests--) - { - // all work is done in getTriangle() - unsigned long long x; - std::cin >> x; - std::cout << getTriangle(x) << std::endl; - } + unsigned int tests; + std::cin >> tests; + while (tests--) + { + unsigned long long x; + std::cin >> x; + std::cout << getTriangle(x) << std::endl; + } #endif - return 0; + return 0; }