import random import unittest from sparse_table import SparseTable class TestSparseTable(unittest.TestCase): def test_min_basic(self): a = [3, 1, 4, 1, 5, 9, 2, 6] st = SparseTable(a) self.assertEqual(st.query(0, 7), 1) self.assertEqual(st.query(1, 4), 1) self.assertEqual(st.query(2, 5), 1) self.assertEqual(st.query(6, 7), 2) def test_single(self): st = SparseTable([42]) self.assertEqual(st.query(0, 0), 42) def test_empty_raises(self): st = SparseTable([]) with self.assertRaises(IndexError): st.query(0, 0) def test_invalid_range(self): st = SparseTable([1, 2, 3]) for l, r in [(-1, 1), (0, 3), (2, 1)]: with self.assertRaises(IndexError): st.query(l, r) def test_max_func(self): a = [3, 1, 4, 1, 5, 9, 2, 6] st = SparseTable(a, func=max) self.assertEqual(st.query(0, 7), 9) self.assertEqual(st.query(1, 4), 5) def test_gcd_func(self): import math a = [12, 18, 24, 30] st = SparseTable(a, func=math.gcd) self.assertEqual(st.query(0, 3), 6) self.assertEqual(st.query(1, 2), 6) def test_fuzz_min(self): rng = random.Random(7) for _ in range(200): n = rng.randint(1, 60) a = [rng.randint(-100, 100) for _ in range(n)] st = SparseTable(a) for _ in range(50): l = rng.randrange(n) r = rng.randrange(l, n) self.assertEqual(st.query(l, r), min(a[l:r + 1])) def test_fuzz_max(self): rng = random.Random(9) for _ in range(100): n = rng.randint(1, 40) a = [rng.randint(-50, 50) for _ in range(n)] st = SparseTable(a, func=max) for _ in range(30): l = rng.randrange(n) r = rng.randrange(l, n) self.assertEqual(st.query(l, r), max(a[l:r + 1])) if __name__ == "__main__": unittest.main()