OK, **I finally got it to compile with the original iteration count** , but man, did I have to jump through hoops to do it.
To reduce the number of loops, instead of doing `brute force trial-and-error` to test each residue against the others to find its inverse, I found the code here `https://rosettacode.org/wiki/Modular_inverse#Nim` on Rosetta Code, that had a Nim version already done. [Notice: the code there doesn't compile without changing `proc mulInv(a0, b0): int =` to `proc mulInv(a0, b0: int): int =`. In fact, quite a few of those old Rosetta code Nim examples don't compile, but I digress.] proc mulInv(a0, b0: int): int = var (a, b, x0) = (a0, b0, 0) result = 1 if b == 1: return while a > 1: let q = a div b a = a mod b swap a, b result = result - q * x0 swap x0, result if result < 0: result += b0 Then I was able to eliminate the loop-in-a-loop construct, and just do this: var inverses: seq[int] = @[] for res in residues: inverses.add(mulInv(res,modpg)) I was trying to avoid using another function just to do this, since I don't use it at runtime, but you do what you gotta do. Does Nim already have this function in its library? If not, can you please add it (math lib, etc). Below is final code that compiles with original compiler iteration value, with some added diagnostic checks. # Compute modular inverse of a to base b, e.g. a*a_invese mod m = 1 proc mulInv(a0, b0: int): int = var (a, b, x0) = (a0, b0, 0) result = 1 if b == 1: return while a > 1: let q = a div b a = a mod b swap a, b result = result - q * x0 swap x0, result if result < 0: result += b0 # Create constant parameters for chosen PG at compile time proc genPGparameters(prime: int): (int, int, int, seq[int], seq[int], seq[int]) = echo("generating parameters for P", prime) let primes = [2, 3, 5, 7, 11, 13, 17, 19, 23] var modpg = 1 for prm in primes: (modpg *= prm; if prm == prime: break) var pc = 1 var residues: seq[int] = @[] while pc < modpg: (pc += 2; if gcd(modpg, pc) == 1: residues.add(pc)) let rescnt = residues.len var restwins: seq[int] = @[] var j = 0 while j < rescnt-1: if residues[j]+2 == residues[j+1]: restwins.add residues[j]; restwins.add residues[j+1]; j += 1 j += 1 let rescntp = restwins.len inverses: seq[int] = @[] for res in residues: inverses.add(mulInv(res,modpg)) echo("residues size = ", residues.len) echo("inverses size = ", inverses.len) for j in 0..residues.len-1: (if residues[j]*inverses[j] mod modpg != 1: echo("error at index ",j)) result = (modpg, rescnt, rescntp, residues, restwins, inverses) # Generate at compile time the parameters for P13 const parameters = genPGparameters(13) This must be is under the `Magical Limit` using P13. So what will it do with P17? And the answer is.......Nope! It bombs (again) when trying to compute the 92,160 values for the `residues` array, as it never gets to the inverse array computation. I ultimately tried changing the iteration variable upto 1 trillion again before giving up. I think I will need to rebuild Nim with a new value in that file to make it take. That's for tomorrow (maybe), unless someone can instruct me how to do it without rebuilding Nim. So, at least partial success, and I have learned something new and useful. **But Please, FIX THIS!, and DOCUMENT IT!**