-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgfᗒO.py
More file actions
executable file
·89 lines (71 loc) · 2.31 KB
/
gfᗒO.py
File metadata and controls
executable file
·89 lines (71 loc) · 2.31 KB
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
#!/usr/bin/env python3
# Convert a Natural Gödelfish value into its resulting output encoding.
# https://esolangs.org/wiki/Gödelfish
from math import floor, log
class Memoize:
""" Memoize to speed up the recursive fn."""
def __init__(self, fn):
self.fn = fn
self.memo = {}
def __call__(self, *args):
if args not in self.memo:
self.memo[args] = self.fn(*args)
return self.memo[args]
# Final Output of a Gödelfish program, excludes the current accumulator value.
O = lambda 𝜑̈, r=10, d=4: E(𝜑̈, r**d)//r**d
@Memoize
def E(𝜑̈, z=10**4):
"""
Evaluate a Gödelfish program. Returns full state:
current accumulator and all previous output.
"""
if 𝜑̈ == 0:
return 0
return sum([v(E(s(𝜑̈, i, 2), z) % z, d(E(s(𝜑̈, i, 2), z), c(𝜑̈, i), z)) for i in range(floor(log(𝜑̈, 4)) + 2)])
def c(𝜑̈, i):
""" c: current Command."""
return s(𝜑̈, i, 1) - 4 * s(𝜑̈, i, 2)
def d(x, c, z):
""" d: Difference."""
if c == 0:
return -1
elif c == 1:
return 1
elif c == 2:
return (x%z)**2 - x%z
elif c == 3:
return x * (z - 1) + x%z
def s(𝜑̈, i, n):
""" s: current State."""
return 𝜑̈ // 4**(floor(log(𝜑̈, 4)) - i + n)
def v(a, x):
""" v: oVerflow check.
a = current accumulator
x = proposed difference
"""
if a + x < 0:
return -a
elif a + x == 256:
return -a
else:
return x
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Convert a Natural Gödelfish value into its resulting output encoding.')
parser.add_argument('value', help='Gödelfish value, 𝜑̈ ∈ ℕ')
parser.add_argument('radix', help='radix of output values', nargs='?', default='10')
parser.add_argument('digits', help='number of digits per output value in base radix', nargs='?', default='4')
args = parser.parse_args()
if args.value.startswith('0d'): # custom base-4 notation
value = int(args.value[2:], 4)
else:
value = int(args.value, 0)
radix = int(args.radix, 0)
digits = int(args.digits, 0)
o = O(value, radix, digits)
if radix == 16:
print(hex(o))
elif radix == 8:
print(oct(o))
else:
print(o)