#Fibinaries and Pribinaries
Silly script to create numbers in a positional notation using the fibonacci sequence and prime numbers as bases.
| import math | |
| from functools import partial | |
| BITS = 16 | |
| def is_prime(n): | |
| if n % 2 == 0 and n > 2: | |
| return False | |
| return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2)) | |
| def make_primes(n): | |
| count = 0 | |
| num = 1 | |
| while count < n: | |
| if is_prime(num): | |
| count += 1 | |
| yield num | |
| num += 1 | |
| def fibonacci(n): | |
| if n <= 1: | |
| return 1 | |
| return fibonacci(n-1) + fibonacci(n-2) | |
| def make_fibonacci(n): | |
| fibs = 0 | |
| num = 0 | |
| while fibs < n: | |
| fibs += 1 | |
| yield fibonacci(num) | |
| num += 1 | |
| primes = list(make_primes(BITS)) | |
| fibonaccis = list(make_fibonacci(BITS + 1))[1:] | |
| def decimal_to_base_x(num, base_list, length=BITS): | |
| result = "" | |
| for pos in range(length - 1, -1, -1): | |
| if num >= base_list[pos]: | |
| num -= base_list[pos] | |
| result += "1" | |
| else: | |
| result += "0" | |
| return result | |
| def base_x_to_decimal(num, base_list): | |
| return sum(base_list[index] for index, bit in enumerate(reversed(num)) if bit == "1") | |
| def add(num1, num2, length=BITS): | |
| """Not all additions work, maybe convert back to decimal""" | |
| carry = 0 | |
| result = "" | |
| for i in range(len(num1) - 1, -1, -1): | |
| n = carry | |
| n += 1 if num1[i] == '1' else 0 | |
| n += 1 if num2[i] == '1' else 0 | |
| result = ('1' if n % 2 == 1 else '0') + result | |
| carry = 0 if n < 2 else 1 | |
| if carry != 0: | |
| result = '1' + result | |
| return result | |
| decimal_to_fibinary = partial(decimal_to_base_x, base_list=fibonaccis) | |
| decimal_to_pribinary = partial(decimal_to_base_x, base_list=primes) | |
| fibinary_to_decimal = partial(base_x_to_decimal, base_list=fibonaccis) | |
| pribinary_to_decimal = partial(base_x_to_decimal, base_list=primes) | |
| if __name__ == '__main__': | |
| print("With {} bits it is possible to have the following ranges:".format(BITS)) | |
| print("Prime base: [1 .. {}]".format(sum(primes))) | |
| print("Fibonacci base: [1 .. {}]".format(sum(fibonaccis))) | |
| print("(For reference, normal base-2: [1 .. {}])".format(2**BITS)) | |
| print("-- Examples --") | |
| print("Converting 22") | |
| print(decimal_to_fibinary(22)) | |
| print(fibinary_to_decimal("0000000001000001")) | |
| assert fibinary_to_decimal("0000000001000001") == 22 | |
| print(decimal_to_pribinary(22)) | |
| print(pribinary_to_decimal("0000000100000100")) | |
| assert pribinary_to_decimal("0000000100000100") == 22 | |
| a = 7 | |
| b = 43 | |
| c = a + b | |
| a_ = decimal_to_fibinary(a) | |
| b_ = decimal_to_fibinary(b) | |
| c_ = add(a_, b_) | |
| assert fibinary_to_decimal(c_) == c |