Skip to content

Commit 0a444af

Browse files
unordered_map
1 parent 242547e commit 0a444af

File tree

1 file changed

+42
-43
lines changed

1 file changed

+42
-43
lines changed

FindAFactor/_find_a_factor.cpp

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,7 @@ struct Factorizer {
764764
std::vector<uint16_t> primes;
765765
ForwardFn forwardFn;
766766
std::map<BigInteger, boost::dynamic_bitset<size_t>> smoothNumberMap;
767+
std::unordered_map<boost::dynamic_bitset<size_t>, BigInteger> hashMap;
767768

768769
Factorizer(const BigInteger &tfsqr, const BigInteger &tf, const BigInteger &tfsqrt, const BigInteger &range, size_t nodeCount, size_t nodeId, size_t w, size_t spl,
769770
const std::vector<uint16_t> &p, ForwardFn fn)
@@ -879,75 +880,73 @@ struct Factorizer {
879880
// WRITTEN BY ELARA (GPT) BELOW //
880881
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
881882

882-
// Find factor via Gaussian elimination
883+
// Find duplicate rows
883884
BigInteger findFactor(const BigInteger &target) {
884-
// Check for linear dependencies and find a congruence of squares
885-
std::mutex rowMutex;
885+
std::mutex toStrikeMtx;
886+
std::mutex hashMapMtx;
886887
BigInteger result = 1U;
887888
std::set<BigInteger> toStrike;
888-
auto iIt = smoothNumberMap.begin();
889-
const size_t rowCount = smoothNumberMap.size();
890-
const size_t rowCountMin1 = rowCount - 1U;
891-
for (size_t i = 0U; (i < rowCountMin1) && (result == 1U); ++i) {
892-
dispatch.dispatch([&target, i, iIt, &rowCount, &result, &toStrike, &rowMutex]() -> bool {
893-
boost::dynamic_bitset<size_t> &iRow = iIt->second;
894-
auto jIt = iIt;
895-
for (size_t j = i + 1U; j < rowCount; ++j) {
896-
++jIt;
897-
898-
boost::dynamic_bitset<size_t> &jRow = jIt->second;
899-
if (iRow != jRow) {
900-
continue;
889+
auto rIt = smoothNumberMap.begin();
890+
std::advance(rIt, hashMap.size());
891+
for (size_t row = hashMap.size(); (row < smoothNumberMap.size()) && (result == 1U); ++row) {
892+
dispatch.dispatch([this, &target, row, rIt, &toStrikeMtx, &hashMapMtx, &toStrike, &result] {
893+
const auto& binaryRow = rIt->second;
894+
// Check if the row already exists in the map
895+
BigInteger duplicateRow;
896+
// For lock_guard scope
897+
if (true) {
898+
std::lock_guard<std::mutex> lock(hashMapMtx);
899+
const auto found = this->hashMap.find(binaryRow);
900+
if (found == this->hashMap.end()) {
901+
this->hashMap[binaryRow] = row;
902+
903+
return false;
901904
}
905+
duplicateRow = found->second;
906+
}
902907

903-
if (true) {
904-
std::lock_guard<std::mutex> lock(rowMutex);
905-
toStrike.insert(jIt->first);
906-
}
907-
908-
// Compute x and y
909-
const BigInteger x = (iIt->first * jIt->first) % target;
910-
const BigInteger y = modExp(x, target >> 1U, target);
911-
912-
// Check congruence of squares
913-
BigInteger factor = gcd(target, x + y);
914-
if ((factor != 1U) && (factor != target)) {
915-
std::lock_guard<std::mutex> lock(rowMutex);
916-
result = factor;
908+
// Compute x and y
909+
const BigInteger x = (rIt->first * duplicateRow) % target;
910+
const BigInteger y = modExp(x, target >> 1U, target);
917911

918-
return true;
919-
}
912+
// Check congruence of squares
913+
BigInteger factor = gcd(target, x + y);
914+
if ((factor != 1U) && (factor != target)) {
915+
std::lock_guard<std::mutex> lock(toStrikeMtx);
916+
result = factor;
920917

921-
if (x == y) {
922-
continue;
923-
}
918+
return true;
919+
}
924920

921+
if (x != y) {
925922
// Try x - y as well
926923
factor = gcd(target, x - y);
927924
if ((factor != 1U) && (factor != target)) {
928-
std::lock_guard<std::mutex> lock(rowMutex);
925+
std::lock_guard<std::mutex> lock(toStrikeMtx);
929926
result = factor;
930927

931928
return true;
932929
}
933930
}
934931

932+
if (rIt->first < duplicateRow) {
933+
std::lock_guard<std::mutex> lock(toStrikeMtx);
934+
toStrike.insert(duplicateRow);
935+
} else {
936+
std::lock_guard<std::mutex> lock(toStrikeMtx);
937+
toStrike.insert(rIt->first);
938+
}
939+
935940
return false;
936941
});
937-
++iIt;
942+
++rIt;
938943
}
939944
dispatch.finish();
940945

941-
if (result != 1U) {
942-
return result;
943-
}
944-
945946
// These numbers have been tried already:
946947
for (const BigInteger& i : toStrike) {
947948
smoothNumberMap.erase(i);
948949
}
949-
950-
return 1U; // No factor found
951950
}
952951

953952
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)