-1

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!

  • What question are you asking? – Scott Hunter Jun 04 '17 at 20:37
  • @Scott Hunter, I'm not sure what check to run to detect a multiple palindrome. Just realized I didn't put enough, thanks, lol – Alphanumeric Jun 04 '17 at 20:38
  • @Alphanumeric: Isn't *every* positive integer a palindrome to infinitely many bases? E.g., 1729 is trivially a palindrome in any base >= 1730, since it's a single digit. Do you have some restriction on the bases that you care about? – Mark Dickinson Jun 05 '17 at 07:01

1 Answers1

1

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.

cs95
  • 379,657
  • 97
  • 704
  • 746
  • I have two comments/questions: Edit: (enter doesn't work here lol) 1: all bases (like 2 to infinity)? 2: trying not to use strings. Thanks! – Alphanumeric Jun 04 '17 at 20:40
  • Between 2 and 36. Sorry, should have mentioned that. – cs95 Jun 04 '17 at 20:43
  • No worries! Also, is it possible to do this without strings, i.e. int's? Thanks! I really like this answer – Alphanumeric Jun 04 '17 at 20:45
  • Yes, if you can somehow figure out how to reverse number without using strings, you can do `num ^ reversedNum`. The XOR operation should result in 0 if the numbers are the same. – cs95 Jun 04 '17 at 20:59
  • You are talking about reversing the *repersentations* of a number, which *are* strings. – Scott Hunter Jun 04 '17 at 21:02
  • @Alphanumeric Also, I realised I was a little misguiding on the use of the `int` function. All that does is convert an existing number in the base specified to decimal. I have edited my post to include a link that could help you do what you want. – cs95 Jun 04 '17 at 21:03
  • Had to go do something. @Shiva, I guess I'm not sure what I'm doing, since the math I'm using should be strings. It's not a mathematical function since it's dependent on the base you're using. I think this is the closest answer I can get. Thanks! – Alphanumeric Jun 04 '17 at 22:00
  • @Shiva: `int` doesn't convert anything to decimal: Python integers aren't stored in base 10. – Mark Dickinson Jun 05 '17 at 07:02