I quickly put together some Python code to test my knowledge. I'm trying to detect "multiple palindromes" without using strings. Here's my code:
from math import log
from math import ceil
from math import floor
palindrome = 0
def palindromify(half, base):
assert base != 0
reversedhalf = 0
palindrome = 0
iterator = 0
size = floor(log(half, base)) + 1
"""
for base = 10 and half = 100,
log10(100) = 2, floored + 1 = 2 + 1 = 3.
for base = 10 and half = 999,
log10(999) = 2.9... (or something).
floored + 1 = 2 + 1 = 3.
size = digits.
"""
palindrome = half * (base ** size)
while iterator < size:
digit = floor(half / (base ** iterator)) % base
reversedhalf = (base ** (size - iterator - 1)) * digit + reversedhalf
iterator = iterator + 1
palindrome = reversedhalf + palindrome
return palindrome
def depalindromify(whole, base):
halfsize = (ceil(log(whole,base)) / 2)
"""
if the half is 100 and base = 10, whole = 100001.
log10(100001) = just over 5
ceil(just above 5) = 6
6 / 2 = 3. And 100 is 3 digits!
if the half is 999 and base = 10, whole = 999999.
log10(999999) = just under 6.
ceil(just under 6) = 6
6 / 2 = 3. 999 is 3 digits.
"""
halfbottom = whole % (base ** halfsize)
halftop = (whole - halfbottom) / (base ** halfsize)
"""
(whole - (whole % (base ** halfsize))) / (base ** halfsize)
if base = 10, whole = 526625,
(526625 - (526625 mod 1000)) / (1000)
= (526625 - 625) / 1000
= (526000) / 1000
= 526
"""
return halftop
"""
Does not work
"""
def multipalindrome():
current = 2
currentbase = 2
palindromed = 0
dun = False
highest = 2
while True:
dun = False
current = (highest ** 4) if current < (highest ** 4) else current + 1
currentbase = 2
while not dun:
palindromed = palindromify(current, currentbase)
currentbase = currentbase + 1
depalindromed = depalindromify(palindromed, currentbase)
print '(D) depalindromed = ', depalindromed
if (current != depalindromed): ## here
if currentbase > highest:
print 'New highest! In bases from 2 to ', currentbase, ', top half ', current, '!\n'
highest = currentbase
dun = True
multipalindrome()
# x = input("Enter first half: ")
# y = input("Enter base: ")
#
# print palindromify(x, y)
I've added the """ comments """
to help myself understand the ceil and floor functions. Basically, multipalindrome()
should run an infinite loop that chooses a number, palindromifies it, and sees if that palindrome is a palindrome in more than 1 base. It attempts to do this enough to get a palindrome in all bases (this probably won't happen). I'm not sure where to go as far as detecting multiple palindromes and what bases to use in the function, etc..
When I run this with the python interpreter (2.7), I get:
...
(D) depalindromed = 30657.0
(D) depalindromed = 30657.0
(D) depalindromed = 30658.0
(D) depalindromed = 30659.0
(D) depalindromed = 30661.0
(D) depalindromed = 30661.0
(D) depalindromed = 30662.0
(D) depalindromed = 30663.0
(D) depalindromed = 30664.0
(D) depalindromed = 30665.0
(D) depalindromed = 30666.0
(D) depalindromed = 30667.0
(D) depalindromed = 30668.0
(D) depalindromed = 30668.0
(D) depalindromed = 30670.0
(D) depalindromed = 30671.0
(D) depalindromed = 30672.0
(D) depalindromed = 30672.0
(D) depalindromed = 30674.0
(D) depalindromed = 30674.0
(D) depalindromed = 30676.0
(D) depalindromed = 30676.0
(D) depalindromed = 30678.0
(D) depalindromed = 30678.0
(D) depalindromed = 30680.0
(D) depalindromed = 30680.0
(D) depalindromed = 30681.0
(D) depalindromed = 30682.0
(D) depalindromed = 30684.0
(D) depalindromed = 30684.0
(D) depalindromed = 30685.0
(D) depalindromed = 30686.0
(D) depalindromed = 30688.0
(D) depalindromed = 30688.0
(D) depalindromed = 30689.0
(D) depalindromed = 30690.0
(D) depalindromed = 30691.0
(D) depalindromed = 30692.0
(D) depalindromed = 30693.0
(D) depalindromed = 30694.0
(D) depalindromed = 30695.0
(D) depalindromed = 30695.0
(D) depalindromed = 30697.0
(D) depalindromed = 30697.0
(D) depalindromed = 30699.0
(D) depalindromed = 30699.0
(D) depalindromed = 30701.0
(D) depalindromed = 30701.0
(D) depalindromed = 30703.0
(D) depalindromed = 30703.0
(D) depalindromed = 30704.0
(D) depalindromed = 30705.0
(D) depalindromed = 30707.0
(D) depalindromed = 30707.0
(D) depalindromed = 30708.0
(D) depalindromed = 30709.0
(D) depalindromed = 30711.0
(D) depalindromed = 30711.0
(D) depalindromed = 30712.0
(D) depalindromed = 30713.0
(D) depalindromed = 30714.0
(D) depalindromed = 30715.0
(D) depalindromed = 30716.0
(D) depalindromed = 30717.0
(D) depalindromed = 30718.0
(D) depalindromed = 30718.0
(D) depalindromed = 30720.0
(D) depalindromed = 30721.0
(D) depalindromed = 30722.0
(D) depalindromed = 30722.0
(D) depalindromed = 30724.0
(D) depalindromed = 30725.0
(D) depalindromed = 30726.0
(D) depalindromed = 30726.0
(D) depalindromed = 30727.0
(D) depalindromed = 30728.0
(D) depalindromed = 30730.0
^CTraceback (most recent call last):
File "palindrome.py", line 77, in <module>
multipalindrome()
File "palindrome.py", line 67, in multipalindrome
palindromed = palindromify(current, currentbase)
File "palindrome.py", line 26, in palindromify
reversedhalf = (base ** (size - iterator - 1)) * digit + reversedhalf
KeyboardInterrupt
henry@FusionReactor:~/code4fun/palindrome$
Edit: Question: I'm not sure what check to run to detect a multiple palindrome. If you don't understand what I'm trying to do, feel free to ask. Thanks!
First up, since you are using python, you really should take advantage of it. Please take a look at this link on how to efficiently convert any base to any base.
Second, you can check if a number is a palindrome by doing str(num) == str(num)[::-1]
, which returns True
or False
depending on whether said number in whatever base is palindromic or not. The [::-1]
part reverses the string.