Search code examples
pythonpalindromeradix

Is there a quick Python function for turning numbers into different bases?


I'm writing a code to check how many times a number is a palindrome in bases 2-10. Is there a python function for converting numbers into different bases?

I have already tried manually creating a function, but it is too slow.

baseChars="0123456789"
def toBase(n, b): 
    return "0" if not n else toBase(n//b, b).lstrip("0") + baseChars[n%b]

I expect the toBase function to return the number expressed in all bases from 2-10. I would like to avoid NumPy


Solution

  • I don't think there's any single function that does this in the standard library. But working on a different project for one of my own classes, I had to tackle this type of problem, and my solution looked like this:

    def _base(decimal, base):
        """
        Converts a number to the given base, returning a string.
        Taken from https://stackoverflow.com/a/26188870/2648811
        :param decimal: an integer
        :param base: The base to which to convert that integer
        :return: A string containing the base-base representation of the given number
        """
        li = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        other_base = ""
        while decimal != 0:
            other_base = li[decimal % base] + other_base
            decimal = decimal // base
        if other_base == "":
            other_base = "0"
        return other_base
    
    def palindromes(num, bases=range(2, 11)):
        """
        Checks if the given number is a palindrome in every given base, in order. 
        Returns the sublist of bases for which the given number is a palindrome, 
        or an empty list if it is not a palindrome in any base checked.
        :param num: an integer to be converted to various bases
        :param bases: an iterable containing ints representing bases
        """
        return [i for i in bases if _base(num, i) == _base(num, i)[::-1]]
    

    (A less succinct version of that last statement (expanding the for loop) looks like this):

    r = []
    for i in bases:
        b = _base(num, i)
        if b == b[::-1]:
            r.append(i)
    return r
    

    In your case, if you just want a list of representations of your integer in various bases, the code would be even simpler:

    reps = {b: _base(num, b) for base in range(2, 11)}
    

    will produce a dict of base : representation in that base. For example, if num = 23:

    {2: '10111',
     3: '212',
     4: '113',
     5: '43',
     6: '35',
     7: '32',
     8: '27',
     9: '25',
     10: '23'}