Divide by two a number in base -2 I was given this coding challenge when a applying for a summer internship but didn't get selected for the next round and I was curious if it could be improved.

The problem says:


  Given a number in base "-2" divide it by 2.
  
  For example:
  
  Given [1, 0, 0, 1, 1, 1] (-23) the output is [1, 0, 1, 0, 1, 1] (-11)
  
  Given [0, 0, 1, 0, 1, 1] (-12) the output is [0, 1, 1, 1] (-6)
  
  Note the array is read from left to right. [1, 0, 0, 1, 1, 1] = 1*(-2)^0 + 0*(-2)^1 + 0*(-2)^2 + 1*(-2)^3 + 1*(-2)^4 + 1 * (-2)^5 = 1
  + 0 + 0 + (-8) + 16 + (-32) = -23


The easiest solution that I found was to convert the number to an integer, divide it by two and then convert it back to base -2.

Thanks in advance for your input.

My code in Python:

import math

# Main function
def solution(A):
    value = math.ceil(calculate_number(A) / 2)
    p = convert_number_to_binary(value)
    return p


# This function calculates the value of the list
def calculate_number(A):
    total = 0
    for i in range(0, len(A)):
        total += A[i] * (-2) ** i
    return total

# This function converts a number to base -2
def convert_number_to_binary(number):
    binary = []
    if number == 0:
        return binary

    while number != 0:
        number, remainder = divmod(number, -2)
        if remainder &lt; 0:
            number += 1
            remainder -= -2
        binary.append(remainder)
    return binary

print(solution([1, 0, 0, 1, 1, 1]))
General


As per PEP 8 conventions, the variables in functions should be in lowercase.
Adding docstrings is recommended. PEP 257
Names should be short and meaningful. For example, convert_number_to_binary should actually be to_base_minus_two. Also, calculate_number should be from_base_minus_two
Use type hints
Instead of x == 0 python allows you to use use not x. Similarly, x != 0 can be replaced with x.
Envelop the main code inside if __name__ == '__main__':. This will prevent the code from being run if imported from another module.
Following  @Martin R's advice, you can change -2 to a constant BASE


Function solution

value = math.ceil(from_base_minus_two(A) / 2)
p = to_base_minus_two(value)
return p


Can be replaced with the one liner:

return to_base_minus_two(math.ceil(from_base_minus_two(a) / 2))


Function from_base_minus_two

total = 0
for i in range(0, len(a)):
    total += a[i] * BASE ** i
return total


Instead, you can use:

return sum(j * BASE ** i for i, j in enumerate(a)))


Function to_base_minus_two

The value you are finding isn't exactly binary. Change it to base_minus_two

You don't need to use

if number == 0:
    return base_minus_two


Automatically, the while loop will terminate immediately as number is 0, and will return base_minus_two which is []



Here's what the final code might look like:

import math
from typing import List


BASE = -2


def from_base_minus_two(a: List[int]) -&gt; int:
    """ Converts base 'BASE' to decimal """

    return sum(j * BASE ** i for i, j in enumerate(a))


def to_base_minus_two(number: int) -&gt; List[int]:
    """ Converts decimal to 'BASE' """

    base_minus_two = []

    while number:
        number, remainder = divmod(number, BASE)

        if remainder &lt; 0:
            number += 1
            remainder -= BASE

        base_minus_two.append(remainder)

    return base_minus_two


def solution(a: List[int]) -&gt; List[int]:
    """

    * Converts from 'BASE' to decimal
    * Divides the decimal by 2
    * Converts the decimal back to 'BASE'

    """

    return to_base_minus_two(math.ceil(from_base_minus_two(a) / 2))


if __name__ == '__main__':
    print(solution([1, 0, 0, 1, 1, 1]))