help with prime pairs code

user1234 user1234 at 12.de
Sat Feb 1 00:21:22 UTC 2025


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...


More information about the Digitalmars-d-learn mailing list