Search code examples
algorithmnumber-theoryparipari-gp

Remove duplicate during count in PARI GP


I have a problem with PARI GP : when I try to count some values, I have some duplicate, for example with this code :

for(a=12170,12170, for(p=67, 100, for(b=0,3, for(c=1,3, for(d=0,2, for(f=0,2, for(g=0,2, 
for(h=0,2, for(j=0, 2, for(k=0,2, for(l=0,2, for(q=0, 2, 
if(((3^b*5^c*11^d*13^f*19^g*29^h*37^j*53^k*59^l*61^q*p) < 2^64), s=0; for(t=1, 100, 
if(ispseudoprime(((2*a-1)*2^(t)+3^b*5^c*11^d*13^f*19^g*29^h*37^j*53^k*59^l*61^q*p)), 
s++, if(s>27, 
print(s,",",3^b*5^c*11^d*13^f*19^g*29^h*37^j*53^k*59^l*61^q*p))))))))))))))))); s

The printing is :

28,1150342765
29,1150342765
29,1150342765
28,46059899786615
28,46059899786615
28,46059899786615
28,46059899786615
28,46059899786615
28,46059899786615
28,46059899786615
28,46059899786615
28,368149925
28,368149925
28,368149925
28,368149925
28,368149925
29,368149925
28,170449675
28,170449675
28,170449675
28,170449675

And I only want this :

29,1150342765
28,46059899786615
28,170449675

I tried to change the s++ and the s=0; in the code but I have nothing that print, or these duplicate.

Is it possible to print only once ?


Solution

  • Firstly, your code can be improved by refactoring the inner loops by use of forvec. It will increase its readability a lot.

    Secondly, you can save your results in Set data structure to avoid duplicates. Below you can find your code refactored:

    param_space = {[
      [12170, 12170], \\ a
      [67, 100], \\ p
      [0, 3], \\ b
      [1, 3], \\ c
      [0, 2], \\ d
      [0, 2], \\ f
      [0, 2], \\ g
      [0, 2], \\ h
      [0, 2], \\ j
      [0, 2], \\ k
      [0, 2], \\ l
      [0, 2] \\ q
    ]};
    
    results = Set()
    forvec(params = param_space, {
      [a, p, b, c, d, f, g, h, j, k, l, q] = params;
      target = 3^b*5^c*11^d*13^f*19^g*29^h*37^j*53^k*59^l*61^q*p;
      if(target < 2^64,
        s = 0;
        for(t = 1, 100,
          if(ispseudoprime(((2*a-1)*2^(t)+target)),
             s++,
             if(s > 27,
               my(len = #results);
               results = setunion(results, [target]);
               if(#results > len, print(s, ",", target))
             )
          )
        )
      )
    });