-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecoder.py
205 lines (154 loc) · 4.58 KB
/
decoder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#done in python 3.9
labels_list = ['A', 'B', 'C', 'D', 'E'] #List of Labels, ordered based on Davis's Book
vars_list = ['X', 'Z'] #List of Variables, Ordered based on Davis's Book
def decode(program_code):
"""
Input (int): program_code - a command's respective code
Output (string): The command's form in Davis's language
Receives a command's respective code, and transforms it to a command of strings.
Example:
input: 21
output: [A1] X1 <- X1 + 1
"""
a, b, c = decompose(program_code)
command = transform_to_command(a, b, c)
return command
def decompose(program_code):
"""
Input (int): program_code - a command's respective code
Output (string): a structure in the form of <a, <b, c>, which represent label,
command type and variable, respectively.
Calculates a, b, c based on the pairing function 2^x(2y + 1) = z + 1
Example:
input: 21
output: 1, 1, 1 (<1, <1, 1>>)
"""
a, b, c = 0, 0, 0 #<a, <b, c>>
# Extracting a and <b, c>
temp_code = program_code + 1
twos = 0
T = 0 # <b, c>
while temp_code % 2 == 0:
twos += 1
temp_code = int(temp_code/2)
a = twos
twos = 0
T = int((temp_code - 1)/2)
# Extracting b and c
T += 1
while T % 2 == 0:
twos += 1
T = int(T/2)
b = twos
c = int((T - 1)/2)
return a, b, c
def transform_to_command(a, b, c):
"""
Inputs (int): a, b, c, three integers representing label, command type and variable, respectively
Output (string): The rescpective instruction in the form of Davis's language
Gets a, b, c and transforms them to the instruction they code, based on the algorithm in s1 ch4 of Davis.
Example:
input: 1, 1, 1
output: [A1] X1 <- X1 + 1
"""
l, var, command = "", "", ""
if a != 0:
l = label(a)
var = find_var(c + 1)
command = ""
if b == 0:
if a == 0:
command = f"{var} <- {var}"
else:
command = f"[{l}] {var} <- {var}"
elif b == 1:
if a == 0:
command = f"{var} <- {var} + 1"
else:
command = f"[{l}] {var} <- {var} + 1"
elif b == 2:
if a == 0:
command = f"{var} <- {var} - 1"
else:
command = f"[{l}] {var} <- {var} - 1"
else:
forward_label = label(b - 2)
if a == 0:
command = f"IF {var} != 0 GOTO {forward_label}"
else:
command = f"[{l}] IF {var} != 0 GOTO {forward_label}"
return command
def label(n):
"""
Input (int): Receives a label's place in their ordering
Output (string): The Label
Based on s1 ch4 of the book. The labels can be ordered like below:
A1 B1 C1 D1 E1
A2 B2 C2 D2 E2
A3 B3 C3 D3 E3
.
.
.
As they have a one-to-one relation to the natural numbers, the above ordering
becomes as follows:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
.
.
.
Paying attention, we can notice a pattern:
i) Indices of A_i % 5 = 1
ii) Indices of B_i % 5 = 2
iii) Indices of C_i % 5 = 3
iv) Indices of D_i % 5 = 4
v) Indices of E_i % 5 = 0
Using the above knowledge, we can find the correct label.
Example:
Input: 1
Output: A1
"""
if n % 5 == 0:
return f"E{int(n/5)}"
else:
num_label = int(n/5) + 1
alph_label = labels_list[int(n%5) - 1]
return f"{alph_label}{num_label}"
def find_var(n):
"""
Input (int): A variable's place in their ordering
Output (string): The variable
Based on Davis s1 ch4. The variables can be ordered like below:
Y
X1 Z1
X2 Z2
X3 Z3
.
.
.
.
As they have a one-to-one relation to the natural numbers, we can write:
1
2 3
4 5
6 7
.
.
.
The pattern is obvious: Indices of X_i is even, and Z_i's are odd.
Example:
Input: 1
Output: 'Y'
Input: 2
Output: X1
Input: 3
Output: Z1
"""
if n == 1:
return 'Y'
else:
return f"{vars_list[int(n%2)]}{int(n/2)}"
########################## THE MAIN SECTION ###############################
codes = list(map(int, input().split()))
for code in codes:
print(decode(code))