Single returns with iteration in a range

46 views
Skip to first unread message

u220e

unread,
May 8, 2020, 5:13:57 PM5/8/20
to sage-support


Hi. I'm trying to generate a list of pairs of primes (x,y) within a range of values such that the digit length of their products is between 19 and 35. I've written a few different code variations that (unfortunately) either (1) generate ALL the integer pairs (that equal 19, 20, 21, etc.) or (2) never seem to halt. 

I really want the iteration to be as follows: find the first pair that equals 19, then locate the first pair that equals 20, and so on so until I have one list of 17 pairs of primes---one pair for each digit length. Here's what I have so far:

x=var('x')
y=var('y')
for x in sxrange (10**9,10**(36)):
   for y in sxrange (961748941,982451653):
      if x.is_prime()==1 and y.is_prime()==1:
            if (floor(log((x*y),10)+1)<=35)==1:
               print(x,y); print(floor(log((x*y),10)+1); break

Then I tried defining y=982451653 so I could use only one iterable using the following code:

for x in sxrange (10**9,10**(36)):
   if x.is_prime()==1:
      if (floor(log((x*y),10)+1)>=19)==1:
         continue
      print(x,y); print(floor(log((x*y),10)+1); break

which returns only one value:

1000000007 982451653
18

Sorry for the n00b post. I've only been using Sage for three days. 

Thanks,

David

 


           

u220e

unread,
Jun 23, 2020, 1:52:18 PM6/23/20
to sage-support
Anybody?

Vincent Delecroix

unread,
Jun 23, 2020, 2:17:25 PM6/23/20
to sage-s...@googlegroups.com
First of all if p and q are primes then p - q is even unless p=2 or q=2.

Next, there is no need to declare variable in Python.

Finally, there are optimized methods to access primes. Look
for prime_range, next_prime, Primes, etc

x = 3
while True:
y = (10**18 // x).next_prime()
ymax = (10**36 + x - 2) // x
while y <= ymax:
print("x = %d and y = %d" % (x, y))
y = y.next_prime()
x = x.next_prime()

slelievre

unread,
Jun 23, 2020, 2:33:11 PM6/23/20
to sage-support
Not sure why one would want the "first pair" each time.

Below we define a function that produces an iterator
yielding random prime pairs one after the other,
with primes picked at random in a range ensuring
their product will have the correct number of digits.

```
def prime_pair_for_each_product_ndigits(nmin, nmax):
    for n in range(nmin, nmax + 1):
        lo = isqrt(10**(n-1))
        hi = isqrt(10**n)
        a = random_prime(hi, lbound=lo)
        b = random_prime(hi, lbound=lo)
        yield a, b
```

This might give something like the following.

```
sage: p_q_list = list(prime_pair_for_each_product_ndigits(19, 35))
sage: p_q_list
[(2257885207, 1029222697),
 (7906953709, 8831254513),
 (28123041337, 18086888887),
 (59156603659, 75212477107),
 (244478980829, 297135812329),
 (878180166047, 926189502323),
 (1390098443147, 1010518243127),
 (5150835567223, 3603512345189),
 (16533079879703, 15727405198679),
 (34437803922611, 57693414719911),
 (102979771890571, 141205565889301),
 (941693653240727, 468548529571597),
 (1375078260756671, 1726461802816903),
 (8524331332200121, 4310462307066121),
 (19014345158785303, 31601933129557883),
 (92121426759262499, 64338223205154251),
 (262242817443146321, 251117727289363427)]
```

We check the number of digits of each product.

```
sage: f = lambda n: f'{n:36d} has {n.ndigits():2d} digits'
sage: print('\n'.join(f(n) for n in (p*q for p, q in p_q_list)))
                 2323866702264943279 has 19 digits
                69828320626688338717 has 20 digits
               508658323826826921919 has 21 digits
              4449314698430409934513 has 22 digits
             72643460565990932840741 has 23 digits
            813361250941000432227181 has 24 digits
           1404719836542484333000669 has 25 digits
          18561099554526665790140147 has 26 digits
         260022446450216138134512337 has 27 digits
        1986834503750174243684807621 has 28 digits
       14541316964959210349671680871 has 29 digits
      441229176532847985852022831019 has 30 digits
     2374020093080293654628048809913 has 31 digits
    36743808900391354263355551200641 has 32 digits
   600890064210265812194221708193549 has 33 digits
  5926928916814700284047132294733249 has 34 digits
 65853820314282336219416564107002067 has 35 digits
```

u220e

unread,
Jun 23, 2020, 4:42:16 PM6/23/20
to sage-support
Thank you.

slelievre

unread,
Jun 24, 2020, 12:13:57 PM6/24/20
to sage-support


Le mardi 23 juin 2020 20:33:11 UTC+2, slelievre a écrit :
Not sure why one would want the "first pair" each time.

Below we define a function that produces an iterator
yielding random prime pairs one after the other,
with primes picked at random in a range ensuring
their product will have the correct number of digits.

```
def prime_pair_for_each_product_ndigits(nmin, nmax):
    for n in range(nmin, nmax + 1):
        lo = isqrt(10**(n-1))
        hi = isqrt(10**n)
        a = random_prime(hi, lbound=lo)
        b = random_prime(hi, lbound=lo)
        yield a, b
```

This might give a product with one digit less
in extremely rare cases. To avoid that, replace

        lo = isqrt(10**(n-1))

with

        lo = isqrt(10**(n-1)) + 1


Reply all
Reply to author
Forward
0 new messages