Check magic numbers (those whose square root is a prime number) within a range

Asked

Viewed 144 times

-1

I wonder why it doesn’t work.

import math
#Se a divisão do numero der um primo, o número é mágico

is_magic = []
for n in range(8, 27):
    cont = 0

if pow(n,(1/2)) == 2 or 3 or 5 or 7:
    cont += 1
    is_magic.append(n)

print(is_magic) #Resposta  deveria ser 9 e 25

3 answers

4

That has been detailed here and here, but basically, by doing:

if algumacoisa == 2 or 3

In fact the two conditions analyzed are algumacoisa == 2 and 3 (only the value 3). And for the second case (only the 3), the rules of Truth Value Testing, in which any object can be tested in a context boolean. In the case of numbers, only zero is considered false, and any other value is true. Thus, the condition "only the 3" is considered True. And how are you using the operator or (which is true if any of the conditions are True), then you’ll always get into this if.

Then you can do as indicated in another answer (if valor == 2 or valor == 3 or valor == 5 or valor == 7:), or if you want you can store the valid values in a list and use the operator in to check if the value is one of the ones in the list:

import math

primos = [2, 3, 5, 7]
is_magic = []
for n in range(8, 27):
    if math.sqrt(n) in primos:
        is_magic.append(n)

print(is_magic) # [9, 25]

Also note another detail: as you have already done import math at first, could use math.sqrt(n) instead of pow(n, 1/2) to calculate the square root. In your original code you ended up using nothing from the module math, so this one import was half "dropped".

Another option is to use one comprehensilist on, much more succinct and pythonic:

import math

primos = [2, 3, 5, 7]

is_magic = [ n for n in range(8, 27) if math.sqrt(n) in primos ]
print(is_magic) # [9, 25]

I also removed the cont, that was not being used for anything. If you want to know the quantity, just get the list size is_magic, with len(is_magic).


Not directly related, but if the range starts in 8, the square root will never be 2, so it shouldn’t even be in the if. The same goes for 7, for if the range ends in 26, the square root will never be greater than 5.0990195135927845.

But maybe we should reverse the logic. If I want to check magic numbers within a certain range, just go through the list of prime numbers, square them and see if they’re in the range:

intervalo = range(8, 27)
is_magic = []
primos = [2, 3, 5, 7]
for n in primos:
    quadrado = n ** 2
    if quadrado in intervalo:
        is_magic.append(quadrado)

print(is_magic)

This would make it even easier to include several different ranges, for example:

primos = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
# números entre 8 e 26, ou entre 100 e 199
intervalo = list(range(8, 27)) + list(range(100, 200))
is_magic = []
for n in primos:
    quadrado = n ** 2
    if quadrado in intervalo:
        is_magic.append(quadrado)

print(is_magic) # [9, 25, 121, 169]

Although then the interval will have all the numbers, because I had to create a list from the ranges (one range only holds the initial and final values, in addition to step). So an alternative is to have a list of ranges, and then you check if the value is in any of them:

primos = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]
# números entre 8 e 26, ou entre 100 e 199
intervalos = [ range(8, 27), range(100, 200) ]
is_magic = []
for n in primos:
    quadrado = n ** 2
    # verifica se está em algum dos ranges
    if any(quadrado in r for r in intervalos):
        is_magic.append(quadrado)

print(is_magic) # [9, 25, 121, 169]

Of course you would need to have a previous list of prime numbers, but anyway, in the original code you would also need (the difference is that if the list is too large, it would be impractical to write a if valor == 2 or valor == 3 or etc... for all possible values).

If you don’t want to write the prime numbers one by one, you can use a algorithm for this.

3

You are making 4 conditions and concatenating them all with the operator or. So far so good. The first works as expected. The problem comes in the next. The second condition is only 3, nothing more. It is not pow(n, 0.5) == 3 as you probably think it is. It’s only 3. And 3 is considered a true number. So if that condition is true and all are connected with or, everything will always be true. You have to fix this and the other conditions by making a complete comparison. And not having to do the math every time is best to store the value in a variable and use the variable to calculate.

import math

is_magic = []
for n in range(8, 27):
    valor = pow(n, 0.5)
    if valor == 2 or valor == 3 or valor == 5 or valor == 7:
        is_magic.append(n)
print(is_magic)

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

  • Thank you so much! What if I want for one more range? " for n in range(8, 27) and (45,33):".... I tried so but it didn’t work...I wanted to be able to choose the numerical intervals =o

1

In the if pow(n,(1/2)) == 2 or 3 or 5 or 7 you should compare the result of the Pow with each item, in this example I put the prime numbers inside a list, so we use the operator 'in' to see if it exists inside the list:

import math

is_magic = []
primos = [2,3,5,7]

for n in range(8, 27):
    if pow(n,(1/2)) in primos:
        is_magic.append(n)

print(is_magic)

You can do with the concept of list comprehension in python:

primos = [2,3,5,7]
is_magic = [x for x in range(8,27) if pow(x,1/2) in primos]
print(is_magic)

The result will be the same in both cases. Note: your contactor cont is not necessary.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.