Skip to content

Commit

Permalink
Fix cl init
Browse files Browse the repository at this point in the history
  • Loading branch information
morefreeze committed Dec 17, 2024
1 parent bae8642 commit 70aa177
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 118 deletions.
73 changes: 59 additions & 14 deletions _code/algorithm_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ def to_int(self):
def to_hex(self) -> int:
hex_str = self.to_str()
return int(hex_str, 16)

def shift1(self):
'''shift x as hex left by 1 bit and add the prefix'''
shifted_str = self.to_str()
shifted_str = shifted_str[1:] + shifted_str[0]
return Alpha.from_str(shifted_str, self.m)

def rshift1(self):
'''shift x as hex right by 1 bit and add the suffix'''
shifted_str = self.to_str()
shifted_str = shifted_str[-1] + shifted_str[:-1]
return Alpha.from_str(shifted_str, self.m)

class ThreeLines:
def __init__(self, m, mask):
Expand All @@ -46,7 +58,7 @@ def __init__(self, m, mask):
self.base_power_4 = m ** 4
self.index = [-1] * self.base_power_4
self.mem = [0] * self.base_power_4
self.tail = [0] * self.base_power_4
self.len = [0] * self.base_power_4 # 0 for empty list, -1 for closed list
self.mask = mask
self.shift = self.calculate_shift(mask)

Expand All @@ -69,26 +81,26 @@ def add(self, x):
# x is hex number
if self.index[x] == -1:
st = self.start(x)
self.index[x] = st + self.tail[st]
self.index[x] = st + self.len[st]
self.mem[self.index[x]] = x
self.tail[st] += 1
self.len[st] += 1

def __len__(self):
return sum([self.mem[i] != -1 for i in range(self.base_power_4)])

def remove(self, x):
if self.index[x] != -1:
st = self.start(x)
last_element = self.mem[self.tail[st] - 1]
last_element = self.mem[self.len[st] - 1]
pos = self.index[x]
self.mem[pos] = last_element
self.index[last_element] = pos
self.index[x] = -1
self.tail[st] -= 1
self.len[st] -= 1

def ss_len(self, x):
st = self.start(x)
return self.tail[st]
return self.len[st]

def __iter__(self):
for i in range(self.base_power_4):
Expand All @@ -98,6 +110,40 @@ def __iter__(self):
def __contains__(self, x):
return self.index[x] != -1

class CL(ThreeLines):
def __init__(self, m):
super().__init__(m, 0xFFFF)
self._st = [-1] * self.base_power_4
self._mem = [-1] * self.base_power_4
for i in range(self.base_power_4):
if self._st[i] != -1:
continue
st_alf = self.start_alpha(i)
st_idx = st_alf.to_int() // 4 * 4
candidates = []
for j in range(4):
candidates.append(st_alf.to_int())
st_alf = st_alf.shift1()
if len(set(candidates)) != 4:
continue
while self._mem[st_idx] != -1:
st_idx += 4
for i, candidate in enumerate(candidates):
self._mem[st_idx+i] = candidate
self._st[candidate] = st_idx

def start_alpha(self, x):
alf = Alpha(x, self.m)
min_alf = alf
for i in range(n-1):
alf = alf.shift1()
if alf.to_hex() < min_alf.to_hex():
min_alf = alf
return min_alf

def start(self, x):
return self._st[x]

class CommaFreeCode:
def __init__(self, m, g):
self.m = m
Expand All @@ -111,7 +157,7 @@ def __init__(self, m, g):
self.s1 = ThreeLines(m, 0x000F)
self.s2 = ThreeLines(m, 0x00FF)
self.s3 = ThreeLines(m, 0x0FFF)
# self.cl = ThreeLines(m, 0xFFFF)
self.cl = CL(m)
self.alf = [0] * 16**3 * self.m
self.stamp = [0] * self.memory_size
self.sigma = 0
Expand Down Expand Up @@ -149,9 +195,12 @@ def initialize(self):
self.s1.add(i)
self.s2.add(i)
self.s3.add(i)
# for i in range(self.base_power_4):
# if self.state[i] != BLUE or self.
# self.cl[self.cl(al.to_hex())].add(i)
pr_code = self.cl.start_alpha(i)
self.cl.add(pr_code.to_int())
for j in range(n-1):
pr_code = pr_code.shift1()
if self.state[pr_code.to_int()] != RED:
self.cl.add(pr_code.to_int())

