Advertisement
Guest User

bbb.ts

a guest
Apr 18th, 2025
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. **
  2.  * Checks if three given side lengths can form a valid, non-degenerate triangle.
  3.  *
  4.  * The triangle inequality theorem states that the sum of the lengths of any
  5.  * two sides of a triangle must be strictly greater than the length of the
  6.  * third side.
  7.  *
  8.  * This implementation handles large numbers up to Number.MAX_VALUE, incorporates
  9.  * tolerance for floating-point inaccuracies (e.g., 0.1, 0.2, 0.3 -> false),
  10.  * and includes specific checks for edge cases involving Number.MAX_VALUE where
  11.  * standard arithmetic might fail due to precision limits (e.g., MAX + 1 === MAX).
  12.  *
  13.  * @param a - Length of the first side. Must be a positive finite number.
  14.  * @param b - Length of the second side. Must be a positive finite number.
  15.  * @param c - Length of the third side. Must be a positive finite number.
  16.  * @returns True if the sides can form a valid, non-degenerate triangle, false otherwise.
  17.  */
  18. function isTriangle(a: number, b: number, c: number): boolean {
  19.     // 1. Basic validity checks: sides must be positive and finite numbers.
  20.     if (a <= 0 || b <= 0 || c <= 0 ||
  21.         !Number.isFinite(a) || !Number.isFinite(b) || !Number.isFinite(c)) {
  22.         return false;
  23.     }
  24.  
  25.     // --- Refined Special Case Handling for MAX_VALUE ---
  26.     // Handles cases where standard arithmetic fails due to precision (MAX+1=MAX)
  27.     // ONLY for configurations guaranteed to be valid triangles.
  28.     const max = Number.MAX_VALUE;
  29.     const aIsMax = (a === max);
  30.     const bIsMax = (b === max);
  31.     const cIsMax = (c === max);
  32.  
  33.     if (aIsMax && bIsMax && cIsMax) {
  34.         // Case (MAX, MAX, MAX) -> Valid
  35.         return true;
  36.     }
  37.     if (aIsMax && bIsMax && !cIsMax) {
  38.          // Case (MAX, MAX, c) where c is finite positive -> Valid
  39.          return true;
  40.     }
  41.      // Case (MAX, b, MAX) where b is finite positive:
  42.      // This is degenerate (a+b=c due to precision). Let general checks handle it.
  43.      // No 'return true' here.
  44.  
  45.      // Case (a, MAX, MAX) where a is finite positive:
  46.      // This is degenerate (a+b=c due to precision). Let general checks handle it.
  47.      // No 'return true' here.
  48.  
  49.     // --- End Special Case ---
  50.  
  51.     // 2. General Triangle Inequality Check with Tolerance
  52.     // For all other cases, including (MAX, b, MAX) and (a, MAX, MAX).
  53.     // Tolerance is scaled based on max side involved in each comparison.
  54.  
  55.     // Check 1: a + b > c?
  56.     // Use Math.max(a,b,c) for consistent tolerance scaling across checks
  57.     const maxSide = Math.max(a, b, c); // Calculate once if possible
  58.     // Note: Math.max works correctly even with large numbers, but not Infinity.
  59.     // However, Infinity inputs are already rejected by isFinite check.
  60.     const tolerance = Number.EPSILON * maxSide * 2;
  61.  
  62.     // Check the difference against the tolerance.
  63.     // `a + b - c` handles potential Infinity in `a+b` correctly if c is finite.
  64.     if (a + b - c <= tolerance) {
  65.          return false;
  66.     }
  67.  
  68.     // Check 2: a + c > b?
  69.     // Re-use the same tolerance for consistency and slight optimization
  70.     if (a + c - b <= tolerance) {
  71.         return false;
  72.     }
  73.  
  74.     // Check 3: b + c > a?
  75.     // Re-use the same tolerance
  76.     if (b + c - a <= tolerance) {
  77.         return false;
  78.     }
  79.  
  80.     // If all checks passed, it's a valid, non-degenerate triangle.
  81.     return true;
  82. }
  83.  
  84. // --- Native TypeScript Test Suite (same as previous versions) ---
  85.  
  86. console.log("Starting Triangle Validity Tests...\n");
  87. let passed = 0;
  88. let failed = 0;
  89.  
  90. function runTest(description: string, expected: boolean, actual: boolean) {
  91.     const result = expected === actual;
  92.     if (result) {
  93.         console.log(`✅ PASS: ${description}`);
  94.         passed++;
  95.     } else {
  96.         console.error(`❌ FAIL: ${description} (Expected: ${expected}, Got: ${actual})`);
  97.         failed++;
  98.     }
  99. }
  100.  
  101. // --- Test Cases (including the one that failed previously) ---
  102.  
  103. // 1. Equivalence Classes: Valid Triangles
  104. console.log("--- Valid Triangles ---");
  105. runTest("Equilateral (small)", true, isTriangle(5, 5, 5));
  106. runTest("Equilateral (large)", true, isTriangle(1e100, 1e100, 1e100));
  107. runTest("Isosceles (small)", true, isTriangle(5, 5, 8));
  108. runTest("Isosceles (base > leg)", true, isTriangle(8, 8, 5));
  109. runTest("Isosceles (large)", true, isTriangle(1e50, 1e50, 1.5e50));
  110. runTest("Scalene (small)", true, isTriangle(3, 4, 5)); // Right triangle
  111. runTest("Scalene (obtuse)", true, isTriangle(3, 5, 7));
  112. runTest("Scalene (acute)", true, isTriangle(5, 6, 7));
  113. runTest("Scalene (large)", true, isTriangle(1e10, 1.2e10, 1.5e10));
  114. runTest("Sides very close", true, isTriangle(10, 10, 10 + Number.EPSILON * 100));
  115.  
  116. // 2. Equivalence Classes: Degenerate Triangles (Should return false)
  117. console.log("\n--- Degenerate Triangles (Expect False) ---");
  118. runTest("Degenerate (exact sum: 1, 2, 3)", false, isTriangle(1, 2, 3));
  119. runTest("Degenerate (exact sum: 3, 1, 2)", false, isTriangle(3, 1, 2));
  120. runTest("Degenerate (exact sum: 2, 3, 1)", false, isTriangle(2, 3, 1));
  121. runTest("Degenerate (large exact sum)", false, isTriangle(1e50, 2e50, 3e50));
  122. runTest("Degenerate (floating point: 0.1, 0.2, 0.3)", false, isTriangle(0.1, 0.2, 0.3));
  123. runTest("Degenerate (floating point: 0.3, 0.1, 0.2)", false, isTriangle(0.3, 0.1, 0.2));
  124. runTest("Degenerate (floating point: 0.2, 0.3, 0.1)", false, isTriangle(0.2, 0.3, 0.1));
  125. const slightlyOffA = 0.1;
  126. const slightlyOffB = 0.2;
  127. const slightlyOffC = 0.3 + Number.EPSILON;
  128. runTest("Degenerate (A+B almost equal C, C slightly larger)", false, isTriangle(slightlyOffA, slightlyOffB, slightlyOffC));
  129. const slightlyOffC2 = 0.3 - Number.EPSILON;
  130. runTest("Near Degenerate (A+B barely greater than C)", true, isTriangle(slightlyOffA, slightlyOffB, slightlyOffC2));
  131.  
  132.  
  133. // 3. Equivalence Classes: Impossible Triangles (Should return false)
  134. console.log("\n--- Impossible Triangles (Expect False) ---");
  135. runTest("Impossible (1, 1, 3)", false, isTriangle(1, 1, 3));
  136. runTest("Impossible (3, 1, 1)", false, isTriangle(3, 1, 1));
  137. runTest("Impossible (1, 3, 1)", false, isTriangle(1, 3, 1));
  138. runTest("Impossible (large)", false, isTriangle(1e100, 1e100, 3e100));
  139. runTest("Impossible (one side much larger)", false, isTriangle(5, 8, 100));
  140.  
  141. // 4. Boundary / Edge Cases
  142. console.log("\n--- Boundary & Edge Cases ---");
  143. // 4.1 Zero and Negative Sides
  144. runTest("Zero side (a=0)", false, isTriangle(0, 5, 5));
  145. runTest("Zero side (b=0)", false, isTriangle(5, 0, 5));
  146. runTest("Zero side (c=0)", false, isTriangle(5, 5, 0));
  147. runTest("All zero sides", false, isTriangle(0, 0, 0));
  148. runTest("Negative side (a<0)", false, isTriangle(-1, 5, 5));
  149. runTest("Negative side (b<0)", false, isTriangle(5, -1, 5));
  150. runTest("Negative side (c<0)", false, isTriangle(5, 5, -1));
  151. runTest("All negative sides", false, isTriangle(-1, -2, -3));
  152.  
  153. // 4.2 Very Small Positive Sides
  154. const tiny = Number.MIN_VALUE;
  155. const tinyEps = Number.EPSILON;
  156. runTest("Very small equilateral", true, isTriangle(tiny, tiny, tiny));
  157. runTest("Very small isosceles", true, isTriangle(tiny * 2, tiny * 2, tiny));
  158. runTest("Very small scalene", true, isTriangle(tiny * 3, tiny * 4, tiny * 5));
  159. runTest("Very small degenerate", false, isTriangle(tiny, tiny * 2, tiny * 3));
  160. runTest("Near zero, almost degenerate", false, isTriangle(tinyEps, tinyEps, 2 * tinyEps));
  161. runTest("Near zero, valid", true, isTriangle(tinyEps * 2, tinyEps * 2, tinyEps * 3));
  162.  
  163. // 4.3 Very Large Positive Sides (Near MAX_VALUE)
  164. const max = Number.MAX_VALUE;
  165. const maxHalf = max / 2;
  166. const maxSlightlyLess = max * (1 - Number.EPSILON * 10);
  167. runTest("Max value equilateral", true, isTriangle(max, max, max)); // Handled by special case
  168. runTest("Max value isosceles (MAX, MAX, X)", true, isTriangle(max, max, maxHalf)); // Handled by special case
  169. runTest("Max value isosceles (base small)", true, isTriangle(max, max, 1)); // Handled by special case
  170. runTest("Max value scalene (near max, general check)", true, isTriangle(maxSlightlyLess, maxHalf, maxHalf + maxHalf / 2));
  171. runTest("Max value impossible (degenerate, near max)", false, isTriangle(maxHalf, maxHalf, max));
  172. runTest("Max value impossible (sum < third, near max)", false, isTriangle(maxHalf, maxHalf / 2, max));
  173. // THIS IS THE CRITICAL TEST THAT FAILED BEFORE: (MAX, 1, MAX) should be false
  174. runTest("Max value precision limit (a+c > b fails in simple check)", false, isTriangle(max, 1, max)); // Handled by general check now
  175.  
  176. // 4.4 Non-Finite Inputs
  177. runTest("Infinity side (a=Infinity)", false, isTriangle(Infinity, 5, 5));
  178. runTest("Infinity side (b=Infinity)", false, isTriangle(5, Infinity, 5));
  179. runTest("Infinity side (c=Infinity)", false, isTriangle(5, 5, Infinity));
  180. runTest("Two Infinity sides", false, isTriangle(Infinity, Infinity, 5));
  181. runTest("All Infinity sides", false, isTriangle(Infinity, Infinity, Infinity));
  182. runTest("NaN side (a=NaN)", false, isTriangle(NaN, 5, 5));
  183. runTest("NaN side (b=NaN)", false, isTriangle(5, NaN, 5));
  184. runTest("NaN side (c=NaN)", false, isTriangle(5, 5, NaN));
  185. runTest("All NaN sides", false, isTriangle(NaN, NaN, NaN));
  186.  
  187. // --- Test Summary ---
  188. console.log("\n--- Test Summary ---");
  189. console.log(`Total Tests: ${passed + failed}`);
  190. console.log(`Passed: ${passed}`);
  191. console.log(`Failed: ${failed}`);
  192.  
  193. if (failed > 0) {
  194.     console.error("\n❌ Some tests failed!");
  195.     // process.exit(1); // Optional for Node.js
  196. } else {
  197.     console.log("\n✅ All tests passed!");
  198. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement