• API
• FAQ
• Tools
• Archive
SHARE
TWEET

# recprimefac.py

a guest Feb 23rd, 2017 82 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #!/usr/bin/env python3
2. import sys, itertools
3. import urllib.parse
4. from collections import defaultdict, Counter
5.
6. try:
7.     import primesieve
8. except ImportError as e:
9.     sys.exit("primesieve is required. See https://pypi.python.org/pypi/primesieve")
10.
11. class RecursiveFactor:
12.     Top = itertools.repeat(0)
13.     def __init__(self, n):
14.         if isinstance(n, RecursiveFactor):
15.             if n.factors == RecursiveFactor.Top:
16.                 self.factors = RecursiveFactor.Top
17.             else:
18.                 self.factors = [RecursiveFactor(factor) for factor in n.factors]
19.         elif isinstance(n, int):
20.             if n == 0:
21.                 self.factors = RecursiveFactor.Top
22.             else:
23.                 factors = []
24.                 i = 2
25.                 print("factoring {0}".format(n))
26.                 while i * i <= n:
27.                     while n % i == 0:
28.                         n = n // i
29.                         factors.append(i)
30.                     i = i + 1
31.                 if n != 1: factors.append(n)
32.                 self.factors = [RecursiveFactor(primesieve.count_primes(factor)) for factor in factors]
33.         else:
34.             self.factors = [RecursiveFactor(factor) for factor in n]
35.         if self.factors != RecursiveFactor.Top:
36.             self.factors.sort()
37.
38.     def reduce(self, binary, unary, one, zero = None, horiz_combo = False, vert_combo = False):
39.         ''' binary expected to take sum and nextFactor
40.            unary expected to take factor (or (nextFactor, times) if horiz_combo)
41.                                or factor and depth if vert_combo)
42.            if binary = RF(a*b), you can expect sum < nextFactor
43.                 using ordinal (epsilon naught) ordering:
44.                                  (1,2,4,8,...,3,6,12...,9,...,27,...
45.                                   7,14,28,...,21,42,...,63,...
46.                                   19, ...
47.                                   ...
48.                                   5, ... 13, ... 37, ..., ..., 23, ...
49.                                   17, ..., 67, ...
50.                                   11, ......., 0)
51.            DOES NOT RECURSE - ADD RECURSION IN UNARY
52.        '''
53.         if self.factors == RecursiveFactor.Top:
54.             if zero is None:
55.                 uninput = (0,...) if horiz_combo else 0
56.                 return unary(uninput,...) if vert_combo else unary(uninput)
57.             else: return zero
58.         it = iter(sorted(Counter(self.factors).items() if horiz_combo else self.factors))
59.         out = one
60.         for factor in it:
61.             if vert_combo:
62.                 depth = 0
63.                 while(factor.is_prime()):
64.                     depth += 1
65.                     factor = factor.factors[0]
66.                 out = binary(out, unary(factor, depth))
67.             else: out = binary(out, unary(factor))
68.         return out
69.
70.     def stringify(self, left = '<', right = '>', middle = '', one = '', depth = None, zero = 'T'):
71.         ''' this.stringify([left],[right],[middle], [one], [depth])
72.            blearugh '''
73.         if depth is None:
74.             return self.reduce(lambda a, b: a+middle+b if a!=one else b,
75.                                lambda a: left
76.                                + a.stringify(left, right, middle, one = one, depth = depth, zero = zero)
77.                                + right,
78.                                one,
79.                                zero = zero)
80.         else:
81.             return self.reduce(lambda a, b: a+middle+b if a!= one else b,
82.                                lambda a, de:
83.                                    depth(de) if int(a)==1 else
84.                                    left(de)
85.                                    + a.stringify(left, right, middle, one = one, depth = depth, zero = zero)
86.                                    + right(de),
87.                                one,
88.                                zero = zero,
89.                                vert_combo = True)
90.
91.     def factor_list(self):
92.         if self.factors == RecursiveFactor.Top:
93.             return [(RecursiveFactor(0), ...)]
94.         print(str(self.factors))
95.         print(sorted(Counter(self.factors).items()))
96.         return [(RecursiveFactor(1),...)] + sorted(Counter(self.factors).items())
97.
98.     def __eq__(self,other):
99.         return self.factors == RecursiveFactor(other).factors
100.
101.     def __hash__(self):
102.         return hash(self.stringify())
103.
104.     def __ne__(self,other):
105.         other = RecursiveFactor(other)
106.         return self.factors != other.factors
107.
108.     def __lt__(self,other):
109.         other = RecursiveFactor(other)
110.         if self.factors == RecursiveFactor.Top:
111.             return False
112.         if other.factors == RecursiveFactor.Top:
113.             return True
114.         if other.factors == []:
115.             return False
116.         if self.factors == []:
117.             return True
118.         max = min(len(self.factors), len(other.factors))
119.         for i in range(max):
120.             if self.factors[-i] != other.factors[-i]:
121.                 return self.factors[-i]<other.factors[-i]
122.         return False
123.
124.     def __ge__(self,other):
125.         other = RecursiveFactor(other)
126.         return not self < other
127.
128.     def __repr__(self):
129.         return 'RecursiveFactor: [' + self.stringify(left = '[', right = ']', middle = ', ') + ']'
130.
131.     def is_symmetrical(self):
132.         if self.factors == RecursiveFactor.Top:
133.             return self
134.         elif len(self.factors)==1:
135.             return self.factors[0].is_symmetrical()
136.         else:
137.             found_odd = False
138.             for factor, times in Counter(self.factors).items():
139.                 if times % 2 == 1:
140.                     if found_odd:
141.                         return False
142.                     if not factor.is_symmetrical():
143.                         return False
144.                     found_odd = True
145.             return True
146.
147.     def is_prime(self):
148.         if self.factors == RecursiveFactor.Top:
149.             return False
150.         else:
151.             return len(self.factors)==1
152.
153.     def __int__(self):
154.         if self.factors == RecursiveFactor.Top: return 0
155.         return self.reduce(lambda x,y: x * y, lambda x: primesieve.nth_prime(x), 1)
156.
157. def get_ordinal(n, latex=True):
158.     n = RecursiveFactor(n)
159.     def unary(factory):
160.         factor = factory[0]
161.         if int(factor) == 1:
162.             return str(factory[1])
163.         times = factory[1]
164.         if times == 1: times = ''
165.         omega = r'\omega' if latex else 'ω'
166.         if int(factor) == 2:
167.             return omega + str(times)
168.         else:
169.             ordinal = get_ordinal(factor, latex=latex)
170.             if latex:
171.                 return omega + '^{' + ordinal + '}' + str(times)
172.             else:
173.                 if '+' in ordinal or times != '':
174.                     return omega + '^(' + ordinal + ')' + str(times)
175.                 else:
176.                     return omega + '^' + ordinal
177.     return n.reduce(lambda x,y:
178.                     y if x == '0' else y + '+' + x, unary, '0', zero = r'\epsilon_0' if latex else 'ε₀', horiz_combo = True)
179.
180. def full_ordinal(n):
181.     return r'\mathfrak{p}(' + get_ordinal(n) + ')'
182.
183. def get_info(n):
184.     info = {}
185.     n = RecursiveFactor(n)
186.     brackets = n.stringify()
187.     info["bracket_notation"] = brackets
188.     abc = brackets.replace('<>', 'a')
189.     letter = 'a'
190.     while letter in abc:
191.         abc = abc.replace('<'+letter+'>', chr(ord(letter)+1))
192.         letter = chr(ord(letter)+1)
193.     info["abc_notation"] = abc
194.     info["p_notation"] = n.stringify(lambda x: 'pdfghijklmnopqtuvwxyz'[x] + '<',
195.                                      lambda x: '>',
196.                                      one = 's',
197.                                      depth= lambda x: 'pdfghijklmnopqtuvwxyz'[x])
198.
199.     digits_list = []
200.     last_bracket = ''
201.     for char in brackets:
202.         if char == last_bracket:
203.             digits_list[-1] += 1
204.         else:
205.             digits_list.append(1)
206.         last_bracket = char
207.     digits = ''.join(map(str,digits_list))
208.     info["digit_notation"] = digits
209.
210.     depth = []
211.     current_depth = 0
212.     max_depth = 0
214.     for digit in digits_list[:-1]:
216.             current_depth += digit
217.         else:
218.             current_depth -= digit
219.         depth.append('*' * current_depth)
221.         if current_depth > max_depth:
222.             max_depth = current_depth
223.     info["depth_notation"] = '\n'.join(''.join(row) for row in itertools.zip_longest(*depth, fillvalue=' '))
224.     ordinal_escaped = urllib.parse.quote(full_ordinal(n))
225.     info["ordinal"] = '[img]http://latex.codecogs.com/gif.latex?' + ordinal_escaped + '[/img]'
226.
227.     info["is_prime"] = len(n.factor_list()) == 2 and n.factor_list()[1] == 1
228.     info["is_prime_power"] = len(n.factor_list()) <= 2
229.     info["is_symmetrical"] = n.is_symmetrical()
230.     info["is_alphabetical"] = not ('<' in abc)
231.
232.     factors = n.factor_list()
233.     factors = [int(factor) for factor in factors]
234.     factors.sort()
235.
236.     info["length"] = len(brackets)
237.     info["reversals"]= len(digits_list) - 1
238.     info["max_depth"] = max_depth
239.     info["factors"] = len(factors)-1
240.     info["smoothness"] = int(factors[-1][0])
241.     info["necessary_brackets"] = abc.count('<')*2
242.     return info
243.
244. def info_string(number):
245.     info = get_info(number)
246.     return '\n'.join([
247.         str(int(number)),
248.         info["bracket_notation"],
249.         info["abc_notation"],
250.         info["p_notation"],
251.         info["digit_notation"],
252.         '[code]',
253.         info["depth_notation"],
254.         '[/code]',
255.         info["ordinal"],
256.         '',
257.         'Prime: {0}'.format('Yes' if info["is_prime"] else 'No'),
258.         'Prime Power: {0}'.format('Yes' if info["is_prime_power"] else 'No'),
259.         'Symmetrical: {0}'.format('Yes' if info["is_symmetrical"] else 'No'),
260.         'Alphabetical: {0}'.format('Yes' if info["is_alphabetical"] else 'No'),
261.         '',
262.         'Length: {0}'.format(info["length"]),
263.         'Reversals: {0}'.format(info["reversals"]),
264.         'Max Depth: {0}'.format(info["max_depth"]),
265.         'Factors: {0}'.format(info["factors"]),
266.         'Smoothness: {0}'.format(info["smoothness"]),
267.         'Necessary Brackets: {0}'.format(info["necessary_brackets"])
268.     ])
269. if __name__ == '__main__':
270.     n = int(sys.argv[1] if len(sys.argv) > 1 else 1)
271.     while n != 0:
272.         print(info_string(n))
273.         print("-----------------------------------------")
274.         try: n = int(input())
275.         except:
276.             n = 0
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.

Top