Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions Maths/ModularBinaryExponentiationRecursive.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
/*
Modified from:
https://github.com/TheAlgorithms/Python/blob/master/maths/binary_exp_mod.py
/**
* @function modularBinaryExponentiation
* @description Calculate (base^exponent) % mod recursively using binary exponentiation.
* @param {number} base
* @param {number} exponent
* @param {number} mod
* @returns {number}
*/
const isOddExponent = (exponent) => exponent % 2 !== 0

Explanation:
https://en.wikipedia.org/wiki/Exponentiation_by_squaring
*/
const modularBinaryExponentiation = (base, exponent, mod) => {
if (mod === 1) return 0
if (exponent === 0) return 1

const modularBinaryExponentiation = (a, n, m) => {
// input: a: int, n: int, m: int
// returns: (a^n) % m: int
if (n === 0) {
return 1
} else if (n % 2 === 1) {
return (modularBinaryExponentiation(a, n - 1, m) * a) % m
if (isOddExponent(exponent)) {
return (base * modularBinaryExponentiation(base, exponent - 1, mod)) % mod
} else {
const b = modularBinaryExponentiation(a, n / 2, m)
return (b * b) % m
const half = modularBinaryExponentiation(base, exponent / 2, mod)
return (half * half) % mod
}
}

Expand Down
23 changes: 23 additions & 0 deletions Maths/test/ModularBinaryExponentiationRecursive.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,26 @@ describe('modularBinaryExponentiation', () => {
expect(modularBinaryExponentiation(2, 10, 17)).toBe(4)
})
})

import { modularBinaryExponentiation } from '../ModularBinaryExponentiationRecursive'

describe('modularBinaryExponentiation behavior & simplified parity logic (Precondition near line 9 of Maths/ModularBinaryExponentiationRecursive.js)', () => {
test('Smallest valid input (base = 2, exponent = 0, mod = 5)', () => {
expect(modularBinaryExponentiation(2, 0, 5)).toBe(1)
})

test('Ordinary input (base = 2, exponent = 10, mod = 1000)', () => {
// 2^10 = 1024, 1024 % 1000 = 24
expect(modularBinaryExponentiation(2, 10, 1000)).toBe(24)
})

test('Boundary input (mod = 1)', () => {
expect(modularBinaryExponentiation(5, 3, 1)).toBe(0)
})

test('Equivalence across odd and even exponent evaluations', () => {
expect(modularBinaryExponentiation(3, 5, 7)).toBe(5) // 3^5 = 243 % 7 = 5
expect(modularBinaryExponentiation(7, 2, 13)).toBe(10) // 7^2 = 49 % 13 = 10
expect(modularBinaryExponentiation(10, 4, 100)).toBe(0) // 10^4 = 10000 % 100 = 0
})
})
43 changes: 43 additions & 0 deletions work/R50-T026/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
import subprocess
import json
import sys

def run_checks():
work_dir = "work/R50-T026"
os.makedirs(work_dir, exist_ok=True)

# 1. Capture versions
node_ver = subprocess.check_output(["node", "-v"]).decode().strip()
npm_ver = subprocess.check_output(["npm", "-v"]).decode().strip()
with open(f"{work_dir}/versions.json", "w") as f:
json.dump({"node": node_ver, "npm": npm_ver}, f, indent=2)

# 2. Execute test suite
cmd = ["npx", "vitest", "run", "Maths/test/ModularBinaryExponentiationRecursive.test.js"]
res = subprocess.run(cmd, capture_output=True, text=True)

if res.returncode != 0:
cmd = ["npx", "vitest", "run", "Maths/tests/ModularBinaryExponentiationRecursive.test.js"]
res = subprocess.run(cmd, capture_output=True, text=True)

with open(f"{work_dir}/test_output.log", "w") as f:
f.write(res.stdout + "\n" + res.stderr)

if res.returncode == 0:
with open(f"{work_dir}/fixture_results.json", "w") as f:
json.dump({
"status": "PASSED",
"task": "R50-T026",
"precondition_line": "Maths/ModularBinaryExponentiationRecursive.js:9",
"refactored_responsibility": "Extracted exponent parity evaluation into explicit isOddExponent helper",
"smallest_valid_input": {"base": 2, "exponent": 0, "mod": 5, "expected": 1},
"ordinary_input": {"base": 2, "exponent": 10, "mod": 1000, "expected": 24}
}, f, indent=2)
print("All checks passed.")
else:
print("Tests failed!")
sys.exit(1)

if __name__ == "__main__":
run_checks()
18 changes: 18 additions & 0 deletions work/R50-T026/fixture_results.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"status": "PASSED",
"task": "R50-T026",
"precondition_line": "Maths/ModularBinaryExponentiationRecursive.js:9",
"refactored_responsibility": "Extracted exponent parity evaluation into explicit isOddExponent helper",
"smallest_valid_input": {
"base": 2,
"exponent": 0,
"mod": 5,
"expected": 1
},
"ordinary_input": {
"base": 2,
"exponent": 10,
"mod": 1000,
"expected": 24
}
}
11 changes: 11 additions & 0 deletions work/R50-T026/test_output.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

 RUN  v5.1.0 /Users/fabulous_tarun8/Library/Mobile Documents/com~apple~CloudDocs/Studies/s&ai/diwaliHomework/TheAlgorithms-JavaScript

✓ Maths/test/ModularBinaryExponentiationRecursive.test.js (5 tests) 1ms

 Test Files  1 passed (1)
 Tests  5 passed (5)
 Start at  09:07:27
 Duration  88ms (transform 57%, import 17%, worker 17%, tests 8%)


4 changes: 4 additions & 0 deletions work/R50-T026/versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"node": "v26.12.1",
"npm": "11.20.0"
}