I've been writing a simple program in python that encodes a string into a number using Gödel's encoding. Here's a quick overview: you take the first letter of the string, find its position in the alphabet (a -> 1, b -> 2, ..., z -> 26) and raise the first prime number (2) to this power. The you take the second letter in the string and the second prime (3) and so on. Here's the code:
import string, math
alphabet = list(string.ascii_lowercase)
def primes(n):
"Returns a list of primes up to n."
primes = [2, 3]
i = 5
while i < n:
l = math.ceil(math.sqrt(i))
k = math.ceil(math.sqrt(i+2))
for p in primes[:l]:
if i % p == 0:
break
else:
primes.append(i)
for p in primes[:k]:
if (i+2) % p == 0:
break
else:
primes.append(i+2)
i += 6
return primes
def Encode(string):
"Encodes a string using Godel's encoding."
enc = 1
p = primes(100)
for i in range(len(string)):
enc = enc*(p[i]**(alphabet.index(string[i])+1))
return enc
def Decode(code):
"Decodes a Godel's encoding into a string."
dec = ""
for i in primes(100):
count = 0
while code % i == 0:
code /= i
count += 1
if count == 0: #If we've found a prime that doesn't divide code,
#there are no more letters to be added.
break
else:
dec += alphabet[count-1]
return dec
The primes() function works for my intends and purposes and so does Encode(). Now Decode() is the interesting part. It works for encodings up to ~15 digits long but starts doing some mystical stuff starting at ~20 digits. So for instance it gives the right output for the encoding of "aaaaaaaaaaaaaa" but not for "python". For big numbers it seems to execute the while code % i == 0
loop too many times (176 for the first letter of "python" when it should be just 16).
Is this just a problem with the mod function in python? Sounds strange as 20 digits isn't all that long for a computer. Is there a mistake in my code? Thanks for all the help. I'm not a programmer myself but I'm trying to learn doing stuff like this. Therefore any constructive criticism is welcome.
For big numbers, alternately add and subtract digits in groups of three. If the answer is divisible by 7, the number is too. For example 256242 is divisible by 7 because 256-242 = 14. 8 If the last three digits form a number divisible by 8, then so is the whole number.
Alternative Method: num = int (input (“Enter the number whose divisibility needs to be checked:”)) div = int (input (“Enter the number with which divisibility needs to be checked:”)) if num%div == 0: print (“The number is divisible.”) else: print (“The number is not divisible.”)
The basic rule for divisibility by 4 is that if the number formed by the last two digits in a number is divisible by 4, the original number is divisible by 4; this is because 100 is divisible by 4 and so adding hundreds, thousands, etc. is simply adding another number that is divisible by 4.
/=
in Python 3 returns a double-precision floating point value. (As does math.ceil
, btw.) Floating point values do not have arbitrary precision. You could use //=
instead. That always results in an integer. (It gives the floor of the result.)
(I previously said that math.ceil was your main culprit. I don't think that's the case, but nonetheless, you probably shouldn't be using a floating point value to index into a list. If you need to run the same code in Python 2 that will fail. You can cast it back to an integer using int(math.ceil(...))
, although you might want to consider avoiding floating-point calculations altogether, since things will begin to break down for sufficiently large values.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With