2929#include < cctype>
3030#include < regex>
3131#include < string>
32+ #include < unordered_set>
3233
3334namespace io {
3435
@@ -72,6 +73,83 @@ static std::string toUpper(const std::string& s){
7273 return t;
7374}
7475
76+ static std::vector<std::string> splitAndUniqFactorsBySelfDivision (
77+ const std::vector<std::string>& inFactors
78+ ) {
79+ std::vector<mpz_class> f;
80+ f.reserve (inFactors.size ());
81+ for (const auto & s : inFactors) {
82+ if (s.empty ()) continue ;
83+ mpz_class x;
84+ if (x.set_str (s, 10 ) != 0 ) continue ;
85+ if (x < 0 ) x = -x;
86+ if (x > 1 ) f.push_back (x);
87+ }
88+
89+ auto normalize = [&](){
90+ f.erase (std::remove_if (f.begin (), f.end (),
91+ [](const mpz_class& v){ return v <= 1 ; }),
92+ f.end ());
93+ std::sort (f.begin (), f.end ());
94+ };
95+
96+ normalize ();
97+
98+ bool changed = true ;
99+ while (changed) {
100+ changed = false ;
101+ normalize ();
102+
103+ for (size_t i = 0 ; i < f.size () && !changed; ++i) {
104+ for (size_t j = 0 ; j < f.size (); ++j) {
105+ if (i == j) continue ;
106+ if (f[j] <= 1 ) continue ;
107+
108+ if (f[i] > f[j]) {
109+ if (mpz_divisible_p (f[i].get_mpz_t (), f[j].get_mpz_t ())) {
110+ mpz_class q;
111+ mpz_tdiv_q (q.get_mpz_t (), f[i].get_mpz_t (), f[j].get_mpz_t ());
112+ f[i] = f[j];
113+ if (q > 1 ) f.push_back (q);
114+
115+ changed = true ;
116+ break ;
117+ }
118+ }
119+ }
120+ }
121+ if (changed) continue ;
122+
123+ for (size_t i = 0 ; i < f.size () && !changed; ++i) {
124+ for (size_t j = i + 1 ; j < f.size () && !changed; ++j) {
125+ mpz_class g;
126+ mpz_gcd (g.get_mpz_t (), f[i].get_mpz_t (), f[j].get_mpz_t ());
127+
128+ if (g > 1 && g < f[i] && g < f[j]) {
129+ mpz_class ai, bj;
130+ mpz_tdiv_q (ai.get_mpz_t (), f[i].get_mpz_t (), g.get_mpz_t ());
131+ mpz_tdiv_q (bj.get_mpz_t (), f[j].get_mpz_t (), g.get_mpz_t ());
132+
133+ f[i] = g;
134+ f[j] = bj;
135+ if (ai > 1 ) f.push_back (ai);
136+
137+ changed = true ;
138+ }
139+ }
140+ }
141+ }
142+
143+ normalize ();
144+ f.erase (std::unique (f.begin (), f.end ()), f.end ());
145+
146+ std::vector<std::string> out;
147+ out.reserve (f.size ());
148+ for (const auto & x : f) out.push_back (x.get_str (10 ));
149+ return out;
150+ }
151+
152+
75153std::tuple<bool , std::string, std::string> JsonBuilder::computeResult (
76154 const std::vector<uint64_t >& hostResult,
77155 const CliOptions& opts,
@@ -259,7 +337,8 @@ static std::string generatePrimeNetJson(
259337 const std::string &aid,
260338 const std::string ×tamp,
261339 const std::string &computer,
262- const std::vector<std::string>& knownFactors)
340+ const std::vector<std::string>& knownFactors,
341+ const std::vector<std::string>& knownFactors_start)
263342{
264343 std::string canonWT;
265344 if (worktype == " prp" ) canonWT = " PRP-3" ;
@@ -269,25 +348,52 @@ static std::string generatePrimeNetJson(
269348 int torsion = opts.notorsion ? 0 : (opts.torsion16 ? 16 : 8 );
270349 std::ostringstream oss;
271350
272- std::vector<std::string> uniqFactors;
273- uniqFactors.reserve (knownFactors.size ());
274- for (const auto & f : knownFactors) {
275- if (std::find (uniqFactors.begin (), uniqFactors.end (), f) == uniqFactors.end ()) {
276- uniqFactors.push_back (f);
351+
352+ std::vector<std::string> startFactors =
353+ splitAndUniqFactorsBySelfDivision (knownFactors_start);
354+
355+ std::vector<std::string> allFactors = knownFactors;
356+ allFactors.insert (allFactors.end (), startFactors.begin (), startFactors.end ());
357+
358+ std::vector<std::string> allSplit =
359+ splitAndUniqFactorsBySelfDivision (allFactors);
360+
361+ std::unordered_set<std::string> startSet (startFactors.begin (), startFactors.end ());
362+
363+ std::vector<std::string> newFactors;
364+ newFactors.reserve (allSplit.size ());
365+ for (const auto & f : allSplit) {
366+ if (!startSet.count (f)) newFactors.push_back (f);
367+ }
368+
369+ std::string factorStr;
370+ std::string factorStrQuoted;
371+
372+ if (!newFactors.empty ()) {
373+ factorStr = newFactors[0 ];
374+ factorStrQuoted = " \" " + newFactors[0 ];
375+ for (size_t i = 1 ; i < newFactors.size (); ++i) {
376+ factorStr += " ," + newFactors[i];
377+ factorStrQuoted += " \" ,\" " + newFactors[i];
277378 }
379+ factorStrQuoted += " \" " ;
278380 }
279381
280- std::string knownFactorStr; // e.g. 204453287,1255070097822910516312001 -- for use in checksum
281- std::string knownFactorStrQuoted; // e.g. "204453287","1255070097822910516312001" -- for use in JSON, note is already quoted and MUST NOT be wrapped in jsonEscape()
282- if (!uniqFactors .empty ()) {
283- knownFactorStr = uniqFactors [0 ];
284- knownFactorStrQuoted = " \" " + uniqFactors [0 ];
285- for (size_t i = 1 ; i < uniqFactors .size (); ++i) {
286- knownFactorStr += " ," + uniqFactors [i];
287- knownFactorStrQuoted += " \" ,\" " + uniqFactors [i];
382+ std::string startFactorStr;
383+ std::string startFactorStrQuoted;
384+ if (!startFactors .empty ()) {
385+ startFactorStr = startFactors [0 ];
386+ startFactorStrQuoted = " \" " + startFactors [0 ];
387+ for (size_t i = 1 ; i < startFactors .size (); ++i) {
388+ startFactorStr += " ," + startFactors [i];
389+ startFactorStrQuoted += " \" ,\" " + startFactors [i];
288390 }
289- knownFactorStrQuoted += " \" " ;
391+ startFactorStrQuoted += " \" " ;
290392 }
393+ std::cerr << " [DBG] knownFactors_start=" << knownFactors_start.size ()
394+ << " knownFactors=" << knownFactors.size ()
395+ << " startFactors=" << startFactors.size ()
396+ << " newFactors=" << newFactors.size () << " \n " ;
291397
292398 oss << " {" ;
293399 oss << " \" status\" :" << jsonEscape (status);
@@ -296,9 +402,17 @@ static std::string generatePrimeNetJson(
296402 if (!knownFactors.empty ()) {
297403 // *** TODO: this is totally wrong, "known-factors" and "factors" are two ENTIRELY separate things, and should be better stored in the PrMers data structure
298404 if ((worktype == " ll" ) || (worktype == " llsafe" ) || (worktype == " prp" )) {
299- oss << " ,\" known-factors\" :[" << knownFactorStrQuoted << " ]" ;
405+ oss << " ,\" known-factors\" :[" << startFactorStrQuoted << " ]" ;
300406 } else {
301- oss << " ,\" factors\" :[" << knownFactorStrQuoted << " ]" ;
407+ if (!newFactors.empty ()) {
408+ oss << " ,\" factors\" :[" << factorStrQuoted << " ]" ;
409+ }
410+
411+ // Facteurs connus avant le run (worktodo)
412+ if (!startFactors.empty ()) {
413+ oss << " ,\" known-factors\" :[" << startFactorStrQuoted << " ]" ;
414+ }
415+
302416 }
303417 }
304418 if (opts.B1 > 0 ) {
@@ -365,15 +479,18 @@ static std::string generatePrimeNetJson(
365479 std::string canonWTNorm = canonWT;
366480 if (canonWTNorm == " PRP-3" || canonWTNorm == " prp-3" ) canonWTNorm = " PRP" ;
367481 canon << canonWTNorm << " ;" ; // worktype
368- if (!(canonWTNorm == " PRP" ) && !knownFactors.empty ()) {
482+ /* if (!(canonWTNorm == "PRP") && !knownFactors.empty()) {
369483 canon << knownFactorStr; // factors
370484 }
371485 canon << ";";
372486 if ((canonWTNorm == "PRP") && !knownFactors.empty()) {
373487 canon << knownFactorStr; // factors
374- }
375-
376- canon << " " << " ;" ; // known-factors *** TODO: not yet supported (factors that were known BEFORE this factoring run and included in worktodo.txt, distinct from factors just found ***
488+ }*/
489+ canon << factorStr;
490+ canon << " ;" ;
491+ canon << startFactorStr;
492+ canon << " ;" ;
493+ // known-factors *** TODO: not yet supported (factors that were known BEFORE this factoring run and included in worktodo.txt, distinct from factors just found ***
377494
378495 if (canonWT == " TF" ) {
379496 // *** TODO: not yet not yet implemented ***
@@ -441,7 +558,7 @@ static std::string generatePrimeNetJson(
441558 oss.str (" " ); oss.clear ();
442559 oss << prefix
443560 << " ,\" checksum\" :{\" version\" :1,\" checksum\" :\" " << hexss.str () << " \" }"
444- // << ",\"hash\":\"" << canon.str() << "\""
561+ << " ,\" hash\" :\" " << canon.str () << " \" "
445562 // << ",\"code-hash\":" << jsonEscape(util::code_hash_crc32_upper8())
446563 << " }" ;
447564 return oss.str ();
@@ -494,7 +611,8 @@ std::string JsonBuilder::generate(const CliOptions& opts,
494611 opts.aid ,
495612 timestampBuf,
496613 opts.computer_name ,
497- opts.knownFactors
614+ opts.knownFactors ,
615+ opts.knownFactors_start
498616 );
499617}
500618
0 commit comments