for i in range(self.code_length):
self.free[i] = i
Expand Down Expand Up @@ -186,10 +235,6 @@ def suffix2(self, alpha):
def suffix3(self, alpha):
return (alpha & 0x0FFF) << 4

def cl(self, alpha):
# Implement the logic to calculate cl(alpha)
return alpha

def search(self):
self.level = 1
while True:
Expand Down
216 changes: 115 additions & 101 deletions _code/test_algorithm_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,129 +2,143 @@
from algorithm_c import CommaFreeCode, Alpha, RED

class TestCommaFreeCode(unittest.TestCase):
def test_p1_addition(self):
m = 2
g = 57
code = CommaFreeCode(m, g)
# def test_p1_addition(self):
# m = 2
# g = 57
# code = CommaFreeCode(m, g)

code.initialize()
# code.initialize()

for i in range(code.base_power_4):
al = Alpha(i, m)
alf = code.prefix(al.to_hex())
if code.state[i] != RED:
self.assertIn(i, code.p1, f"Value {i} not found in p1[{alf}]")
self.assertGreater(len(code.p1), 0, f"p1[{alf}] is unexpectedly empty")
else:
self.assertNotIn(i, code.p1, f"Unexpected value {i} found in p1[{alf}]")
self.assertEqual(code.p1.ss_len(0), 5)
self.assertEqual(code.p1.ss_len(0b1000), 5)
# for i in range(code.base_power_4):
# al = Alpha(i, m)
# alf = code.prefix(al.to_hex())
# if code.state[i] != RED:
# self.assertIn(i, code.p1, f"Value {i} not found in p1[{alf}]")
# self.assertGreater(len(code.p1), 0, f"p1[{alf}] is unexpectedly empty")
# else:
# self.assertNotIn(i, code.p1, f"Unexpected value {i} found in p1[{alf}]")
# self.assertEqual(code.p1.ss_len(0), 5)
# self.assertEqual(code.p1.ss_len(0b1000), 5)

def test_p2_addition(self):
m = 2
g = 57
code = CommaFreeCode(m, g)
# def test_p2_addition(self):
# m = 2
# g = 57
# code = CommaFreeCode(m, g)

code.initialize()
# code.initialize()

for i in range(code.base_power_4):
al = Alpha(i, m)
alf = code.prefix2(al.to_hex())
if code.state[i] != RED:
self.assertIn(i, code.p2, f"Value {i} not found in p2[{alf}]")
self.assertGreater(len(code.p2), 0, f"p2[{alf}] is unexpectedly empty")
else:
self.assertNotIn(i, code.p2, f"Unexpected value {i} found in p2[{alf}]")
self.assertEqual(code.p2.ss_len(0), 3)
self.assertEqual(code.p2.ss_len(0b0100), 2)
self.assertEqual(code.p2.ss_len(0b1000), 2)
self.assertEqual(code.p2.ss_len(0b1100), 3)
# for i in range(code.base_power_4):
# al = Alpha(i, m)
# alf = code.prefix2(al.to_hex())
# if code.state[i] != RED:
# self.assertIn(i, code.p2, f"Value {i} not found in p2[{alf}]")
# self.assertGreater(len(code.p2), 0, f"p2[{alf}] is unexpectedly empty")
# else:
# self.assertNotIn(i, code.p2, f"Unexpected value {i} found in p2[{alf}]")
# self.assertEqual(code.p2.ss_len(0), 3)
# self.assertEqual(code.p2.ss_len(0b0100), 2)
# self.assertEqual(code.p2.ss_len(0b1000), 2)
# self.assertEqual(code.p2.ss_len(0b1100), 3)

