diff --git a/src/test1512/hamming.py b/src/test1512/hamming.py new file mode 100644 index 0000000..9c029f5 --- /dev/null +++ b/src/test1512/hamming.py @@ -0,0 +1,66 @@ +def calcRedundantBits(m): + for i in range(m): + if(2**i >= m + i + 1): + return i + +def posRedundantBits(data, r): + j = 0 + k = 1 + m = len(data) + res = '' + for i in range(1, m + r+1): + if(i == 2**j): + res = res + '0' + j += 1 + else: + res = res + data[-1 * k] + k += 1 + return res[::-1] + + +def calcParityBits(arr, r): + n = len(arr) + for i in range(r): + val = 0 + for j in range(1, n + 1): + if(j & (2**i) == (2**i)): + val = val ^ int(arr[-1 * j]) + + arr = arr[:n-(2**i)] + str(val) + arr[n-(2**i)+1:] + return arr + + +def detectError(arr, nr): + n = len(arr) + res = 0 + for i in range(nr): + val = 0 + for j in range(1, n + 1): + if(j & (2**i) == (2**i)): + val = val ^ int(arr[-1 * j]) + res = res + val*(10**i) + return int(str(res), 2) + + +def encode(inp: str) -> str: + + data = ''.join(format(x, 'b') for x in bytearray(inp, 'utf-8')) + m = len(data) + r = calcRedundantBits(m) + + arr = posRedundantBits(data, r) + arr = calcParityBits(arr, r) + + return arr + + +def decode(arr: str) -> int: + correction = detectError(arr, calcRedundantBits(len(arr))) + if(correction==0): + print(calcRedundantBits(len(arr))) + return -1 + else: + return len(arr)-correction + +data = ''.join(format(x, 'b') for x in bytearray('Hi', 'utf-8')) +print(data) diff --git a/src/test1512/test_hamming.py b/src/test1512/test_hamming.py new file mode 100644 index 0000000..e86f9e8 --- /dev/null +++ b/src/test1512/test_hamming.py @@ -0,0 +1,19 @@ +from hamming import encode, decode + + +def test_encode(): + s = encode("Hi") + assert s == '1001100011011000101' + +def test_decode_right(): + s = encode("Hi") + r = decode(s) + assert r == -1 + +def test_decode_wrong(): + s = '1011100011011000101' + r = decode(s) + assert r == 2 + + + diff --git a/src/test1512/test_walker.py b/src/test1512/test_walker.py new file mode 100644 index 0000000..991db75 --- /dev/null +++ b/src/test1512/test_walker.py @@ -0,0 +1,17 @@ +from walker import Walker +import pytest + +def test_wrong_input(): + with pytest.raises(Exception): + Walker([("A", 0.25), ("B", 0.33), ("C", 0.70)]) + +def test_1_prob(): + w = Walker([("A", 1.00), ("B", 0.00)]) + res = w.get_random() + assert res == "A" + +def test_returning_value(): + w = Walker([("A", 0.07), ("B", 0.31), ("C", 0.35), ("D", 0.27)]) + res = w.get_random() + assert isinstance(res, str) + diff --git a/src/test1512/walker.py b/src/test1512/walker.py new file mode 100644 index 0000000..96351c3 --- /dev/null +++ b/src/test1512/walker.py @@ -0,0 +1,55 @@ +import random +from math import floor + +class Walker: + def __init__(self, pairs: list[tuple[str, float]]): + self.pairs = pairs + self.psum = 0 + self.pairsd = {} + + self.num = len(self.pairs) + + for i in range(self.num): + self.psum += pairs[i][1] + self.pairsd[self.pairs[i][0]] = self.pairs[i][1] + + if (self.psum != 1): + raise Exception("Error: probabilities must add up to 1") + + self.new_pairs = [] + self.avg = 1 / self.num + for pair in self.pairs: + self.new_pairs.append([pair[0], self.avg]) + + # storing tuples where 1st element is donor, 2nd is recepient, 3rd is barier value + self.table = [] + self.recepients = [] + self.donors = [] + for i in range(self.num): + if self.pairs[i][1] > self.new_pairs[i][1]: + self.recepients.append(self.new_pairs[i]) + elif self.pairs[i][1] < self.new_pairs[i][1]: + self.donors.append(self.new_pairs[i]) + + while (self.recepients or self.donors): + self.recepients[0][1] += self.donors[0][1] - self.pairsd[self.donors[0][0]] + remain = self.avg - (self.donors[0][1] - self.pairsd[self.donors[0][0]]) + self.table.append([self.donors[0][0], self.recepients[0][0], len(self.table) * self.avg + remain]) + self.donors.pop(0) + if self.recepients[0][1] > self.pairsd[self.recepients[0][0]]: + self.donors.append(self.recepients.pop(0)) + elif self.recepients[0][1] == self.pairsd[self.recepients[0][0]]: + self.recepients.pop(0) + + self.table.append([self.table[-1][1], self.table[0][0], 1]) + def get_random(self) -> str: + value = random.random() + row_num = floor(self.num * value) + row = self.table[row_num] + if value < row[2]: + return row[0] + elif value > row[2]: + return row[1] + + +