666/malbolge/trinary.py
2014-01-13 23:54:13 +01:00

217 lines
5.0 KiB
Python

class Trinary:
"""Trinary word"""
def __init__(self, value, convert):
#Convert to base 3 if necessary
if convert:
value = self.__converti(value)
self.value = value
#Check max lenght
if self.lenght > 10:
raise OverflowError("Trit word limit exceeded: max 10 (passed %d)"
% self.lenght)
def __converti(self, decimal):
"""Return decimal value of the passed trinary."""
trinary = []
if decimal == 0:
return [0]
while decimal > 0:
trinary += decimal % 3,
decimal //= 3
return trinary[::-1]
#Operators override
def __iter__(self):
trilist = (int(i) for i in self.value)
return iter(trilist)
def __str__(self):
return self.value
def __repr__(self):
return self.value
def __setattr__(self, name, value):
"""
Assegna entrambi i valori (decimal e trinary) quando almeno uno
cambia.
"""
if name == "value":
if type(value) is list:
value = "".join([str(i) for i in value])
self.__dict__["value"] = value
elif type(value) is str:
self.__dict__["value"] = value
elif type(value) is int:
self.__dict__["value"] = str(value)
self.__dict__["decimal"] = int(self.value, base=3)
self.__dict__["lenght"] = len(self.value)
elif name == "decimal":
if type(value) is int:
self.__dict__["value"] = str(self.decimal)
self.__dict__["decimal"] = value
elif type(value) is list:
value = "".join([str(i) for i in value])
self.__dict__["value"] = value
self.__dict__["decimal"] = int(self.value, base=3)
self.__dict__["lenght"] = len(self.value)
def __getitem__(self, index):
return self.value[index]
#Math operators override
def __add__(self, other):
try:
return Trinary(self.decimal + other.decimal, True)
except AttributeError:
return Trinary(self.decimal + other, True)
def __iadd__(self, other):
try:
return self + other
except AttributeError:
return self.decimal + other
def __sub__(self, other):
try:
return Trinary(self.decimal - other.decimal, True)
except AttributeError:
return Trinary(self.decimal - other, True)
def __isub__(self, other):
return self - other
def __mul__(self, other):
try:
return Trinary(self.decimal * other.decimal, True)
except AttributeError:
return Trinary(self.decimal * other, True)
def __imul__(self, other):
return self * other
def __mod__(self, other):
try:
return Trinary(self.decimal % other.decimal, True)
except AttributeError:
return Trinary(self.decimal % other, True)
def __imod__(self, other):
return self % other
def __truediv__(self, floor):
try:
return Trinary(self.decimal / other.decimal, True)
except AttributeError:
return Trinary(self.decimal / other, True)
def __itruediv__(self, other):
return self / other
def __floordiv__(self, other):
try:
return Trinary(self.decimal // other.decimal, True)
except AttributeError:
return Trinary(self.decimal // other, True)
def __ifloordiv__(self, other):
return self // other
def __lt__(self, other):
try:
return self.decimal < other.decimal
except AttributeError:
return self.decimal < other
def __le__(self, other):
try:
return self.decimal <= other.decimal
except AttributeError:
return self.decimal <= other
def __eq__(self, other):
try:
return self.decimal == other.decimal
except AttributeError:
return self.decimal == other
def __ne__(self, other):
try:
return self.decimal != self.other
except AttributeError:
return self.decimal != other
def __gt__(self, other):
try:
return self.decimal > other.decimal
except AttributeError:
return self.decimal > other
def __ge__(self, other):
try:
return self.decimal >= other.decimal
except AttributeError:
return self.decimal >= other
class Trilist:
"""Trinary word list"""
def __init__(self, trilist, convert):
"""Trinary list inizialization."""
self.valori ={a:trin(b, convert) for a, b in enumerate(trilist)}
#Operators override
def __setitem__(self, index, value):
try:
self.valori[index.decimal] = value
except AttributeError:
self.valori[index] = value
def __getitem__(self, index):
try:
return self.valori[index.decimal]
except AttributeError:
return self.valori[index]
except KeyError:
return trin(0)
def __str__(self):
return self.valori.__str__()
def __repr__(self):
return self.valori
#Wrappers
def trin(value, convert=False):
"""
Returns a trinary word. Provide convert=True as a parameter if
the value is decimal.
"""
return Trinary(value, convert)
def trinord(carattere):
"""
Returns the ordinal value of a character in a trinary word.
"""
return trin(ord(carattere), True)
def trinchr(trinary):
"""
Returns the ASCII character given a trinary word.
"""
return chr(trinary.decimal % 256)
def trinlist(trilist=[], convert=False):
"""
Returns a trilist accessible by trinary indices given a list word.
Provide convert=False as a parameter only if the elements of trilist
are trinary. Do not use lists with mixed basis.
"""
return Trilist(trilist, convert)