def test_p3_addition(self):
m = 2
g = 57
code = CommaFreeCode(m, g)
# def test_p3_addition(self):
# m = 2
# g = 57
# code = CommaFreeCode(m, g)

code.initialize()
# code.initialize()

for i in range(code.base_power_4):
al = Alpha(i, m)
alf = code.prefix3(al.to_hex())
if code.state[i] != RED:
self.assertIn(i, code.p3, f"Value {i} not found in p3[{alf}]")
self.assertGreater(len(code.p3), 0, f"p3[{alf}] is unexpectedly empty")
else:
self.assertNotIn(i, code.p3, f"Unexpected value {i} found in p3[{alf}]")
self.assertEqual(code.p3.ss_len(0), 1)
self.assertEqual(code.p3.ss_len(0b0010), 2)
self.assertEqual(code.p3.ss_len(0b0110), 2)
self.assertEqual(code.p3.ss_len(0b1000), 1)
self.assertEqual(code.p3.ss_len(0b1010), 1)
self.assertEqual(code.p3.ss_len(0b1100), 2)
self.assertEqual(code.p3.ss_len(0b1110), 1)
# for i in range(code.base_power_4):
# al = Alpha(i, m)
# alf = code.prefix3(al.to_hex())
# if code.state[i] != RED:
# self.assertIn(i, code.p3, f"Value {i} not found in p3[{alf}]")
# self.assertGreater(len(code.p3), 0, f"p3[{alf}] is unexpectedly empty")
# else:
# self.assertNotIn(i, code.p3, f"Unexpected value {i} found in p3[{alf}]")
# self.assertEqual(code.p3.ss_len(0), 1)
# self.assertEqual(code.p3.ss_len(0b0010), 2)
# self.assertEqual(code.p3.ss_len(0b0110), 2)
# self.assertEqual(code.p3.ss_len(0b1000), 1)
# self.assertEqual(code.p3.ss_len(0b1010), 1)
# self.assertEqual(code.p3.ss_len(0b1100), 2)
# self.assertEqual(code.p3.ss_len(0b1110), 1)

def test_s1_addition(self):
m = 2
g = 57
code = CommaFreeCode(m, g)
# def test_s1_addition(self):
# m = 2
# g = 57
# code = CommaFreeCode(m, g)

code.initialize()
# code.initialize()

for i in range(code.base_power_4):
al = Alpha(i, m)
alf = code.suffix(al.to_hex())
if code.state[i] != RED:
self.assertIn(i, code.s1, f"Value {i} not found in s1[{alf}]")
self.assertGreater(len(code.s1), 0, f"s1[{alf}] is unexpectedly empty")
else:
self.assertNotIn(i, code.s1, f"Unexpected value {i} found in s1[{alf}]")
self.assertEqual(code.s1.ss_len(0b0010), 4)
self.assertEqual(code.s1.ss_len(0b1100), 4)
self.assertEqual(code.s1.ss_len(0b1), 6)
self.assertEqual(code.s1.ss_len(0b111), 6)
# for i in range(code.base_power_4):
# al = Alpha(i, m)
# alf = code.suffix(al.to_hex())
# if code.state[i] != RED:
# self.assertIn(i, code.s1, f"Value {i} not found in s1[{alf}]")
# self.assertGreater(len(code.s1), 0, f"s1[{alf}] is unexpectedly empty")
# else:
# self.assertNotIn(i, code.s1, f"Unexpected value {i} found in s1[{alf}]")
# self.assertEqual(code.s1.ss_len(0b0010), 4)
# self.assertEqual(code.s1.ss_len(0b1100), 4)
# self.assertEqual(code.s1.ss_len(0b1), 6)
# self.assertEqual(code.s1.ss_len(0b111), 6)

def test_s2_addition(self):
m = 2
g = 57
code = CommaFreeCode(m, g)
# def test_s2_addition(self):
# m = 2
# g = 57
# code = CommaFreeCode(m, g)

