Skip to content

Commit 346296b

Browse files
committed
refactor: Ensure unique factors in prime_primitive_root for compile-time
1 parent 5380f1c commit 346296b

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

weilycoder/number-theory/primitive_root.hpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,33 @@ constexpr uint64_t prime_primitive_root(uint64_t p) {
6969
if (!is_prime(p))
7070
return 0;
7171
auto factors = factorize_fixed<N, bit32>(p - 1);
72-
auto factor_end = std::unique(factors.begin(), factors.end());
73-
if (factor_end != factors.end())
74-
*factor_end = 0;
72+
auto factors_set = std::array<uint64_t, N>{};
73+
size_t factor_count = 0;
74+
for (size_t i = 0; i < N; ++i) {
75+
uint64_t q = factors[i];
76+
if (q == 0)
77+
break;
78+
if (i == 0 || q != factors[i - 1])
79+
factors_set[factor_count++] = q;
80+
}
7581
for (uint64_t g = 2; g < p; ++g)
76-
if (is_primitive_root<64, bit32>(g, p, factors))
82+
if (is_primitive_root<N, bit32>(g, p, factors_set))
7783
return g;
7884
return 0;
7985
}
86+
87+
/**
88+
* @brief Find a primitive root modulo a prime (compile-time version)
89+
* @tparam prime The prime modulus
90+
* @return A primitive root modulo prime.
91+
*/
92+
template <uint64_t prime> constexpr uint64_t prime_primitive_root() {
93+
if constexpr (prime == 2)
94+
return 1;
95+
if (prime < UINT32_MAX)
96+
return prime_primitive_root<true, 32>(prime);
97+
return prime_primitive_root<false, 64>(prime);
98+
}
8099
} // namespace weilycoder
81100

82101
#endif

0 commit comments

Comments
 (0)