def pad_left(s, cnt, ch):
    # Uzupełnienie ciągu 's' znakami 'ch' z lewej strony tak, aby nowy ciąg miał 'cnt' długości
    return ch * cnt + s

def strip_left(s, ch):
    # Usunięcie wszystkich znaków 'ch' z lewej strony ciągu 's'
    stripped = s.lstrip(ch)
    return stripped if len(stripped) > 0 else ch

def digit_to_int(digit):
    # Zamiana cyfry zapisanej jako znak na jej wartość liczbową
    if '0' <= digit <= '9':
        return ord(digit) - ord('0')
    elif 'A' <= digit <= 'Z':
        return ord(digit) - ord('A') + 10
    elif 'a' <= digit <= 'z':
        return ord(digit) - ord('a') + 10
    else:
        return 0

def int_to_digit(value):
    # Zamiana wartości liczbowej na cyfrę zapisaną jako znak
    if 0 <= value <= 9:
        return chr(value + ord('0'))
    elif 10 <= value <= 36:
        return chr(value - 10 + ord('A'))
    else:
        return '0'

def any_base_to_dec(value, base):
    # Zamiana liczby zapisanej w dowolnym systemie na system dziesiętny
    # ten same efekt można uzyskać pisząc: return int(value, base)
    minus_result = False
    if len(value) > 0 and value[0] == '-':
        minus_result = True
        value = value[1:]
    result = 0
    for digit in value:
        result = result * base + digit_to_int(digit)
    if minus_result:
        result = -result
    return result

def dec_to_any_base(value, base):
   # Zamiana liczby dziesiętnej na dowolny system
   if value == 0:
       return "0"
   minus_result = False
   if value < 0:
       minus_result = True
       value = -value
   result = ""
   while value > 0:
       result = int_to_digit(value % base) + result
       value //= base
   if minus_result:
       result = '-' + result
   return result

def add_bin(value1, value2):
    # Dodawanie dwóch liczb w systemie binarnym
    len1, len2 = len(value1), len(value2)
    # Dopasowanie długości - dodanie '0' z przodu w razie potrzeby
    if len1 > len2:
        value2 = pad_left(value2, len1 - len2, '0')
    elif len2 > len1:
        value1 = pad_left(value1, len2 - len1, '0')

    result = ""
    carry = 0  # Wartość przeniesienia
    for i in range(len(value1) - 1, -1, -1):
        sum = digit_to_int(value1[i]) + digit_to_int(value2[i]) + carry
        carry = sum // 2
        sum = sum % 2
        result = int_to_digit(sum) + result

    if carry:
        result = int_to_digit(carry) + result

    return strip_left(result, '0')  # Usunięcie zbędnych zer po lewej stronie

def test_add(value1, value2):
    # Testowanie dodawania dwóch liczb binarnych
    add_result = add_bin(value1, value2)
    v1 = any_base_to_dec(value1, 2)
    v2 = any_base_to_dec(value2, 2)
    addv = any_base_to_dec(add_result, 2)
    ok = (v1 + v2 == addv)
    print(f"{value1} + {value2} = {add_result}\tKontrola: {v1} + {v2} = {addv}{' BLAD!' if not ok else ''}")

def main():
    # Główna funkcja testująca
    test_add("0", "0")
    test_add("0", "1")
    test_add("1", "0")
    test_add("1", "1")
    test_add("1010", "1100")
    test_add("1010", "0100")
    test_add("0100", "1010")
    test_add("1010", "100")
    test_add("100", "1010")
    test_add("1111", "1111")

if __name__ == "__main__":
    main()