code.initialize()
# code.initialize()

for i in range(code.base_power_4):
al = Alpha(i, m)
alf = code.suffix2(al.to_hex())
if code.state[i] != RED:
self.assertIn(i, code.s2, f"Value {i} not found in s2[{alf}]")
self.assertGreater(len(code.s2), 0, f"s2[{alf}] is unexpectedly empty")
else:
self.assertNotIn(i, code.s2, f"Unexpected value {i} found in s2[{alf}]")
self.assertEqual(code.s2.ss_len(0b1100), 1)
self.assertEqual(code.s2.ss_len(0b1), 3)
self.assertEqual(code.s2.ss_len(0b10), 3)
self.assertEqual(code.s2.ss_len(0b11), 3)
# for i in range(code.base_power_4):
# al = Alpha(i, m)
# alf = code.suffix2(al.to_hex())
# if code.state[i] != RED:
# self.assertIn(i, code.s2, f"Value {i} not found in s2[{alf}]")
# self.assertGreater(len(code.s2), 0, f"s2[{alf}] is unexpectedly empty")
# else:
# self.assertNotIn(i, code.s2, f"Unexpected value {i} found in s2[{alf}]")
# self.assertEqual(code.s2.ss_len(0b1100), 1)
# self.assertEqual(code.s2.ss_len(0b1), 3)
# self.assertEqual(code.s2.ss_len(0b10), 3)
# self.assertEqual(code.s2.ss_len(0b11), 3)

def test_s3_addition(self):
# def test_s3_addition(self):
# m = 2
# g = 57
# code = CommaFreeCode(m, g)

# code.initialize()

# for i in range(code.base_power_4):
# al = Alpha(i, m)
# alf = code.suffix3(al.to_hex())
# if code.state[i] != RED:
# self.assertIn(i, code.s3, f"Value {i} not found in s3[{alf}]")
# self.assertGreater(len(code.s3), 0, f"s3[{alf}] is unexpectedly empty")
# else:
# self.assertNotIn(i, code.s3, f"Unexpected value {i} found in s3[{alf}]")
# self.assertEqual(code.s3.ss_len(0b1), 2)
# self.assertEqual(code.s3.ss_len(0b0010), 1)
# self.assertEqual(code.s3.ss_len(0b11), 2)
# self.assertEqual(code.s3.ss_len(0b1100), 1)
# self.assertEqual(code.s3.ss_len(0b1101), 1)
# self.assertEqual(code.s3.ss_len(0b110), 2)
# self.assertEqual(code.s3.ss_len(0b0111), 1)

def test_cl(self):
m = 2
g = 57
code = CommaFreeCode(m, g)

code.initialize()

for i in range(code.base_power_4):
al = Alpha(i, m)
alf = code.suffix3(al.to_hex())
alf = Alpha(i, m)
if code.state[i] != RED:
self.assertIn(i, code.s3, f"Value {i} not found in s3[{alf}]")
self.assertGreater(len(code.s3), 0, f"s3[{alf}] is unexpectedly empty")
self.assertIn(i, code.cl, f"Value {i} not found in cl[{alf}]")
self.assertGreater(len(code.cl), 0, f"cl[{alf}] is unexpectedly empty")
else:
self.assertNotIn(i, code.s3, f"Unexpected value {i} found in s3[{alf}]")
self.assertEqual(code.s3.ss_len(0b1), 2)
self.assertEqual(code.s3.ss_len(0b0010), 1)
self.assertEqual(code.s3.ss_len(0b11), 2)
self.assertEqual(code.s3.ss_len(0b1100), 1)
self.assertEqual(code.s3.ss_len(0b1101), 1)
self.assertEqual(code.s3.ss_len(0b110), 2)
self.assertEqual(code.s3.ss_len(0b0111), 1)
self.assertNotIn(i, code.cl, f"Unexpected value {i} found in cl[{alf}]")


if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 70aa177

Please sign in to comment.