fork download
  1. # Casting out nines. (2.00)
  2. # Correctness and performance tests generated by Copilot (GPT-5).
  3.  
  4. import sys
  5. import unittest
  6. import random
  7. import timeit
  8.  
  9. # --- Your casting out nines functions ---
  10. def residue(n: int) -> int:
  11. return n % 9
  12.  
  13. def casting_out_nines_add(x: int, y: int) -> bool:
  14. return residue(x + y) == residue(residue(x) + residue(y))
  15.  
  16. def casting_out_nines_sub(x: int, y: int) -> bool:
  17. return residue(x - y) == residue(residue(x) - residue(y))
  18.  
  19. def casting_out_nines_mul(x: int, y: int) -> bool:
  20. return residue(x * y) == residue(residue(x) * residue(y))
  21.  
  22. def casting_out_nines_pow(x: int, y: int) -> bool:
  23. return residue(pow(x, y)) == residue(pow(residue(x), y))
  24.  
  25. def casting_out_nines_div(x: int, y: int) -> bool:
  26. q, r = divmod(x, y)
  27. return residue(x) == residue(residue(y) * residue(q) + residue(r))
  28.  
  29. # --- Unit + Randomized Tests ---
  30. class TestCastingOutNines(unittest.TestCase):
  31. def test_residue_basic(self):
  32. self.assertEqual(residue(10), 1)
  33. self.assertEqual(residue(18), 0)
  34. self.assertEqual(residue(0), 0)
  35.  
  36. def test_addition(self):
  37. self.assertTrue(casting_out_nines_add(123, 456))
  38. self.assertTrue(casting_out_nines_add(9, 18))
  39. self.assertTrue(casting_out_nines_add(0, 0))
  40.  
  41. def test_subtraction(self):
  42. self.assertTrue(casting_out_nines_sub(456, 123))
  43. self.assertTrue(casting_out_nines_sub(18, 9))
  44. self.assertTrue(casting_out_nines_sub(0, 0))
  45.  
  46. def test_multiplication(self):
  47. self.assertTrue(casting_out_nines_mul(123, 456))
  48. self.assertTrue(casting_out_nines_mul(9, 18))
  49. self.assertTrue(casting_out_nines_mul(0, 999))
  50.  
  51. def test_power(self):
  52. self.assertTrue(casting_out_nines_pow(2, 10)) # 1024
  53. self.assertTrue(casting_out_nines_pow(5, 3)) # 125
  54. self.assertTrue(casting_out_nines_pow(9, 5)) # multiples of 9
  55.  
  56. def test_division(self):
  57. self.assertTrue(casting_out_nines_div(100, 7))
  58. self.assertTrue(casting_out_nines_div(81, 9))
  59. self.assertTrue(casting_out_nines_div(19, 2))
  60.  
  61. def test_division_by_zero(self):
  62. with self.assertRaises(ZeroDivisionError):
  63. casting_out_nines_div(10, 0)
  64.  
  65. def test_randomized_inputs(self):
  66. for _ in range(5000):
  67. x = random.randint(-10**6, 10**6)
  68. y = random.randint(-10**6, 10**6)
  69. self.assertTrue(casting_out_nines_add(x, y))
  70. self.assertTrue(casting_out_nines_sub(x, y))
  71. self.assertTrue(casting_out_nines_mul(x, y))
  72. self.assertTrue(casting_out_nines_pow(x % 1000, y % 10)) # keep exponents small
  73. self.assertTrue(casting_out_nines_div(x, y if y else 1)) # avoid division by zero
  74.  
  75. # --- Benchmark Harness ---
  76. def benchmark_casting_out_nines(trials=10000):
  77. xs = [random.randint(0, 10**6) for _ in range(trials)]
  78. ys = [random.randint(1, 10**6) for _ in range(trials)]
  79.  
  80. def bench_add():
  81. for x, y in zip(xs, ys):
  82. casting_out_nines_add(x, y)
  83.  
  84. def bench_sub():
  85. for x, y in zip(xs, ys):
  86. casting_out_nines_sub(x, y)
  87.  
  88. def bench_mul():
  89. for x, y in zip(xs, ys):
  90. casting_out_nines_mul(x, y)
  91.  
  92. def bench_pow():
  93. for x, y in zip(xs, ys):
  94. casting_out_nines_pow(abs(x % 50), y % 10)
  95.  
  96. def bench_div():
  97. for x, y in zip(xs, ys):
  98. casting_out_nines_div(x, y)
  99.  
  100. results = {
  101. "Addition": timeit.timeit(bench_add, number=1),
  102. "Subtraction": timeit.timeit(bench_sub, number=1),
  103. "Multiplication": timeit.timeit(bench_mul, number=1),
  104. "Power": timeit.timeit(bench_pow, number=1),
  105. "Division": timeit.timeit(bench_div, number=1),
  106. }
  107. return results
  108.  
  109. if __name__ == "__main__":
  110. print("Running unit and randomized tests...", file=sys.stderr)
  111. unittest.main(exit=False)
  112.  
  113. print("Benchmarking performance...")
  114. results = benchmark_casting_out_nines(trials=10000)
  115. width = 1 + max(map(len, results.keys()))
  116. for op, t in results.items():
  117. print(f"{op:{width}s}: {t:.4f} seconds")
Success #stdin #stdout #stderr 0.47s 20132KB
stdin
Standard input is empty
stdout
Benchmarking performance...
Addition       : 0.0058 seconds
Subtraction    : 0.0057 seconds
Multiplication : 0.0058 seconds
Power          : 0.0082 seconds
Division       : 0.0080 seconds
stderr
Running unit and randomized tests...
........
----------------------------------------------------------------------
Ran 8 tests in 0.033s

OK