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

Reply via email to