digitalmars.D.learn - help with prime pairs code
- Jabari Zakiya (129/129) Jan 31 I'm converting Ruby code to D and am running into issues.
- user1234 (102/107) Jan 31 A first draft of the translation, not very idiomatic D code:
- Jabari Zakiya (11/18) Feb 01 Thank you very much!
- user1234 (3/25) Feb 01 yeah Crystal is in my scope. Whyle I'm usualy not into dynamic
- user1234 (4/27) Feb 01 [Gradual
- Jabari Zakiya (86/114) Feb 01 Here's the Crystal version of the Ruby code.
- Sergey (55/61) Feb 02 First of fall make sure you are using LDC or GDC compiler. Second
- Jabari Zakiya (85/92) Feb 02 Here's the D code with the suggested changes, and other updates.
- Jabari Zakiya (36/131) Feb 02 I am really impressed!
- Sergey (7/15) Feb 02 Nice. Maybe create a github repo with results from different
- Jabari Zakiya (27/42) Feb 02 Good idea. I'll see if I'm up to it.
- monkyyy (3/6) Feb 02 translated code isnt going to be idiomatic ever; just state what
- Jabari Zakiya (11/15) Feb 04 FYI.
- Jabari Zakiya (137/155) Feb 05 I updated the code to make entering data easier.
I'm converting Ruby code to D and am running into issues. Would appreciate what needs to be done to get it to compile/run correctly. Here's the Ruby code: ``` RubyVM::YJIT.enable if RUBY_ENGINE == "ruby" and RUBY_VERSION.to_f >= 3.3 def prime_pairs_lohi(n) return puts "Input not even n > 2" unless n.even? && n > 2 return (pp [n, 1]; pp [n/2, n/2]; pp [n/2, n/2]) if n <= 6 lhr = 3.step(n/2, 2).select { |r| r if r.gcd(n) == 1 } residue limit pcp others are too end end list list r w/others values > this consecutive r’s > n-2 list with ri > n-2 lhr member end vals lhr_del = lhr_mults.map { |r_del| (r_del > ndiv2 ? n - r_del : r_del) } count n n end execution last output ``` Here's my D code. ``` module prime_pairs; import std; //import std.datetime.stopwatch : StopWatch; //import std.stdio : readf, write, writeln, readln; //import std.numeric : gcd; void prime_pairs_lohi(uint n) { if ((n|1) == 1 || n < 4) return writeln("Input not even n > 2"); //if (n <= 6) return { writel([n, 1]); writeln([n/2, n/2]); writeln([n/2, n/2])} // generate the low-half-residues (lhr) r < n/2 lhr = []; auto ndiv2 = n/2; auto rhi = n-2; auto r = 3; while (r < ndiv2) { if (gcd(r,n) == 1) lhr ~= r; r += 2; } lhr_mults = []; // for lhr values not part of a pcp // store all the powers of the lhr members < n-2 foreach(r; lhr) { // step thru the lhr members r_pwr = r; // set to first power of r if (r > rhi/r_pwr) break; // exit if r^2 > n-2, as all others are too while (r < rhi/r_pwr) { // while r^e < n-2 lhr_mults ~=(r_pwr *= r); // store its current power of r } } // store all the cross-products of the lhr members < n-2 lhr_dup = lhr.dup; // make copy of the lhr members list while ((r = lhr_dup.shift) && lhr_dup.length != 0) { ri_max = rhi / r; // ri can't multiply r with values > this if (lhr_dup[0] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr_dup) { // for each residue in reduced list if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // check cross-products of next lhr member // convert lhr_mults vals > n/2 to their lhr complements n-r, // store them, those < n/2, in lhr_del; it now holds non-pcp lhr vals lhr_del = lhr_mults.map { |r_del| (r_del > ndiv2 ? n - r_del : r_del) } lhr -= lhr_del; writeln("[", n,", ", lhr.length,"]"); // show n and pcp prime pairs count writeln("[", lhr[0], ", ", n-lhr[0], "]"); // show first pcp prime pair of n writeln("[", lhr[$-1],", ",n-lhr[$-1],"]"); // show last pcp prime pair of n } void main() { ulong[] x; foreach (_; 0 .. 1) { ulong a; readf!" %d"(a); x ~= a; } n = x[0]; auto stopWatchExecution = StopWatch(); stopWatchExecution.start(); prime_pairs_lohi(n); stopWatchExecution.stop(); writeln(stopWatchExecution.peek()); ```
Jan 31
On Friday, 31 January 2025 at 20:05:54 UTC, Jabari Zakiya wrote:I'm converting Ruby code to D and am running into issues. Would appreciate what needs to be done to get it to compile/run correctly. Here's the Ruby code: [...]A first draft of the translation, not very idiomatic D code: ```d module prime_pairs; import std; void prime_pairs_lohi(uint n) { if ((n|1) == 1 || n < 4) { return writeln("Input not even n > 2"); } if (n <= 6) { writeln([n, 1]); writeln([n/2, n/2]); writeln([n/2, n/2]); return; } // generate the low-half-residues (lhr) r < n/2 int[] lhr; auto ndiv2 = n/2; auto rhi = n-2; { auto r = 3; while (r < ndiv2) { if (gcd(r,n) == 1) lhr ~= r; r += 2; } } int[] lhr_mults; // for lhr values not part of a pcp // store all the powers of the lhr members < n-2 foreach(r; lhr) // step thru the lhr members { auto r_pwr = r; // set to first power of r if (r > rhi/r_pwr) break; // exit if r^2 > n-2, as all others are too while (r < rhi/r_pwr) // while r^e < n-2 lhr_mults ~=(r_pwr *= r);// store its current power of r } // store all the cross-products of the lhr members < n-2 auto lhr_dup = lhr.dup; // make copy of the lhr members list { auto shift(T)(ref T[] a) { if (!a.length) return -1; auto r = a[0]; a = a[1..$]; return r; } int r; while ((r = shift(lhr_dup)) != -1 && lhr_dup.length != 0) { auto ri_max = rhi / r; // ri can't multiply r with values > this if (lhr_dup[0] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr_dup) // for each residue in reduced list { if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // check cross-products of next lhr member } // convert lhr_mults vals > n/2 to their lhr complements n-r, // store them, those < n/2, in lhr_del; it now holds non-pcp lhr vals auto lhr_del = lhr_mults.map!((r_del) => r_del > ndiv2 ? n - r_del : r_del); lhr = lhr.filter!(a => !lhr_del.canFind(a)).array; writeln("[", n,", ", lhr.length,"]"); // show n and pcp prime pairs count writeln("[", lhr[0], ", ", n-lhr[0], "]"); // show first pcp prime pair of n writeln("[", lhr[$-1],", ",n-lhr[$-1],"]"); // show last pcp prime pair of n } void main() { prime_pairs_lohi(16); } ``` Results seems to match to what I see in TryRubyPlayGround. Summary of the problems I've seen in you attempt - problem of scoping (e.g loop variables) - missing storage class to declare variables - some missing 1:1 equivalent of Ruby functs `.shift` and the `-` operator on array. - lambda syntax not mastered (lhr_del mapping) A bit of learning required but should be to overcome. Now I wait for the person who will post a beautiful version with UFCS chains...
Jan 31
On Saturday, 1 February 2025 at 00:21:22 UTC, user1234 wrote:On Friday, 31 January 2025 at 20:05:54 UTC, Jabari Zakiya wrote:Thank you very much! As you can see, D is not my primary language, but I respect its speed and readability. I also have a faster Crystal version, almost identical (96%) to the Rudy code. I'm implementing it in different languages, partly as a way to learn them with a real task. I'll study the D code thoroughly to conceptually understand the idioms used int it. I, like you, also wait to see a "beautiful" version done.[...]A first draft of the translation, not very idiomatic D code: ```d module prime_pairs; import std; [...]
Feb 01
On Saturday, 1 February 2025 at 21:56:23 UTC, Jabari Zakiya wrote:On Saturday, 1 February 2025 at 00:21:22 UTC, user1234 wrote:yeah Crystal is in my scope. Whyle I'm usualy not into dynamic typed langs, there's something I like in the Crystal lang.On Friday, 31 January 2025 at 20:05:54 UTC, Jabari Zakiya wrote:Thank you very much! As you can see, D is not my primary language, but I respect its speed and readability. I also have a faster Crystal version, almost identical (96%) to the Rudy code.[...]A first draft of the translation, not very idiomatic D code: ```d module prime_pairs; import std; [...]I'm implementing it in different languages, partly as a way to learn them with a real task. I'll study the D code thoroughly to conceptually understand the idioms used int it. I, like you, also wait to see a "beautiful" version done.
Feb 01
On Sunday, 2 February 2025 at 01:12:59 UTC, user1234 wrote:On Saturday, 1 February 2025 at 21:56:23 UTC, Jabari Zakiya wrote:[Gradual typing](https://en.wikipedia.org/wiki/Gradual_typing#:~:text=Gradual%20typing%20allows%20software%20developers,static%20typing%20to%20be%20used.) That's the shit I like with Crystal.On Saturday, 1 February 2025 at 00:21:22 UTC, user1234 wrote:yeah Crystal is in my scope. Whyle I'm usualy not into dynamic typed langs, there's something I like in the Crystal lang.On Friday, 31 January 2025 at 20:05:54 UTC, Jabari Zakiya wrote:Thank you very much! As you can see, D is not my primary language, but I respect its speed and readability. I also have a faster Crystal version, almost identical (96%) to the Rudy code.[...]A first draft of the translation, not very idiomatic D code: ```d module prime_pairs; import std; [...]
Feb 01
On Sunday, 2 February 2025 at 01:39:34 UTC, user1234 wrote:On Sunday, 2 February 2025 at 01:12:59 UTC, user1234 wrote:Here's the Crystal version of the Ruby code. ``` prime_pairs_lohi.cr def prime_pairs_lohi(n) return puts "Input not even n > 2" unless n.even? && n > 2 return (pp [n, 1]; pp [n//2, n//2]; pp [n//2, n//2]) if n <= 6 lhr = 3u64.step(to: n//2, by: 2).select { |r| r if r.gcd(n) == 1 }.to_a residue limit of a pcp all others are too of r end end members list 1st list r w/others values > this consecutive r’s > n-2 reduced list cross-product with ri > n-2 next lhr member end complements first lhr -= lhr_mults.map { |r_del| r_del > ndiv2 ? n - r_del : r_del } pairs count pair of n pair of n end code execution def gen_pcp terminal runtime as last output end gen_pcp ``` Add this to the D code to take terminal input and to time execution. I don't know if this is most idiomatic, but it works. import std.datetime.stopwatch : StopWatch; void main() { int n; readf("%s", &n); auto stopWatchExecution = StopWatch(); stopWatchExecution.start(); prime_pairs_lohi(n); stopWatchExecution.stop(); writeln(stopWatchExecution.peek()); } The D version is way slower, because of the array operations. For an input of 1000000 (1M): D: 12+ secs; Crystal: 0.036 secs. In Ruby|Crystal you can just do: lhr -= lhr_mult to remove elements of one array from another, and not one at a time. I assume there's a D equivalent?!? As n increases so do those arrays, and the times become much longer.On Saturday, 1 February 2025 at 21:56:23 UTC, Jabari Zakiya wrote:[Gradual typing](https://en.wikipedia.org/wiki/Gradual_typing#:~:text=Gradual%20typing%20allows%20software%20developers,static%20typing%20to%20be%20used.) That's the shit I like with Crystal.On Saturday, 1 February 2025 at 00:21:22 UTC, user1234 wrote:yeah Crystal is in my scope. Whyle I'm usualy not into dynamic typed langs, there's something I like in the Crystal lang.On Friday, 31 January 2025 at 20:05:54 UTC, Jabari Zakiya wrote:Thank you very much! As you can see, D is not my primary language, but I respect its speed and readability. I also have a faster Crystal version, almost identical (96%) to the Rudy code.[...]A first draft of the translation, not very idiomatic D code: ```d module prime_pairs; import std; [...]
Feb 01
On Sunday, 2 February 2025 at 03:22:00 UTC, Jabari Zakiya wrote:The D version is way slower, because of the array operations. For an input of 1000000 (1M): D: 12+ secs; Crystal: 0.036 secs.First of fall make sure you are using LDC or GDC compiler. Second step is to add proper flags for optimizations (-O3). Your initial version showed on my M1 laptop: ```bash [1000000, 5402] [17, 999983] [499943, 500057] 19 secs, 367 ms, 923 μs, and 9 hnsecs ``` Then I propose some small changes: 1) You can initialize lhr with 1 row in similar logic as in Ruby/Crystal ```d uint[] lhr = iota(3, ndiv2, 2).filter!(e => gcd(e, n) == 1).array; ``` 2) The logic with shift and duplicated array could be simplified in D with simple index processing and slising (you even don't need to create duplicated array) ```d foreach(i, r; lhr) { auto ri_max = rhi / r; // ri can't multiply r with values > this if (lhr[i+1] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr[i+1..$]) // for each residue in reduced list { if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // check cross-products of next lhr member ``` But these 2 updates don't make a lot of improvements in terms of performance.In Ruby|Crystal you can just do: lhr -= lhr_mult to remove elements of one array from another, and not one at a time. I assume there's a D equivalent?!?In D we have `setDifference`, so the code instead of filter + canFind (which will be very costly in terms of big-O notation) will become ```d lhr_del.sort!("a < b"); // to use setDifference we need to have sorted arrays lhr = setDifference(lhr, lhr_del).array; ``` So after those updates the time improved ```bash [1000000, 5402] [17, 999983] [499943, 500057] 81 ms, 144 μs, and 7 hnsecs ```
Feb 02
On Sunday, 2 February 2025 at 10:26:56 UTC, Sergey wrote:So after those updates the time improved ```bash [1000000, 5402] [17, 999983] [499943, 500057] 81 ms, 144 μs, and 7 hnsecs ```Here's the D code with the suggested changes, and other updates. Note, I make the source code look like Ruby|Crystal for my esthetics. ``` // Compile with ldc2: $ ldc2 --release -O3 -mcpu native prime_pairs_lohi.d // Run as: echo 100000 | ./prime_pairs_lohi // Update: 2025/02/02 module prime_pairs; import std; import std.datetime.stopwatch : StopWatch; void prime_pairs_lohi(uint n) { if ((n&1) == 1 || n < 4) { return writeln("Input not even n > 2"); } if (n <= 6) { writeln([n, 1]); writeln([n/2, n/2]); writeln([n/2, n/2]); return; } // generate the low-half-residues (lhr) r < n/2 auto ndiv2 = n/2; // llr:hhr midpoint auto rhi = n-2; // max residue limit uint[] lhr = iota(3, ndiv2, 2).filter!(e => gcd(e, n) == 1).array; // store all the powers of the lhr members < n-2 int[] lhr_mults; // for lhr values not part of a pcp foreach(r; lhr) { // step thru the lhr members auto r_pwr = r; // set to first power of r if (r > rhi/r_pwr) break; // exit if r^2 > n-2, as all others are too while (r < rhi/r_pwr) // while r^e < n-2 lhr_mults ~=(r_pwr *= r); // store its current power of r } // store all the cross-products of the lhr members < n-2 foreach(i, r; lhr) { auto ri_max = rhi / r; // ri can't multiply r with values > this if (lhr[i+1] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr[i+1..$]) { // for each residue in reduced list if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // convert lhr_mults vals > n/2 to their lhr complements n-r, // store them, those < n/2, in lhr_del; it now holds non-pcp lhr vals auto lhr_del = lhr_mults.map!((r_del) => r_del > ndiv2 ? n - r_del : r_del).array; lhr_del.sort!("a < b"); lhr = setDifference(lhr, lhr_del).array; writeln([n, lhr.length]); // show n and pcp prime pairs count writeln([lhr[0], n-lhr[0]]); // show first pcp prime pair of n writeln([lhr[$-1],n-lhr[$-1]]); // show last pcp prime pair of n } void main() { int n; readf("%s", &n); // get input to n from terminal auto timer = StopWatch(); // create execution timer timer.start(); // start it prime_pairs_lohi(n); // run routine writeln(timer.peek()); // show timer results } ``` The D version is now faster than Crystal. ``` D (LDC2 2.40) ➜ ~ echo 100000000 |./prime_pairs_lohi [100000000, 291400] [11, 99999989] [49999757, 50000243] 7 secs, 422 ms, 641 μs, and 9 hnsecs Crystal (1.15) ➜ ~ ./prime_pairs_lohi 100_000_000 [100000000, 291400] [11, 99999989] [49999757, 50000243] 00:00:10.454055301 ``` I'll eventually do a Rust version, maybe C++, et al. I want to think everybody for the help. If you find more performance improvements please post them.
Feb 02
On Sunday, 2 February 2025 at 21:17:39 UTC, Jabari Zakiya wrote:On Sunday, 2 February 2025 at 10:26:56 UTC, Sergey wrote:I am really impressed! D is phenomenally memory efficient with this code. I just ran the D code for some really large n values. On my older Lenovo Legion 5, using Linux (June 2024) w/16GB I was able to go up to n = 1,000,000,0000 and it took up ~14.4GB max, out of ~14.9GB usable. I got a new, fast TUXEDO Gen 3, w/64GB (Jan 2025), so I'm going to how high I can go on it. Here are some results on the Lenovo Legion 5. ``` ➜ ~ echo 500000000 |./prime_pairs_lohi3 [500000000, 1219610] [7, 499999993] [249999877, 250000123] 43 secs, 402 ms, 950 μs, and 3 hnsecs ➜ ~ ➜ ~ echo 900000000 |./prime_pairs_lohi3 [900000000, 4132595] [37, 899999963] [449999993, 450000007] 36 secs, 135 ms, 163 μs, and 6 hnsecs ➜ ~ ➜ ~ echo 1000000000 |./prime_pairs_lohi3 [1000000000, 2274205] [71, 999999929] [499999931, 500000069] 1 minute, 32 secs, 87 ms, 624 μs, and 8 hnsecs ➜ ~ ➜ ~ echo 1500000000 |./prime_pairs_lohi3 [1500000000, 6543613] [43, 1499999957] [749999927, 750000073] 1 minute, 6 secs, 205 ms, 381 μs, and 5 hnsecs ➜ ~ ```So after those updates the time improved ```bash [1000000, 5402] [17, 999983] [499943, 500057] 81 ms, 144 μs, and 7 hnsecs ```Here's the D code with the suggested changes, and other updates. Note, I make the source code look like Ruby|Crystal for my esthetics. ``` // Compile with ldc2: $ ldc2 --release -O3 -mcpu native prime_pairs_lohi.d // Run as: echo 100000 | ./prime_pairs_lohi // Update: 2025/02/02 module prime_pairs; import std; import std.datetime.stopwatch : StopWatch; void prime_pairs_lohi(uint n) { if ((n&1) == 1 || n < 4) { return writeln("Input not even n > 2"); } if (n <= 6) { writeln([n, 1]); writeln([n/2, n/2]); writeln([n/2, n/2]); return; } // generate the low-half-residues (lhr) r < n/2 auto ndiv2 = n/2; // llr:hhr midpoint auto rhi = n-2; // max residue limit uint[] lhr = iota(3, ndiv2, 2).filter!(e => gcd(e, n) == 1).array; // store all the powers of the lhr members < n-2 int[] lhr_mults; // for lhr values not part of a pcp foreach(r; lhr) { // step thru the lhr members auto r_pwr = r; // set to first power of r if (r > rhi/r_pwr) break; // exit if r^2 > n-2, as all others are too while (r < rhi/r_pwr) // while r^e < n-2 lhr_mults ~=(r_pwr *= r); // store its current power of r } // store all the cross-products of the lhr members < n-2 foreach(i, r; lhr) { auto ri_max = rhi / r; // ri can't multiply r with values > this if (lhr[i+1] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr[i+1..$]) { // for each residue in reduced list if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // convert lhr_mults vals > n/2 to their lhr complements n-r, // store them, those < n/2, in lhr_del; it now holds non-pcp lhr vals auto lhr_del = lhr_mults.map!((r_del) => r_del > ndiv2 ? n - r_del : r_del).array; lhr_del.sort!("a < b"); lhr = setDifference(lhr, lhr_del).array; writeln([n, lhr.length]); // show n and pcp prime pairs count writeln([lhr[0], n-lhr[0]]); // show first pcp prime pair of n writeln([lhr[$-1],n-lhr[$-1]]); // show last pcp prime pair of n } void main() { int n; readf("%s", &n); // get input to n from terminal auto timer = StopWatch(); // create execution timer timer.start(); // start it prime_pairs_lohi(n); // run routine writeln(timer.peek()); // show timer results } ``` The D version is now faster than Crystal. ``` D (LDC2 2.40) ➜ ~ echo 100000000 |./prime_pairs_lohi [100000000, 291400] [11, 99999989] [49999757, 50000243] 7 secs, 422 ms, 641 μs, and 9 hnsecs Crystal (1.15) ➜ ~ ./prime_pairs_lohi 100_000_000 [100000000, 291400] [11, 99999989] [49999757, 50000243] 00:00:10.454055301 ``` I'll eventually do a Rust version, maybe C++, et al. I want to think everybody for the help. If you find more performance improvements please post them.
Feb 02
On Sunday, 2 February 2025 at 22:40:41 UTC, Jabari Zakiya wrote:I am really impressed! D is phenomenally memory efficient with this code. I just ran the D code for some really large n values. On my older Lenovo Legion 5, using Linux (June 2024) w/16GB I was able to go up to n = 1,000,000,0000 and it took up ~14.4GB max, out of ~14.9GB usable. I got a new, fast TUXEDO Gen 3, w/64GB (Jan 2025), so I'm going to how high I can go on it.Nice. Maybe create a github repo with results from different languages. It will be interesting to see the comparison. I haven't checked other parts of the code - maybe it is possible to improve the performance a bit more (to reduce some allocations, use `appender` instead of `~=` operator) But will see what other will produce first :)
Feb 02
On Monday, 3 February 2025 at 00:04:17 UTC, Sergey wrote:On Sunday, 2 February 2025 at 22:40:41 UTC, Jabari Zakiya wrote:Good idea. I'll see if I'm up to it. Another code opt for you. I translated this Ruby code: lhr_del = lhr_mults.map { |r_del| (r_del > ndiv2 ? n - r_del : r_del) } lhr_rmax high bound lhr <= lhr_rmax prime residues prime residues <= lhr_rmax To this D code. It works, seems fast, can it be done shorter, faster, more idiomatic? auto lhr_del = lhr_mults.map!((r_del) => r_del > ndiv2 ? n - r_del : r_del).array; lhr_del.sort!("a < b"); auto lhr_rmax = 2 + cast(uint) sqrt(cast(double) n-2); auto lhr_rmax_cnt = 0; foreach(r; lhr) { if (r > lhr_rmax) break; lhr_rmax_cnt += 1;} lhr = setDifference(lhr, lhr_del).array; uint[] pcp_rmax; foreach(pcp; lhr) { if (pcp > lhr_rmax) break; pcp_rmax ~= pcp; }I am really impressed! D is phenomenally memory efficient with this code. I just ran the D code for some really large n values. On my older Lenovo Legion 5, using Linux (June 2024) w/16GB I was able to go up to n = 1,000,000,0000 and it took up ~14.4GB max, out of ~14.9GB usable. I got a new, fast TUXEDO Gen 3, w/64GB (Jan 2025), so I'm going to how high I can go on it.Nice. Maybe create a github repo with results from different languages. It will be interesting to see the comparison. I haven't checked other parts of the code - maybe it is possible to improve the performance a bit more (to reduce some allocations, use `appender` instead of `~=` operator) But will see what other will produce first :)
Feb 02
On Monday, 3 February 2025 at 04:15:09 UTC, Jabari Zakiya wrote:I translated this Ruby code: To this D code. It works, seems fast, can it be done shorter, faster, more idiomatic?translated code isnt going to be idiomatic ever; just state what you want done
Feb 02
On Monday, 3 February 2025 at 04:59:43 UTC, monkyyy wrote:On Monday, 3 February 2025 at 04:15:09 UTC, Jabari Zakiya wrote:FYI. This code finds all the prime pairs that sum to n for all even integers n > 2. It (Ruby code) is included in a paper I just released (Feb 2, 2025) on Goldbach's Conjecture (1742) and Bertrand's Postulate (1845). For those interested in Prime|Number Theory check it out. A lot of new, good, stuff is in it! **Proof of Goldbach's Conjecture and Bertrand's Postulate Using Prime Generator Theory (PGT)** https://www.academia.edu/127404211/Proof_of_Goldbachs_Conjecture_and_Bertrands_Postulate_Using_Prime_Generator_Theory_PGT_I translated this Ruby code:
Feb 04
On Tuesday, 4 February 2025 at 17:17:42 UTC, Jabari Zakiya wrote:On Monday, 3 February 2025 at 04:59:43 UTC, monkyyy wrote:I updated the code to make entering data easier. It now mimics the Ruby|Crystal code and takes "humanized" data strings. You can now run the code as: `$ ./primes_pair_lohi_u32 123_456_780` I also created two versions, one for u32 input values, and one for u64. Unless you have lots of memmory, the u32 version is best to use. Here's the u32 input size version. // Compile with ldc2: $ ldc2 --release -O3 -mcpu native prime_pairs_lohi_u32.d // Run as: $ ./prime_pairs_lohi_u32 123_456_780 module prime_pairs; import std; import std.datetime.stopwatch : StopWatch; void prime_pairs_lohi(uint n) { // inputs can be of size u32 if ((n&1) == 1 || n < 4) { return writeln("Input not even nOn Monday, 3 February 2025 at 04:15:09 UTC, Jabari Zakiya wrote:FYI. This code finds all the prime pairs that sum to n for all even integers n > 2. It (Ruby code) is included in a paper I just released (Feb 2, 2025) on Goldbach's Conjecture (1742) and Bertrand's Postulate (1845). For those interested in Prime|Number Theory check it out. A lot of new, good, stuff is in it! **Proof of Goldbach's Conjecture and Bertrand's Postulate Using Prime Generator Theory (PGT)** https://www.academia.edu/127404211/Proof_of_Goldbachs_Conjecture_and_Bertrands_Postulate_Using_Prime_Generator_Theory_PGT_I translated this Ruby code:2"); }if (n <= 6) { writeln([n, 1]); writeln([n/2, n/2]); writeln([n/2, n/2]); return; } // generate the low-half-residues (lhr) r < n/2 auto ndiv2 = n/2; // llr:hhr midpoint auto rhi = n-2; // max residue limit uint[] lhr = iota(3, ndiv2, 2).filter!(e => gcd(e, n) == 1).array; // store all the powers of the lhr members < n-2 uint[] lhr_mults; // for lhr values not part of a pcp foreach(r; lhr) { // step thru the lhr members auto r_pwr = r; // set to first power of r if (r > rhi/r_pwr) break; // exit if r^2 > n-2, as all others are too while (r < rhi/r_pwr) // while r^e < n-2 lhr_mults ~=(r_pwr *= r); // store its current power of rA } // store all the cross-products of the lhr members < n-2 foreach(i, r; lhr) { auto ri_max = rhi / r; // ri can't multiply r with values > this if (lhr[i+1] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr[i+1..$]) { // for each residue in reduced list if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // convert lhr_mults vals > n/2 to their lhr complements n-r, // store them, those < n/2, in lhr_del; it now holds non-pcp lhr vals auto lhr_del = lhr_mults.map!((r_del) => r_del > ndiv2 ? n - r_del : r_del).array; lhr_del.sort!("a < b"); lhr = setDifference(lhr, lhr_del).array; writeln([n, lhr.length]); // show n and pcp prime pairs count writeln([lhr[0], n-lhr[0]]); // show first pcp prime pair of n writeln([lhr[$-1],n-lhr[$-1]]); // show last pcp prime pair of n } void main(string[] args) { // directly recieve input from terminal string[] inputs = args[1..$]; // can include '_': 123_456 auto nums = inputs.map!(i => i.filter!(n => n != '_')); auto n = nums.map!(f => f.to!uint())[0]; auto timer = StopWatch(); // create execution timer timer.start(); // start it prime_pairs_lohi(n); // run routine writeln(timer.peek()); // show timer results } Here's the u64 version. // Compile with ldc2: $ ldc2 --release -O3 -mcpu native prime_pairs_lohi_u64.d // Run as: $ ./prime_pairs_lohi_u64 123_456_780 module prime_pairs; import std; import std.datetime.stopwatch : StopWatch; void prime_pairs_lohi(ulong n) { // inputs can be of size u64 if ((n&1) == 1 || n < 4) { return writeln("Input not even n2"); }if (n <= 6) { writeln([n, 1]); writeln([n/2, n/2]); writeln([n/2, n/2]); return; } // generate the low-half-residues (lhr) r < n/2 auto ndiv2 = n/2; // llr:hhr midpoint auto rhi = n-2; // max residue limit ulong[] lhr = iota(3, ndiv2, 2).filter!(e => gcd(e, n) == 1).array; // store all the powers of the lhr members < n-2 ulong[] lhr_mults; // for lhr values not part of a pcp foreach(r; lhr) { // step thru the lhr members auto r_pwr = r; // set to first power of r if (r > rhi/r_pwr) break; // exit if r^2 > n-2, as all others are too while (r < rhi/r_pwr) // while r^e < n-2 lhr_mults ~=(r_pwr *= r); // store its current power of rA } // store all the cross-products of the lhr members < n-2 foreach(i, r; lhr) { auto ri_max = rhi / r; // ri can't multiply r with values > this if (lhr[i+1] > ri_max) break; // exit if product of consecutive r’s > n-2 foreach(ri; lhr[i+1..$]) { // for each residue in reduced list if (ri > ri_max) break; // exit for r if cross-product with ri > n-2 lhr_mults ~= r * ri; // store value if < n-2 } } // convert lhr_mults vals > n/2 to their lhr complements n-r, // store them, those < n/2, in lhr_del; it now holds non-pcp lhr vals auto lhr_del = lhr_mults.map!((r_del) => r_del > ndiv2 ? n - r_del : r_del).array; lhr_del.sort!("a < b"); lhr = setDifference(lhr, lhr_del).array; writeln([n, lhr.length]); // show n and pcp prime pairs count writeln([lhr[0], n-lhr[0]]); // show first pcp prime pair of n writeln([lhr[$-1],n-lhr[$-1]]); // show last pcp prime pair of n } void main(string[] args) { // directly recieve input from terminal string[] inputs = args[1..$]; // can include '_': 123_456 auto nums = inputs.map!(i => i.filter!(n => n != '_')); auto n = nums.map!(f => f.to!ulong())[0]; auto timer = StopWatch(); // create execution timer timer.start(); // start it prime_pairs_lohi(n); // run routine writeln(timer.peek()); // show timer results }
Feb 05