Skip to content

Commit a008eb5

Browse files
Create coordinate_compression.py
1 parent f8ccfe8 commit a008eb5

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
"""
2+
Assumption:
3+
- The values to compress are assumed to be comparable,
4+
- values can be sorted and compared with '<' and '>' operators.
5+
"""
6+
7+
8+
class CoordinateCompressor:
9+
"""
10+
A class for coordinate compression.
11+
12+
This class allows you to compress and decompress a list of values.
13+
14+
Mapping:
15+
In addition to compression and decompression, this class maintains a mapping
16+
between original values and their compressed counterparts using two data
17+
structures: a dictionary `coordinate_map` and a list `reverse_map`.
18+
19+
- `coordinate_map`: A dictionary that maps original values to their compressed
20+
coordinates. Keys are original values, and values are compressed coordinates.
21+
22+
- `reverse_map`: A list used for reverse mapping, where each index corresponds
23+
to a compressed coordinate, and the value at that index is the original value.
24+
25+
Example mapping:
26+
27+
Original: 10, Compressed: 0
28+
Original: 52, Compressed: 1
29+
Original: 83, Compressed: 2
30+
Original: 100, Compressed: 3
31+
32+
This mapping allows for efficient compression and decompression of values within
33+
the list.
34+
"""
35+
36+
def __init__(self, arr: list[int | float | str]) -> None:
37+
"""
38+
Initialize the CoordinateCompressor with a list.
39+
40+
Args:
41+
arr: The list of values to be compressed.
42+
43+
>>> arr = [100, 10, 52, 83]
44+
>>> cc = CoordinateCompressor(arr)
45+
>>> cc.compress(100)
46+
3
47+
>>> cc.compress(52)
48+
1
49+
>>> cc.decompress(1)
50+
52
51+
"""
52+
53+
# A dictionary to store compressed coordinates
54+
self.coordinate_map: dict[int | float | str, int] = {}
55+
56+
# A list to store reverse mapping
57+
self.reverse_map: list[int | float | str] = [-1] * len(arr)
58+
59+
self.arr = sorted(arr) # The input list
60+
self.n = len(arr) # The length of the input list
61+
self.compress_coordinates()
62+
63+
def compress_coordinates(self) -> None:
64+
"""
65+
Compress the coordinates in the input list.
66+
67+
>>> arr = [100, 10, 52, 83]
68+
>>> cc = CoordinateCompressor(arr)
69+
>>> cc.coordinate_map[83]
70+
2
71+
>>> cc.coordinate_map.get(80,-1) # Value not in the original list
72+
-1
73+
>>> cc.reverse_map[2] # Value not in the original list
74+
83
75+
"""
76+
key = 0
77+
for val in self.arr:
78+
if val not in self.coordinate_map:
79+
self.coordinate_map[val] = key
80+
self.reverse_map[key] = val
81+
key += 1
82+
83+
def compress(self, original: float | str) -> int:
84+
"""
85+
Compress a single value.
86+
87+
Args:
88+
original: The value to compress.
89+
90+
Returns:
91+
The compressed integer, or -1 if not found in the original list.
92+
93+
>>> arr = [100, 10, 52, 83]
94+
>>> cc = CoordinateCompressor(arr)
95+
>>> cc.compress(100)
96+
3
97+
>>> cc.compress(7) # Value not in the original list
98+
-1
99+
"""
100+
return self.coordinate_map.get(original, -1)
101+
102+
def decompress(self, num: int) -> int | float | str:
103+
"""
104+
Decompress a single integer.
105+
106+
Args:
107+
num: The compressed integer to decompress.
108+
109+
Returns:
110+
The original value.
111+
112+
>>> arr = [100, 10, 52, 83]
113+
>>> cc = CoordinateCompressor(arr)
114+
>>> cc.decompress(0)
115+
10
116+
>>> cc.decompress(5) # Compressed coordinate out of range
117+
-1
118+
"""
119+
return self.reverse_map[num] if num < len(self.reverse_map) else -1
120+
121+
122+
if __name__ == "__main__":
123+
from doctest import testmod
124+
125+
testmod()
126+
127+
arr: list[int | float | str] = [100, 10, 52, 83]
128+
cc = CoordinateCompressor(arr)
129+
compressed: list[int] = [0] * len(arr)
130+
decompressed: list[int | float | str] = [0] * len(arr)
131+
132+
for i, original in enumerate(arr):
133+
compressed[i] = cc.compress(original)
134+
decompressed[i] = cc.decompress(compressed[i])
135+
print(f"Original: {original}, Compressed: {compressed[i]}")

0 commit comments

Comments
 (0)