0

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

  • As far as I know, no. Aside from `str` (base 10), there are separate `bin`, `oct`, and `hex` functions for producing base 2, 8, and 16 representations, respectively. `format` also only has options for bases 2, 8, and 16. – chepner Jul 10 '19 at 16:37

3 Answers3

1

This is available in NumPy through base_repr():

import numpy as np
[np.base_repr(100, base) for base in range(2,11)]

Result:

['1100100', '10201', '1210', '400', '244', '202', '144', '121', '100']
TomNash
  • 3,147
  • 2
  • 21
  • 57
  • Hi Tom, I cannot use NumPy, because NumPy is a pip install, which I am not allowed to use. Is there another way? –  Jul 10 '19 at 16:41
  • 1
    You could look at the [source code](https://github.com/numpy/numpy/blob/master/numpy/core/numeric.py#L1971) and see how they do it, it's pretty straight-forward and uses primitive operations like your current solution. – TomNash Jul 10 '19 at 16:45
0

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'}
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
0

Try this

def rebase( value, new_base ):
    res = ""
    while value > 0:
      res = str( value % new_base ) + res
      value = int( value / new_base )
    return res
Stefan
  • 698
  • 7
  • 9