How to Convert Integer to Whitespace Format in Python


The challenge

Hereinafter, [space] refers to " "[tab] refers to "\t", and [LF] refers to "\n" for illustrative purposes. This does not mean that you can use these placeholders in your solution.

In esoteric language called Whitespace, numbers are represented in the following format:

  • first character represents the sign: [space] for plus, [tab] for minus;
  • characters after that and until [LF] are the binary representation of the integer: [space] for 0, [tab] for 1.
  • characters after that are the binary representation of the absolute value of the number, with [space] for 0, [tab] for 1, the rightmost bit is the least significand bit, and no leading zero bits.
  • the binary representation is immediately followed by [LF].

Notes

  • Valid Whitespace number must always have at least two characters: a sign and the terminator. In case there are only two characters, the number is equal to zero.
  • For the purposes of this challenge, zero must always be represented as [space][LF].
  • In Whitespace, only space, tabulation and linefeed are meaningful characters. All other characters are ignored. However, for the purposes of this simple challenge, please do not add any other characters in the output.
  • In this challenge, input will always be a valid negative or positive integer.
  • For your convenience, in this challenge we will use unbleach() function when evaluating your results. This function replaces whitespace characters with [space][tab], and [LF] to make fail messages more obvious. You can see how it works in Example Test Cases.

Examples

  • 1 in Whitespace is " \t\n".
  • `` in Whitespace is " \n".
  • -1 in Whitespace is "\t\t\n".
  • 2 in Whitespace is " \t \n".
  • -3 in Whitespace is "\t\t\t\n".

The solution in Python code

Option 1:

from string import maketrans

def whitespace_number(n):
    return (' \n' if n == 0 else
        '{:+b}\n'.format(n).translate(maketrans('+-01', ' \t \t')))

Option 2:

def whitespace_number(n):
    sign = ' \t'[n < 0]
    number = bin(abs(n))[2:].replace('0', ' ').replace('1', '\t') if n else ''
    return sign + number + '\n'

Option 3:

whitespace_number=lambda n:f"{n:+b}\n".translate(str.maketrans("+-01"," \t"*2))[n==0:]

Test cases to validate our solution

def unbleach(ws):
    return ws.replace(' ', '[space]').replace('\t', '[tab]').replace('\n', '[LF]')

test.assert_equals(unbleach(whitespace_number( 1)), unbleach(   " \t\n"))
test.assert_equals(unbleach(whitespace_number( 0)), unbleach(     " \n"))
test.assert_equals(unbleach(whitespace_number(-1)), unbleach(  "\t\t\n"))
test.assert_equals(unbleach(whitespace_number( 2)), unbleach(  " \t \n"))
test.assert_equals(unbleach(whitespace_number(-3)), unbleach("\t\t\t\n"))