various fixes

This commit is contained in:
Cameron Neville
2017-09-16 14:15:31 -04:00
parent 6739e940c4
commit b37cf0ea94

View File

@@ -1,115 +1,125 @@
class sortedlist: class sortedlist:
#don't deal with this directly or you'll fuck everything up #don't deal with this directly or you'll fuck everything up
data = [] data = []
def __init__(self, dat=[], presorted=False): def __init__(self, dat=[], presorted=False):
if presorted: if presorted:
self.data = dat self.data = dat
else: else:
self.data = sorted(dat) self.data = sorted(dat)
def __getitem__(self, key): def __getitem__(self, key):
return self.data[key] return self.data[key]
def __len__(self): def __len__(self):
return len(self.data) return len(self.data)
def __str__(self): def __repr__(self):
return str(self.data) ret = 'sortedlist('
for i in self.data:
def __delitem__(self, key): ret += str(i) + ', '
del(self.data[key]) return ret[:-2] + ')'
def __add__(self, operand): def __str__(self):
if isinstance(operand, list): return str(self.data)
return sortedlist(self.merge(self.data, sorted(operand)), True)
elif isinstance(operand, sortedlist): def __delitem__(self, key):
return sortedlist(self.merge(self.data, operand.data), True) del(self.data[key])
else:
raise TypeError('can only concatenate list or sortedlist (not "%s") to sortedlist' % type(operand).__name__) def __add__(self, operand):
if isinstance(operand, list):
#because of sorting, addition is commutative (a + b == b + a) return sortedlist(self.merge(self.data, sorted(operand)), presorted=True)
def __radd__(self, operand): elif isinstance(operand, sortedlist):
return self + operand return sortedlist(self.merge(self.data, operand.data), presorted=True)
else:
def __iadd__(self, operand): return NotImplemented
self.data = (self + operand).data
#because of sorting, addition is commutative (a + b == b + a)
#takes two sorted lists (not sortedlists) and returns a sorted combination at O(n) def __radd__(self, operand):
def merge(self, data1, data2): return self + operand
ind1 = 0
ind2 = 0 def __iadd__(self, operand):
merged = [] self.data = (self + operand).data
return self
while True:
if data1[ind1] <= data2[ind2]: #takes two sorted lists (not sortedlists) and returns a sorted combination at O(n)
merged += [data1[ind1]] def merge(self, data1, data2):
ind1 += 1 ind1 = 0
else: ind2 = 0
merged += [data2[ind2]] merged = []
ind2 += 1
if ind1 >= len(data1): while True:
return merged + data2[ind2:] if data1[ind1] <= data2[ind2]:
break merged += [data1[ind1]]
elif ind2 >= len(data2): ind1 += 1
return merged + data1[ind1:] else:
merged += [data2[ind2]]
ind2 += 1
def add(self, entry): if ind1 >= len(data1):
self.data = self.addhelper(self.data, entry) return merged + data2[ind2:]
break
#I couldn't figure out how to do this recursively in the add method elif ind2 >= len(data2):
#and fuck trying to do this in a loop return merged + data1[ind1:]
def addhelper(self, dat, entry):
if dat == []:
return [entry] def add(self, entry):
ind = int(len(dat)/2) self.data = self.addhelper(self.data, entry)
if entry < dat[ind]:
return self.addhelper(dat[0:ind], entry) + dat[ind:] #I couldn't figure out how to do this recursively in the add method
else: #and fuck trying to do this in a loop
return dat[:ind+1] + self.addhelper(dat[ind+1:], entry) def addhelper(self, dat, entry):
if dat == []:
def isin(self, entry): return [entry]
return self.inhelper(self.data, entry) ind = int(len(dat)/2)
if entry < dat[ind]:
#ditto return self.addhelper(dat[0:ind], entry) + dat[ind:]
def inhelper(self, dat, entry): else:
if len(dat) == 0: return dat[:ind+1] + self.addhelper(dat[ind+1:], entry)
return False
elif len(dat) == 1: def isin(self, entry):
return entry == dat[0] return self.inhelper(self.data, entry)
ind = int(len(dat)/2) #ditto
if entry < dat[ind]: def inhelper(self, dat, entry):
return self.inhelper(dat[:ind], entry) if len(dat) == 0:
elif entry > dat[ind]: return False
return self.inhelper(dat[ind+1:], entry) elif len(dat) == 1:
else: return entry == dat[0]
return True
ind = int(len(dat)/2)
#returns an arbitrary index that contains the value at O(log(n)) if entry < dat[ind]:
#returns -1 if the list doesn't contain the value return self.inhelper(dat[:ind], entry)
def index(self, val): elif entry > dat[ind]:
ind = self.indexhelper(self.data, val) return self.inhelper(dat[ind+1:], entry)
if ind == len(self): else:
ind = -1 return True
return ind
pass #returns an arbitrary index that contains the value, at O(log(n))
def index(self, value):
#at this point I think I'm just bad at defining recursive functions low = 0
def indexhelper(self, dat, val): high = len(self)
ind = int(len(dat)/2) mid = (low + high) / 2
while self[mid] != value:
if len(dat) == 0: if self[mid] > value:
return 0 high = mid
elif dat[ind] == val: else:
return ind low = mid
elif dat[ind] < val: mid = (high + low) / 2
return ind + 1 + self.indexhelper(dat[ind+1:], val) if high in (low, low+1):
else: raise ValueError('sortedlist does not contain entry')
return self.indexhelper(dat[:ind], val) return mid
#TODO: add functionality for single=False #removes a single instance of entry, raises exception if it doesn't exist
def remove(self, entry, single=True): def remove(self, entry):
del(self[self.index(entry)]) del(self[self.index(entry)])
#removes every instance of entry, doesn't raise an exception if it doesn't exist
#TODO: index once, then search adacent indices
def removeall(self, entry):
while True:
try:
del(self[self.index(entry)])
except ValueError:
break