-1

I am looking for a way to reduce a decimal integer representation to a string with the fewest characters possible.

E.g. hexadecimal uses the letters A-F on top of the decimal numbers.

hex(123)

Is there a smooth way to make use of all letters to reduce the string length even more?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
caliph
  • 1,389
  • 3
  • 27
  • 52

1 Answers1

1

So that you can use your own alphabet and even expand it with 0-9, A-Z, a-z:

Recursive:

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n, b): 
  if not n: return "0"
  return to_base(n//b, b).lstrip("0") + BS[n%b]

Iterative:

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n, b):
    res = ""
    while n:
        res+=BS[n%b]
        n//= b
    return res[::-1] or "0"

Note: recursive version can raise RuntimeError: maximum recursion depth exceeded in cmp for very large integers and negative numbers.

Encoder usage: Parameters (n, b) mean (number to convert, base to use), for example:

>>> to_base(123,2)
'1111011'
>>> to_base(123,16)
'7B'
>>> to_base(123,len(BS))
'3F'
>>> to_base(1234567890000,16)
'11F71FB0450'
>>> to_base(1234567890000,len(BS))
'FR5HUGK0'

Using len(BS) means you will use all the characters from your BS variable as the base of conversion.

Iterative decoder:

def to_dec(n, b):
    res = 0
    power = 1
    for letter in enumerate(n[::-1]):
        i = BS.find(letter)
        res += i*power
        power *= b
    return res

Decoder usage: Parameters (n, b) mean (number to convert, base to use), for example:

>>> to_dec('1111011',2)
123
>>> to_dec('7B',16)
123
>>> to_dec('3F',len(BS))
123
>>> to_dec('11F71FB0450',16)
1234567890000
>>> to_dec('FR5HUGK0',len(BS))
1234567890000

Hope this was useful ;)

Edit: added encoder usage
Edit: added decoder
Edit: added decoder usage

MrJavy
  • 196
  • 6
  • Thank you! This is a bit our of my league. I have trouble understanding the (s, b) parameters. Could you please add an example? How would you decode afterwards. – caliph Sep 23 '20 at 08:37