import cmath, copy, functools, hashlib, itertools, locale, math, operator, re, sys, time from .utils import attrdict, lazy_import random, sympy, urllib_request = lazy_import('random sympy urllib.request') code_page = '''¡¢£¤¥¦©¬®µ½¿€ÆÇÐÑ×ØŒÞßæçðıȷñ÷øœþ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¶''' code_page += '''°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ƁƇƊƑƓƘⱮƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭ§Äẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏż«»‘’“”''' # Unused symbols for single-byte atoms/quicks: (quƁƘȤɦɱɲƥʠʂȥḥḳṇẉỵẓėġṅẏ str_digit = '0123456789' str_lower = 'abcdefghijklmnopqrstuvwxyz' str_upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' inf = float('inf') nan = float('nan') sys.setrecursionlimit(1 << 30) def arities(links): return [link.arity for link in links] def at_index(index, array): array = iterable(array) if not array: return 0 low_index = math.floor(index) - 1 high_index = math.ceil(index) - 1 if low_index == high_index: return array[low_index % len(array)] return [array[low_index % len(array)], array[high_index % len(array)]] def at_index_ndim(indices, array): retval = array for index in indices: retval = at_index(index, retval) return retval def base_decompression(integer, digits): digits = iterable(digits, make_range=True) return [digits[i-1] for i in to_base(integer, len(digits))] def bounce(array): return array[:-1] + array[::-1] def carmichael(n): n = int(n) if n < 1: return 0 c = 1 for p, k in sympy.ntheory.factor_.factorint(n).items(): c = lcm(c, 2 ** (k - 2) if p == 2 < k else (p - 1) * p ** (k - 1)) return c def create_chain(chain, arity = -1, isForward = True): return attrdict( arity = arity, chain = chain, call = lambda x = None, y = None: variadic_chain(chain, isForward and (x, y) or (y, x)) ) def create_literal(string): return attrdict( arity = 0, call = lambda: python_eval(string, False) ) def conv_dyadic_integer(link, larg, rarg): try: iconv_larg = int(larg) try: iconv_rarg = int(rarg) return link(iconv_larg, iconv_rarg) except: return iconv_larg except: try: return int(rarg) except: return 0 def conv_monadic_integer(link, arg): try: return link(int(arg)) except: return 0 def convolve(left, right): left, right = iterable(left, make_range = True), iterable(right, make_range = True) result = [0]*(len(left)+len(right)-1) for i,x in enumerate(left): for j,y in enumerate(right): result[i+j] += x*y return result def convolve_power(polynomial, exponent): retval = [1] for _ in range(exponent): retval = convolve(retval, polynomial) return retval def copy_to(atom, value): atom.call = lambda: value return value def determinant(matrix): matrix = sympy.Matrix(matrix) if matrix.is_square: return simplest_number(matrix.det()) return simplest_number(math.sqrt((matrix * matrix.transpose()).det())) def div(dividend, divisor, floor = False): if divisor == 0: return dividend * inf if divisor == inf: return 0 if floor or (type(dividend) == int and type(divisor) == int and not dividend % divisor): return int(dividend // divisor) return dividend / divisor def depth(link): if type(link) != list: return 0 if not link: return 1 return 1 + max(map(depth, link)) def diagonals(matrix): shifted = [None] * len(matrix) for index, row in enumerate(map(iterable, reversed(matrix))): shifted[~index] = index * [None] + row return rotate_left(zip_ragged(shifted), len(matrix) - 1) def distinct_sieve(array): array = iterable(array, make_digits = True) result = [] for (i, x) in enumerate(array): result.append(1 if i == array.index(x) else 0) return result def dot_product(left, right, truncate = False): left, right = iterable(left), iterable(right) if complex in map(type, left + right): right = [complex(t).conjugate() for t in right] if truncate: product = sum(map(operator.mul, left, right)) else: product = sum(dyadic_link(atoms['×'], (left, right))) if product.imag == 0: product = product.real if type(product) != int and product.is_integer(): product = int(product) return product def dyadic_chain(chain, args): larg, rarg = args for link in chain: if link.arity < 0: link.arity = 2 if chain and arities(chain[0:3]) == [2, 2, 2]: ret = dyadic_link(chain[0], args) chain = chain[1:] elif leading_nilad(chain): ret = niladic_link(chain[0]) chain = chain[1:] else: ret = larg while chain: if arities(chain[0:3]) == [2, 2, 0] and leading_nilad(chain[2:]): ret = dyadic_link(chain[1], (dyadic_link(chain[0], (ret, rarg)), niladic_link(chain[2]))) chain = chain[3:] elif arities(chain[0:2]) == [2, 2]: ret = dyadic_link(chain[0], (ret, dyadic_link(chain[1], args))) chain = chain[2:] elif arities(chain[0:2]) == [2, 0]: ret = dyadic_link(chain[0], (ret, niladic_link(chain[1]))) chain = chain[2:] elif arities(chain[0:2]) == [0, 2]: ret = dyadic_link(chain[1], (niladic_link(chain[0]), ret)) chain = chain[2:] elif chain[0].arity == 2: ret = dyadic_link(chain[0], (ret, rarg)) chain = chain[1:] elif chain[0].arity == 1: ret = monadic_link(chain[0], ret) chain = chain[1:] else: output(ret) ret = niladic_link(chain[0]) chain = chain[1:] return ret def dyadic_link(link, args, conv = True, lflat = False, rflat = False): larg, rarg = args lflat = lflat or not hasattr(link, 'ldepth') rflat = rflat or not hasattr(link, 'rdepth') larg_depth = lflat or depth(larg) rarg_depth = rflat or depth(rarg) if (lflat or link.ldepth == larg_depth) and (rflat or link.rdepth == rarg_depth): if conv and hasattr(link, 'conv'): return link.conv(link.call, larg, rarg) return link.call(larg, rarg) conv = conv and hasattr(link, 'conv') if not lflat and larg_depth < link.ldepth: return dyadic_link(link, ([larg], rarg)) if not rflat and rarg_depth < link.rdepth: return dyadic_link(link, (larg, [rarg])) if not rflat and (lflat or larg_depth - rarg_depth < link.ldepth - link.rdepth): return [dyadic_link(link, (larg, y)) for y in rarg] if not lflat and (rflat or larg_depth - rarg_depth > link.ldepth - link.rdepth): return [dyadic_link(link, (x, rarg)) for x in larg] return [dyadic_link(link, (x, y)) for x, y in zip(*args)] + larg[len(rarg) :] + rarg[len(larg) :] def enumerate_md(array, upper_level = []): for i, item in enumerate(array): if type(item) != list: yield [upper_level + [i + 1], item] else: yield from enumerate_md(item, upper_level + [i + 1]) def equal(array): array = iterable(array) return int(all(item == array[0] for item in array)) def extremes(min_or_max, link, array): x,y = array x = iterable(x, make_range=True) if not x: return [] results = [variadic_link(link, (t, y)) for t in x] best = min_or_max(results) return [t for t, ft in zip(x, results) if ft == best] def filter_array(sand, mesh, is_in = True): mesh = {repr(element) for element in iterable(mesh)} return [element for element in iterable(sand) if (repr(element) in mesh) == is_in] def flatten(argument): flat = [] if type(argument) == list: for item in argument: flat += flatten(item) else: flat.append(argument) return flat def foldl(*args): return reduce(*args, arity = 2) def from_base(digits, base): integer = 0 for digit in digits: integer = base * integer + digit return integer def from_diagonals(diagonals): upper_right = 1 while len(diagonals[upper_right - 1]) > 1: upper_right += 1 diagonals = rotate_left(diagonals, upper_right) shift = len(diagonals) - upper_right index = 0 while shift: diagonals[index] = shift * [None] + diagonals[index] index += 1 shift -= 1 return zip_ragged(diagonals) def from_exponents(exponents): integer = 1 for index, exponent in enumerate(exponents): integer *= sympy.ntheory.generate.prime(index + 1) ** exponent return integer def from_factorial_base(digits): placeValue = 1 integer = 0 for nextPlaceIndex, digit in enumerate(digits[::-1], 1): integer += digit * placeValue placeValue *= nextPlaceIndex return integer def from_primorial_base(digits): integer = digits and digits[-1] or 0 for placeIndex, digit in enumerate(digits[-2::-1], 1): integer += digit * sympy.ntheory.generate.primorial(placeIndex) return integer def simplest_number(number): if abs(number ** 2) != number ** 2: return number if number % 1: return float(number) return int(number) def get_request(url): url = ''.join(map(str, url)) url = (re.match(r"[A-Za-z][A-Za-z0-9+.-]*://", url) == None and "http://" or "") + url response = urllib_request.request.urlopen(url).read() try: return list(response.decode('utf-8')) except: return list(response.decode('latin-1')) def grid(array): if depth(array) == 1: return join(array, ' ') if depth(array) == 2 and equal(map(len, array)): array = [[str(entry) for entry in row] for row in array] width = max(max([len(entry) for entry in row]) if row else 0 for row in array) array = [[list(entry.rjust(width)) for entry in row] for row in array] return join([join(row, ' ') for row in array], '\n') if depth(array) == 3 and all(type(item) == str for item in flatten(array)): array = [[''.join(entry) for entry in row] for row in array] width = max(max([len(entry) for entry in row]) if row else 0 for row in array) array = [[list(entry.ljust(width)) for entry in row] for row in array] return join([join(row, ' ') for row in array], '\n') return join(array, '\n') def group(array): array = iterable(array, make_digits = True) grouped = {} for index, item in enumerate(array): item = repr(item) if item in grouped: grouped[item].append(index + 1) else: grouped[item] = [index + 1] try: return [grouped[key] for key in sorted(grouped, key = eval)] except TypeError: return [grouped[key] for key in sorted(grouped)] def group_md(array): array = iterable(array, make_digits = True) grouped = {} for index, item in enumerate_md(array): item = repr(item) if item in grouped: grouped[item].append(index) else: grouped[item] = [index] try: return [grouped[key] for key in sorted(grouped, key = eval)] except TypeError: return [grouped[key] for key in sorted(grouped)] def group_equal(array): array = iterable(array, make_digits = True) groups = [] for x in array: if groups and groups[-1][0] == x: groups[-1].append(x) else: groups.append([x]) return groups def group_lengths(array): array = iterable(array, make_digits = True) lengths = [] previous_item = None for x in array: if lengths and previous_item == x: lengths[-1] += 1 else: lengths.append(1) previous_item = x return lengths def identity(argument): return argument def iterable(argument, make_copy = False, make_digits = False, make_range = False): the_type = type(argument) if the_type == list: return copy.deepcopy(argument) if make_copy else argument if the_type != str and make_digits: return to_base(argument, 10) if the_type != str and make_range: return list(range(1, int(argument) + 1)) return [argument] def index_of(haystack, needle): for index, item in enumerate(iterable(haystack)): if item == needle: return 1 + index return 0 def index_of_md(haystack, needle): for index, item in enumerate_md(haystack): if item == needle: return index return [] def indices_md(array, upper_level = []): a_indices = [] for i, item in enumerate(array): if type(item) != list: a_indices.append(upper_level + [i + 1]) else: a_indices.extend(indices_md(item, upper_level = upper_level + [i + 1])) return a_indices def isqrt(number): a = number b = (a + 1) // 2 while b < a: a = b b = (a + number // a) // 2 return int(a) def is_palindrome(argument): argument = iterable(argument, make_digits = True) return int(argument == argument[::-1]) def is_string(argument): if type(argument) != list: return False return all(map(lambda t: type(t) == str, argument)) def jelly_eval(code, arguments): return variadic_chain(parse_code(code)[-1] if code else '', arguments) def jelly_hash(spec, object): if len(spec) > 2: spec = [spec[0], spec[1:]] if type(spec[0]) == list: digits = [code_page.find(item) if type(item) == str else item for item in spec[0]] magic = from_base([digit + 1 for digit in digits], 250) + 1 else: magic = spec[0] + 1 buckets = spec[1] if type(spec[1]) == list else range(1, spec[1] + 1) shake = hashlib.shake_256(repr(object).encode('utf-8')).digest(512) longs = [int.from_bytes(shake[i : i + 8], 'little') for i in range(0, 512, 8)] temp = sum(((magic >> i) - (magic >> i + 1)) * longs[i] for i in range(64)) hash = temp % 2**64 * len(buckets) >> 64 return buckets[hash - 1] def jelly_uneval(argument, top = True): the_type = type(argument) if the_type in (float, int): return jelly_uneval_real(argument) if the_type == complex: return jelly_uneval_real(argument.real) + 'ı' + jelly_uneval_real(argument.imag) if the_type == str: return '”' + argument if all(map(is_string, argument)): strings = [''.join(string) for string in argument] if all(map(lambda t: code_page.find(t) < 250, ''.join(strings))): return '“' + '“'.join(strings) + '”' if is_string(argument): string = ''.join(argument) if all(map(lambda t: code_page.find(t) < 250, string)): return '“' + string + '”' middle = ','.join(jelly_uneval(item, top = False) for item in argument) return middle if top else '[' + middle + ']' def jelly_uneval_real(number): string = str(number if number % 1 else int(number)) return string.lstrip('0') if number else string def jellify(element, dirty = False): if element is None: return [] if type(element) == str and dirty: return list(element) if type(element) in (int, float, complex) or (type(element) == str and len(element) == 1): return element try: return [jellify(item, dirty) for item in element] except: if element.is_integer: return int(element) if element.is_real: return float(element) return complex(element) def join(array, glue): array = iterable(array, make_copy = True) last = array.pop() if array else [] glue = iterable(glue) ret = [] for item in array: ret += iterable(item) + glue return ret + iterable(last) def last_input(): if len(sys.argv) > 3: return python_eval(sys.argv[-1]) return python_eval(input()) def leading_nilad(chain): return chain and arities(chain) + [1] < [0, 2] * len(chain) def lcm(x, y): return x * y // (math.gcd(x, y) or 1) def loop_until_loop(link, args, return_all = False, return_loop = False, vary_rarg = True): ret, rarg = args cumret = [] while True: cumret.append(ret) larg = ret ret = variadic_link(link, (larg, rarg)) if vary_rarg: rarg = larg if ret in cumret: if return_all: return cumret if return_loop: return cumret[index_of(cumret, ret) - 1 :] return larg def nfind(links, args): larg, rarg = args larg = larg or 0 matches = variadic_link(links[1], args) if len(links) == 2 else last_input() found = [] while len(found) < matches: if variadic_link(links[0], (larg, rarg)): found.append(larg) larg += 1 return found def matrix_to_list(matrix): return [[simplest_number(entry) for entry in row] for row in matrix.tolist()] def max_arity(links): return max(arities(links)) if min(arities(links)) > -1 else (~max(arities(links)) or -1) def maximal_indices(iterable): maximum = max(iterable or [0]) return [u + 1 for u, v in enumerate(iterable) if v == maximum] def maximal_indices_md(iterable, upper_level = [], maximum = None): if maximum == None: maximum = max(flatten(iterable) or [0]) result = [] for i, item in enumerate(iterable): if type(item) != list: if item == maximum: result.append(upper_level + [i + 1]) else: result.extend(maximal_indices_md(item, upper_level = upper_level + [i + 1], maximum = maximum)) return result def median(array): array = sorted(array) return div(array[(len(array) - 1) // 2] + array[len(array) // 2], 2) def mode(array): frequencies = {} maxfreq = 0 retval = [] for element in array: string = repr(element) frequencies[string] = frequencies.get(string, 0) + 1 maxfreq = max(frequencies[string], maxfreq) for element in array: string = repr(element) if frequencies[string] == maxfreq: retval.append(element) frequencies[string] = 0 return retval def modinv(a, m): i, _, g = sympy.numbers.igcdex(a, m) return i % m if g == 1 else 0 def modulus(dividend, divisor): try: return dividend % divisor except: return nan def mold(content, shape): for index in range(len(shape)): if type(shape[index]) == list: mold(content, shape[index]) else: item = content.pop(0) shape[index] = item content.append(item) return shape def monadic_chain(chain, arg): init = True ret = arg larg_save = atoms['⁸'].call while True: if init: for link in chain: if link.arity < 0: link.arity = 1 if leading_nilad(chain): ret = niladic_link(chain[0]) chain = chain[1:] init = False if not chain: break if arities(chain[0:2]) == [2, 1]: ret = dyadic_link(chain[0], (ret, monadic_link(chain[1], arg))) chain = chain[2:] elif arities(chain[0:2]) == [2, 0]: ret = dyadic_link(chain[0], (ret, niladic_link(chain[1]))) chain = chain[2:] elif arities(chain[0:2]) == [0, 2]: ret = dyadic_link(chain[1], (niladic_link(chain[0]), ret)) chain = chain[2:] elif chain[0].arity == 2: ret = dyadic_link(chain[0], (ret, arg)) chain = chain[1:] elif chain[0].arity == 1: if not chain[1:] and hasattr(chain[0], 'chain'): arg = ret chain = chain[0].chain atoms['⁸'].call = lambda literal = arg: literal init = True else: ret = monadic_link(chain[0], ret) chain = chain[1:] else: output(ret) ret = niladic_link(chain[0]) chain = chain[1:] atoms['⁸'].call = larg_save return ret def monadic_link(link, arg, flat = False, conv = True): flat = flat or not hasattr(link, 'ldepth') arg_depth = flat or depth(arg) if flat or link.ldepth == arg_depth: if conv and hasattr(link, 'conv'): return link.conv(link.call, arg) return link.call(arg) conv = conv and hasattr(link, 'conv') if link.ldepth > arg_depth: return monadic_link(link, [arg], conv = conv) return [monadic_link(link, z, conv = conv) for z in arg] def multiset_difference(left, right): result = iterable(left)[::-1] for element in iterable(right): if element in result: result.remove(element) return result[::-1] def multiset_intersect(left, right): right = iterable(right, make_copy = True) result = [] for element in iterable(left): if element in right: result.append(element) right.remove(element) return result def multiset_symdif(left, right): return multiset_union(multiset_difference(left, right), multiset_difference(right, left)) def multiset_union(left, right): return iterable(left) + multiset_difference(right, left) def nCr(left, right): if type(left) == int and type(right) == int: if right < 0: right = left - right if right < 0 or (left > 0 and right > left): return 0 if left > 0: right = min(right, left - right) result = 1 for i in range(right): result = result * (left - i) // (i + 1) return result return div(Pi(left), Pi(left - right) * Pi(right)) def niladic_chain(chain): while len(chain) == 1 and hasattr(chain[0], 'chain'): chain = chain[0].chain if not chain or chain[0].arity > 0: return monadic_chain(chain, 0) return monadic_chain(chain[1:], chain[0].call()) def niladic_link(link): return link.call() def ntimes(links, args, cumulative = False): ret, rarg = args repetitions = variadic_link(links[1], args) if len(links) == 2 else last_input() repetitions = overload((int, bool), repetitions) if cumulative: cumret = [0] * repetitions for index in range(repetitions): if cumulative: cumret[index] = ret larg = ret ret = variadic_link(links[0], (larg, rarg)) rarg = larg return cumret + [ret] if cumulative else ret def odd_even(array): array = iterable(array, make_range = True) return [[t for t in array[::2]], [t for t in array[1::2]]] def order(number, divisor): if number == 0 or abs(divisor) == 1: return inf if divisor == 0: return 0 ret = 0 while True: number, residue = divmod(number, divisor) if residue: break ret += 1 return ret def overload(operators, *args): for operator in operators: try: ret = operator(*args) except: pass else: return ret def integer_partitions(n, I=1): result = [[n,]] for i in range(I, n//2 + 1): for p in integer_partitions(n-i, i): result.append([i,] + p) return result def neighbors(links, array): array = iterable(array, make_digits = True) chain = dyadic_chain if links[-1].arity == 2 else monadic_chain return [chain(links, list(pair)) for pair in zip(array, array[1:])] def partitions(array): array = iterable(array, make_digits = True) ret = [] for index in range(1, len(array)): for subarray in partitions(array[index:]): subarray.insert(0, array[:index]) ret.append(subarray) ret.append([array]) return ret def parse_code(code): lines = regex_flink.findall(code) links = [[] for line in lines] for index, line in enumerate(lines): chains = links[index] for word in regex_chain.findall(line): chain = [] arity, start, isForward = chain_separators.get(word[:1], default_chain_separation) for token in regex_token.findall(start + word): if token in atoms: chain.append(atoms[token]) elif token in quicks: popped = [] while not quicks[token].condition(popped) and (chain or chains): popped.insert(0, chain.pop() if chain else chains.pop()) chain += quicks[token].quicklink(popped, links, index) elif token in hypers: x = chain.pop() if chain else chains.pop() chain.append(hypers[token](x, links)) else: chain.append(create_literal(regex_liter.sub(parse_literal, token))) chains.append(create_chain(chain, arity, isForward)) return links def parse_literal(literal_match): literal = literal_match.group(0) if literal[0] in '”⁾': return repr(literal[1:].replace('¶', '\n')) elif literal[0] == '“': if literal[-1] in '«»‘’”': mode = literal[-1] literal = literal[:-1] else: mode = '' parsed = literal.split('“')[1:] if mode == '»': parsed = [sss(string).replace('¶', '\n') for string in parsed] elif mode == '‘': parsed = [[code_page.find(char) for char in string] for string in parsed] elif mode == '’': parsed = [from_base([code_page.find(char) + 1 for char in string], 250) for string in parsed] else: parsed = [string.replace('¶', '\n') for string in parsed] if mode not in '‘’': parsed = [[string] if len(string) == 1 else string for string in parsed] if len(parsed) == 1: parsed = parsed[0] elif literal[0] == '⁽': parsed = from_base([code_page.find(char) + 1 for char in literal[1:]], 250) parsed += parsed > 31500 and -62850 or 750 else: parsed = eval('+ 1j *'.join([ repr(eval('* 10 **'.join(['-1' if part == '-' else (part + '5' if part[-1:] == '.' else part) or repr(2 * index + 1) for index, part in enumerate(component.split('ȷ'))])) if component else index) for index, component in enumerate(literal.split('ı')) ])) return repr(parsed) + ' ' def partition_at(booleans, array, border = 1): booleans = iterable(booleans) array = iterable(array) chunks = [[], []] index = 0 while index < len(array): if index < len(booleans) and booleans[index]: chunks.append([]) chunks[-border].append(array[index]) else: chunks[-1].append(array[index]) index += 1 return chunks[1:] def pemutation_at_index(index, array = None): result = [] if array is None: divisor = 1 count = 0 while divisor < index: count += 1 divisor *= count values = list(range(1, count + 1)) else: values = iterable(array, make_copy = True, make_range = True) try: divisor = math.factorial(len(values)) except: divisor = functools.reduce(operator.mul, range(1, len(values) + 1), 1) index -= 1 index %= divisor while values: divisor //= len(values) quotient, index = divmod(index, divisor) result.append(values.pop(quotient)) return result def permutation_index(array): result = 1 array = iterable(array) length = len(array) for index in range(length): k = sum(1 for value in array[index + 1:] if value < array[index]) try: factor = math.factorial(length - index - 1) except: factor = functools.reduce(operator.mul, range(1, length - index), 1) result += k * factor return result def Pi(number): if type(number) == int: if number < 0: return inf try: return math.factorial(number) except: return functools.reduce(operator.mul, range(1, number + 1), 1) return math.gamma(number + 1) def powerset(array): array = iterable(array, make_range = True) ret = [] for t in range(len(array) + 1): ret += jellify(itertools.combinations(array, t)) return ret def prefix(links, outmost_links, index): ret = [attrdict(arity = max(1, links[0].arity))] if len(links) == 1: ret[0].call = lambda x, y = None: [variadic_link(links[0], (t, y)) for t in split_prefix(x)] else: ret[0].call = lambda x, y = None: [variadic_link(links[0], (t, y)) for t in split_rolling(x, niladic_link(links[1]))] return ret def primerange(start, end): if start > end: return list(sympy.primerange(end, start + 1))[::-1] else: return list(sympy.primerange(start, end + 1)) def python_eval(string, dirty = True): try: return jellify(eval(string), dirty) except SyntaxError: exec(string) return [] def quickchain(arity, min_length): return attrdict( condition = (lambda links: len(links) >= min_length and links[0].arity == 0) if arity == 0 else lambda links: len(links) - sum(map(leading_nilad, split_suffix(links)[:-1])) >= min_length, quicklink = lambda links, outmost_links, index: [attrdict( arity = arity, call = lambda x = None, y = None: variadic_chain(links, (x, y)) )] ) def random_int(pool): if not pool: return 0 if type(pool) == list: return random.choice(pool) return random.randint(1, pool) def reduce(links, outmost_links, index, arity = 1): ret = [attrdict(arity = arity)] if len(links) == 1: ret[0].call = lambda x, *y: reduce_simple(x, links[0], *y) else: ret[0].call = lambda x, *y: [reduce_simple(t, links[0], *y) for t in split_fixed(iterable(x), links[1].call())] return ret def reduce_simple(array, link, *init): array = iterable(array) return functools.reduce(lambda x, y: dyadic_link(link, (x, y)), array, *init) def reduce_cumulative(links, outmost_links, index): ret = [attrdict(arity = 1)] if len(links) == 1: ret[0].call = lambda t: list(itertools.accumulate(iterable(t), lambda x, y: dyadic_link(links[0], (x, y)))) else: ret[0].call = lambda z: [reduce_simple(t, links[0]) for t in split_rolling(iterable(z), links[1].call())] return ret def rld(runs): return list(itertools.chain(*[[u] * v for u, v in runs])) def rle(array): return [[group[0], len(group)] for group in group_equal(array)] def rotate_left(array, units): array = iterable(array) length = len(array) return array[units % length :] + array[: units % length] if length else [] def shift_left(number, bits): if type(number) == int and type(bits) == int: return number << bits return number * 2 ** bits def shift_right(number, bits): if type(number) == int and type(bits) == int: return number >> bits return div(number, 2 ** bits, floor = True) def shuffle(array): array = iterable(array, make_copy = True, make_range = True) random.shuffle(array) return array def sparse(link, args, indices, indices_literal = False): larg = args[0] if not indices_literal: indices = iterable(variadic_link(indices, args)) indices = [index - 1 if index > 0 else index - 1 + len(larg) for index in indices] ret = iterable(variadic_link(link, args)) return [ret[t % len(ret)] if t in indices else u for t, u in enumerate(larg)] def split_around(array, needle): chunk = [] window = len(needle) index = 0 while index < len(array): if array[index : index + window] == needle: yield chunk chunk = [] index += window else: chunk.append(array[index]) index += 1 yield chunk def split_at(array, needle): chunk = [] for element in array: if element == needle: yield chunk chunk = [] else: chunk.append(element) yield chunk def split_evenly(array, chunks): array = iterable(array) min_width, overflow = divmod(len(array), chunks) ret = [] high = 0 for index in range(chunks): low = high high = low + min_width + (index < overflow) ret.append(array[low : high]) return ret def split_fixed(array, width): if width < 0: return split_fixed_out(array, -width) array = iterable(array) return [array[index : index + width] for index in range(0, len(array), width)] def split_fixed_out(array, width): array = iterable(array) return [array[:index] + array[index + width:] for index in range(0, len(array), width)] def split_key(control, data): groups = {} order = [] count = 0 for key, item in zip(control, data): key = repr(key) if type(key) == list else key if key not in groups: order.append(key) groups[key] = [] groups[key].append(item) count += 1 result = [groups[key] for key in order] if count < len(data): result.append(data[count:]) return result def split_once(array, needle): array = iterable(array, make_digits = True) index = index_of(array, needle) return [array[0 : index - 1], array[index :]] if index else [array] def split_prefix(array): array = iterable(array) return [array[:index + 1] for index in range(len(array))] def split_rolling(array, width): if width < 0: return split_rolling_out(array, -width) array = iterable(array) return [array[index : index + width] for index in range(len(array) - width + 1)] def split_rolling_out(array, width): array = iterable(array) return [array[:index] + array[index + width:] for index in range(len(array) - width + 1)] def split_suffix(array): array = iterable(array) return [array[index:] for index in range(len(array))] def sss(compressed): from . import dictionary decompressed = '' integer = from_base([code_page.find(char) + 1 for char in compressed], 250) while integer: integer, mode = divmod(integer, 3) if mode == 0: integer, code = divmod(integer, 96) decompressed += code_page[code + 32] else: flag_swap = False flag_space = decompressed != '' if mode == 2: integer, flag = divmod(integer, 3) flag_swap = flag != 1 flag_space ^= flag != 0 integer, short = divmod(integer, 2) the_dictionary = (dictionary.long, dictionary.short)[short] integer, index = divmod(integer, len(the_dictionary)) word = the_dictionary[index] if flag_swap: word = word[0].swapcase() + word[1:] if flag_space: word = ' ' + word decompressed += word return decompressed def stringify(iterable, recurse = True): if type(iterable) != list: return iterable if len(iterable) == 1: return stringify(iterable[0]) if str in map(type, iterable) and not list in map(type, iterable) or not iterable: return ''.join(map(str, iterable)) iterable = [stringify(item) for item in iterable] return stringify(iterable, False) if recurse else iterable def suffix(links, outmost_links, index): ret = [attrdict(arity = max(1, links[0].arity))] if len(links) == 1: ret[0].call = lambda x, y = None: [variadic_link(links[0], (t, y)) for t in split_suffix(x)] else: ret[0].call = lambda x, y = None: [variadic_link(links[0], (t, y)) for t in split_fixed(x, niladic_link(links[1]))] return ret def symmetric_mod(number, half_divisor): modulus = number % (2 * half_divisor) return modulus - 2 * half_divisor * (modulus > half_divisor) def tie(links, outmost_links, index): ret = [attrdict(arity= max(1, *arities(links)))] n = 2 if links[-1].arity else links[-1].call() def _make_tie(): i = 0 while True: yield links[i] i = (i + 1) % n cycle = _make_tie() ret[0].call = lambda x = None, y = None: variadic_link(next(cycle), (x, y)) return ret def time_format(bitfield): time_string = ':'.join(['%H'] * (bitfield & 4 > 0) + ['%M'] * (bitfield & 2 > 0) + ['%S'] * (bitfield & 1 > 0)) return list(time.strftime(time_string)) def translate(mapping, array): array = iterable(array, make_copy = True) mapping = iterable(mapping, make_copy = True) while mapping: source = iterable(mapping.pop(0)) destination = iterable(mapping.pop(0)) for (index, item) in enumerate(array): if item in source: array[index] = destination[min(source.index(item), len(destination) - 1)] return array def trim(trimmee, trimmer, left = False, right = False): lindex = 0 rindex = len(trimmee) if left: while lindex < rindex and trimmee[lindex] in trimmer: lindex += 1 if right: while lindex < rindex and trimmee[rindex - 1] in trimmer: rindex -= 1 return trimmee[lindex:rindex] def try_eval(string): try: return python_eval(string) except: return jellify(string, True) def to_base(integer, base, bijective = False): if integer == 0: return [0] * (not bijective) if bijective: base = abs(base) if base == 0: return [integer] if base == -1: digits = [1, 0] * abs(integer) return digits[:-1] if integer > 0 else digits sign = -1 if integer < 0 and base > 0 else 1 integer *= sign if base == 1: return [sign] * integer digits = [] while integer: integer -= bijective integer, digit = divmod(integer, base) digit += bijective if digit < 0: integer += 1 digit -= base digits.append(sign * digit) return digits[::-1] def to_case(argument, lower = False, swap = False, title = False, upper = False): ret = [] last_item = ' ' for item in argument: if type(item) == str: if lower: ret.append(item.lower()) elif swap: ret.append(item.swapcase()) elif title: ret.append(item.lower() if type(last_item) == str and last_item in str_upper + str_lower else item.upper()) elif upper: ret.append(item.upper()) else: ret.append(item) last_item = item return ret def to_exponents(integer): if integer == 1: return [] pairs = sympy.ntheory.factor_.factorint(integer) exponents = [] for prime in sympy.ntheory.generate.primerange(2, max(pairs) + 1): if prime in pairs: exponents.append(pairs[prime]) else: exponents.append(0) return exponents def to_factorial_base(integer): radix = 1 digits = [] while integer: integer, remainder = divmod(integer, radix) digits.append(remainder) radix += 1 return digits[::-1] or [0] def to_primorial_base(integer): placeIndex = 1 integer, remainder = divmod(integer, 2) digits = [remainder] while integer: placeIndex += 1 integer, remainder = divmod(integer, sympy.ntheory.generate.prime(placeIndex)) digits.append(remainder) return digits[::-1] def unicode_to_jelly(string): return ''.join(chr(code_page.find(char)) for char in str(string).replace('\n', '¶') if char in code_page) def unique(array): array = iterable(array, make_digits = True) result = [] for element in array: if not element in result: result.append(element) return result def untruth_md(indices, shape = None, upper_level = []): if not shape: shape = [max(index_zipped) for index_zipped in zip(*indices)] upper_len = len(upper_level) if upper_len < len(shape) - 1: return [untruth_md(indices, shape = shape, upper_level = upper_level + [i + 1]) for i in range(shape[upper_len])] else: return [1 if (upper_level + [i + 1] in indices) else 0 for i in range(shape[-1])] def variadic_chain(chain, args): args = list(filter(None.__ne__, args)) larg_save = atoms['⁸'].call rarg_save = atoms['⁹'].call if len(args) == 0: return niladic_chain(chain) if len(args) == 1: atoms['⁸'].call = lambda literal = args[0]: literal ret = monadic_chain(chain, args[0]) if len(args) == 2: atoms['⁸'].call = lambda literal = args[0]: literal atoms['⁹'].call = lambda literal = args[1]: literal ret = dyadic_chain(chain, args) atoms['⁸'].call = larg_save atoms['⁹'].call = rarg_save return ret def variadic_link(link, args, flat = False, lflat = False, rflat = False): if link.arity < 0: args = list(filter(None.__ne__, args)) link.arity = len(args) if link.arity == 0: return niladic_link(link) if link.arity == 1: return monadic_link(link, args[0], flat) if link.arity == 2: return dyadic_link(link, args, lflat, rflat) def while_loop(link, condition, args, cumulative = False): ret, rarg = args cumret = [] while variadic_link(condition, (ret, rarg)): if cumulative: cumret.append(ret) larg = ret ret = variadic_link(link, (larg, rarg)) rarg = larg return cumret + [ret] if cumulative else ret def windowed_exists(needle, haystack): haystack = iterable(haystack, make_digits = True) needle = iterable(needle, make_digits = True) needle_length = len(needle) for index in range(len(haystack)): if haystack[index : index + needle_length] == needle: return 1 return 0 def windowed_index_of(haystack, needle): haystack = iterable(haystack, make_digits = True) needle = iterable(needle, make_digits = True) needle_length = len(needle) for index in range(len(haystack)): if haystack[index : index + needle_length] == needle: return 1 + index return 0 def windowed_sublists(array): array = iterable(array, make_range = True) return [sublist for width in range(1, len(array) + 1) for sublist in split_rolling(array, width)] def output(argument, end = '', transform = stringify): if locale.getdefaultlocale()[1][0:3] == 'UTF': print(transform(argument), end = end) else: print(unicode_to_jelly(transform(argument)), end = unicode_to_jelly(end)) sys.stdout.flush() return argument def zip_ragged(array): return jellify(map(lambda t: filter(None.__ne__, t), itertools.zip_longest(*map(iterable, array)))) atoms = { '³': attrdict( arity = 0, call = lambda: 100 ), '⁴': attrdict( arity = 0, call = lambda: 16 ), '⁵': attrdict( arity = 0, call = lambda: 10 ), '⁶': attrdict( arity = 0, call = lambda: ' ' ), '⁷': attrdict( arity = 0, call = lambda: '\n' ), '⁸': attrdict( arity = 0, call = lambda: [] ), '⁹': attrdict( arity = 0, call = lambda: 256 ), 'A': attrdict( arity = 1, ldepth = 0, call = abs ), 'Ȧ': attrdict( arity = 1, call = lambda z: int(iterable(z) > [] and all(flatten(z))) ), 'Ạ': attrdict( arity = 1, call = lambda z: int(all(iterable(z))) ), 'a': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: x and y ), 'ȧ': attrdict( arity = 2, call = lambda x, y: x and y ), 'ạ': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: abs(x - y) ), 'B': attrdict( arity = 1, ldepth = 0, call = lambda z: to_base(z, 2) ), 'Ḅ': attrdict( arity = 1, ldepth = 1, call = lambda z: from_base(z, 2) ), 'Ḃ': attrdict( arity = 1, ldepth = 0, call = lambda z: z % 2 ), 'b': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: to_base(x, y) ), 'ḅ': attrdict( arity = 2, ldepth = 1, rdepth = 0, call = lambda x, y: from_base(x, y) ), 'ḃ': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: to_base(x, y, bijective = True) ), 'C': attrdict( arity = 1, ldepth = 0, call = lambda z: 1 - z ), 'Ċ': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.ceil, lambda t: t.imag, identity), z) ), 'c': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = nCr ), 'ċ': attrdict( arity = 2, call = lambda x, y: iterable(x).count(y) ), 'ƈ': attrdict( arity = 0, call = lambda: sys.stdin.read(1) or [] ), 'D': attrdict( arity = 1, ldepth = 0, call = lambda z: to_base(z, 10) ), 'Ḍ': attrdict( arity = 1, ldepth = 1, call = lambda z: from_base(z, 10) ), 'Ḋ': attrdict( arity = 1, call = lambda z: iterable(z, make_range = True)[1:] ), 'd': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: list(divmod(x, y)) ), 'ḍ': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: int(y % x == 0 if x else y == 0) ), 'ḋ': attrdict( arity = 2, ldepth = 1, rdepth = 1, call = lambda x, y: dot_product(x, y, truncate = True) ), 'E': attrdict( arity = 1, call = equal ), 'Ẹ': attrdict( arity = 1, call = lambda z: int(any(iterable(z))) ), 'Ė': attrdict( arity = 1, call = lambda z: [[t + 1, u] for t, u in enumerate(iterable(z))] ), 'e': attrdict( arity = 2, call = lambda x, y: int(x in iterable(y)) ), 'ẹ': attrdict( arity = 2, call = lambda x, y: [t + 1 for t, u in enumerate(iterable(x, make_digits = True)) if u == y] ), 'F': attrdict( arity = 1, call = flatten ), 'Ḟ': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.floor, lambda t: t.real, identity), z) ), 'f': attrdict( arity = 2, call = filter_array ), 'ḟ': attrdict( arity = 2, call = lambda x, y: filter_array(x, y, False) ), 'G': attrdict( arity = 1, call = grid ), 'Ġ': attrdict( arity = 1, call = group ), 'g': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = math.gcd ), 'Ɠ': attrdict( arity = 0, call = lambda: python_eval(input()) ), 'ɠ': attrdict( arity = 0, call = lambda: jellify(input(), dirty = True) ), 'H': attrdict( arity = 1, ldepth = 0, call = lambda z: div(z, 2) ), 'Ḥ': attrdict( arity = 1, ldepth = 0, call = lambda z: z * 2 ), 'Ḣ': attrdict( arity = 1, call = lambda z: iterable(z).pop(0) if iterable(z) else 0 ), 'ḣ': attrdict( arity = 2, rdepth = 0, call = lambda x, y: iterable(x)[:y] ), 'I': attrdict( arity = 1, ldepth = 1, call = lambda z: [z[i] - z[i - 1] for i in range(1, len(z))] ), 'İ': attrdict( arity = 1, ldepth = 0, call = lambda z: div(1, z) ), 'Ị': attrdict( arity = 1, ldepth = 0, call = lambda z: int(abs(z) <= 1) ), 'J': attrdict( arity = 1, call = lambda z: list(range(1, len(iterable(z)) + 1)) ), 'i': attrdict( arity = 2, call = index_of ), 'ḥ': attrdict( arity = 2, call = jelly_hash ), 'ị': attrdict( arity = 2, ldepth = 0, call = at_index ), 'j': attrdict( arity = 2, call = join ), 'K': attrdict( arity = 1, call = lambda z: join(z, ' ') ), 'Ḳ': attrdict( arity = 1, call = lambda z: jellify(split_at(iterable(z), ' ')) ), 'k': attrdict( arity = 2, call = lambda x, y: partition_at(x, y, border = 2) ), 'L': attrdict( arity = 1, call = lambda z: len(iterable(z)) ), 'Ḷ': attrdict( arity = 1, ldepth = 0, call = lambda z: list(range(int(z))) ), 'l': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: overload((math.log, cmath.log), x, y) ), 'ḷ': attrdict( arity = 2, call = lambda x, y: x ), 'M': attrdict( arity = 1, call = maximal_indices ), 'Ṃ': attrdict( arity = 1, call = lambda z: min(iterable(z)) if iterable(z) else 0 ), 'Ṁ': attrdict( arity = 1, call = lambda z: max(iterable(z)) if iterable(z) else 0 ), 'm': attrdict( arity = 2, rdepth = 0, call = lambda x, y: iterable(x)[::y] if y else iterable(x) + iterable(x)[::-1] ), 'ṁ': attrdict( arity = 2, call = lambda x, y: mold(iterable(x, make_copy = True), iterable(y, make_copy = True, make_range = True)) ), 'ṃ': attrdict( arity = 2, ldepth = 0, call = base_decompression ), 'N': attrdict( arity = 1, ldepth = 0, call = lambda z: -z ), 'Ṅ': attrdict( arity = 1, call = lambda z: output(z, end = '\n') ), 'Ṇ': attrdict( arity = 1, call = lambda z: int(not(z)) ), 'n': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: int(x != y) ), 'O': attrdict( arity = 1, ldepth = 0, call = lambda z: ord(z) if type(z) == str else z ), 'Ọ': attrdict( arity = 1, ldepth = 0, call = lambda z: chr(int(z)) if type(z) != str else z ), 'Ȯ': attrdict( arity = 1, call = output ), 'o': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: x or y ), 'ọ': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = order ), 'ȯ': attrdict( arity = 2, call = lambda x, y: x or y ), 'P': attrdict( arity = 1, call = lambda z: functools.reduce(lambda x, y: dyadic_link(atoms['×'], (x, y)), z, 1) if type(z) == list else z ), 'Ṗ': attrdict( arity = 1, call = lambda z: iterable(z, make_range = True)[:-1] ), 'p': attrdict( arity = 2, call = lambda x, y: jellify(itertools.product(iterable(x, make_range = True), iterable(y, make_range = True))) ), 'ṗ': attrdict( arity = 2, rdepth = 0, call = lambda x, y: jellify(itertools.product(*([iterable(x, make_range = True)] * y))) ), 'Q': attrdict( arity = 1, call = unique ), 'R': attrdict( arity = 1, ldepth = 0, call = lambda z: list(range(1, int(z) + 1)) ), 'Ṛ': attrdict( arity = 1, call = lambda z: iterable(z, make_digits = True)[::-1] ), 'Ṙ': attrdict( arity = 1, call = lambda z: output(z, transform = jelly_uneval) ), 'r': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: list(range(int(x), int(y) + 1) or range(int(x), int(y) - 1, -1)) ), 'ṙ': attrdict( arity = 2, rdepth = 0, call = rotate_left ), 'ṛ': attrdict( arity = 2, call = lambda x, y: y ), 'S': attrdict( arity = 1, call = lambda z: functools.reduce(lambda x, y: dyadic_link(atoms['+'], (x, y)), z, 0) if type(z) == list else z ), 'Ṡ': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((lambda t: (t > 0) - (t < 0), lambda t: t.conjugate()), z) ), 'Ṣ': attrdict( arity = 1, call = lambda z: sorted(iterable(z, make_digits = True)) ), 's': attrdict( arity = 2, rdepth = 0, call = lambda x, y: split_fixed(iterable(x, make_range = True), y) ), 'ṡ': attrdict( arity = 2, rdepth = 0, call = lambda x, y: split_rolling(iterable(x, make_range = True), y) ), 'ṣ': attrdict( arity = 2, call = lambda x, y: jellify(split_at(iterable(x, make_digits = True), y)) ), 'T': attrdict( arity = 1, call = lambda z: [u + 1 for u, v in enumerate(z) if v] ), 'Ṭ': attrdict( arity = 1, ldepth = 1, call = lambda z: [int(t + 1 in iterable(z)) for t in range(max(iterable(z) or [0]))] ), 'Ṫ': attrdict( arity = 1, call = lambda z: iterable(z).pop() if iterable(z) else 0 ), 't': attrdict( arity = 2, call = lambda x, y: trim(x, iterable(y), left = True, right = True) ), 'ṫ': attrdict( arity = 2, rdepth = 0, call = lambda x, y: iterable(x)[y - 1 :] ), 'ṭ': attrdict( arity = 2, call = lambda x, y: iterable(y) + [x] ), 'U': attrdict( arity = 1, ldepth = 1, call = lambda z: z[::-1] ), 'Ụ': attrdict( arity = 1, call = lambda z: sorted(range(1, len(iterable(z)) + 1), key = lambda t: iterable(z)[t - 1]) ), 'V': attrdict( arity = 1, ldepth = 1, call = lambda z: jelly_eval(''.join(map(str, z)), []) ), 'Ṿ': attrdict( arity = 1, call = lambda z: jellify(jelly_uneval(z)) ), 'v': attrdict( arity = 2, ldepth = 1, call = lambda x, y: jelly_eval(''.join(map(str, x)), [y]) ), 'W': attrdict( arity = 1, call = lambda z: [z] ), 'Ẇ': attrdict( arity = 1, call = windowed_sublists ), 'Ẉ': attrdict( arity = 1, call = lambda z: [len(iterable(t, make_digits = True)) for t in iterable(z, make_range = True)] ), 'w': attrdict( arity = 2, call = windowed_index_of ), 'ẇ': attrdict( arity = 2, call = windowed_exists ), 'X': attrdict( arity = 1, call = random_int ), 'Ẋ': attrdict( arity = 1, call = shuffle ), 'x': attrdict( arity = 2, ldepth = 1, call = lambda x, y: rld(zip(x, y if depth(y) else [y] * len(x))) ), 'ẋ': attrdict( arity = 2, rdepth = 0, call = lambda x, y: iterable(x) * int(y) ), 'Y': attrdict( arity = 1, call = lambda z: join(z, '\n') ), 'Ỵ': attrdict( arity = 1, call = lambda z: jellify(split_at(iterable(z), '\n')) ), 'Ẏ': attrdict( arity = 1, call = lambda z: sum(map(iterable, iterable(z)), []) ), 'y': attrdict( arity = 2, call = translate ), 'Z': attrdict( arity = 1, call = zip_ragged ), 'Ż': attrdict( arity = 1, call = lambda z: [0] + iterable(z, make_range = True) ), 'z': attrdict( arity = 2, call = lambda x, y: jellify(itertools.zip_longest(*map(iterable, x), fillvalue = y)) ), 'ż': attrdict( arity = 2, call = lambda x, y: zip_ragged([x, y]) ), '§': attrdict( arity = 1, ldepth = 1, call = sum ), 'Ä': attrdict( arity = 1, ldepth = 1, call = lambda z: list(itertools.accumulate(z)) ), '!': attrdict( arity = 1, ldepth = 0, call = Pi ), '<': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: int(x < y) ), '=': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: int(x == y) ), '>': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: int(x > y) ), ':': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: div(x, y, floor = True) ), ',': attrdict( arity = 2, call = lambda x, y: [x, y] ), ';': attrdict( arity = 2, call = lambda x, y: iterable(x) + iterable(y) ), '+': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = operator.add ), '_': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = operator.sub ), '×': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = operator.mul ), '÷': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = div ), '%': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = modulus ), '*': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = operator.pow ), '&': attrdict( arity = 2, ldepth = 0, rdepth = 0, conv = conv_dyadic_integer, call = operator.and_ ), '^': attrdict( arity = 2, ldepth = 0, rdepth = 0, conv = conv_dyadic_integer, call = operator.xor ), '|': attrdict( arity = 2, ldepth = 0, rdepth = 0, conv = conv_dyadic_integer, call = operator.or_ ), '~': attrdict( arity = 1, ldepth = 0, conv = conv_monadic_integer, call = lambda z: ~z ), '²': attrdict( arity = 1, ldepth = 0, call = lambda z: z ** 2 ), '½': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.sqrt, cmath.sqrt), z) ), '°': attrdict( arity = 1, ldepth = 0, call = math.radians ), '¬': attrdict( arity = 1, ldepth = 0, call = lambda z: int(not z) ), '‘': attrdict( arity = 1, ldepth = 0, call = lambda z: z + 1 ), '’': attrdict( arity = 1, ldepth = 0, call = lambda z: z - 1 ), '«': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = min ), '»': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = max ), '⁼': attrdict( arity = 2, call = lambda x, y: int(x == y) ), '⁻': attrdict( arity = 2, call = lambda x, y: int(x != y) ), '®': attrdict( arity = 0, call = lambda: 0 ), '¹': attrdict( arity = 1, call = identity ), 'ÆA': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.acos, cmath.acos), z) ), 'ÆẠ': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.cos, cmath.cos), z) ), 'ÆC': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.generate.primepi(z) ), 'ÆĊ': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.functions.combinatorial.numbers.catalan(z)) ), 'Æc': attrdict( arity = 1, ldepth = 0, call = carmichael ), 'ÆD': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.factor_.divisors(z) ), 'ÆḌ': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.factor_.divisors(z)[:-1] ), 'Æd': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.ntheory.factor_.divisor_count(z)) ), 'Æḍ': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.ntheory.factor_.divisor_count(z) - 1) ), 'ÆḊ': attrdict( arity = 1, ldepth = 2, call = determinant ), 'ÆE': attrdict( arity = 1, ldepth = 0, call = to_exponents ), 'ÆẸ': attrdict( arity = 1, ldepth = 1, call = from_exponents ), 'ÆF': attrdict( arity = 1, ldepth = 0, call = lambda z: [[x, y] for x, y in sorted(sympy.ntheory.factor_.factorint(z).items())] ), 'Æe': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.exp, cmath.exp), z) ), 'Æf': attrdict( arity = 1, ldepth = 0, call = lambda z: rld(sorted(sympy.ntheory.factor_.factorint(z).items())) ), 'ÆḞ': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.functions.combinatorial.numbers.fibonacci(z)) ), 'Æi': attrdict( arity = 1, ldepth = 0, call = lambda z: [z.real, z.imag] ), 'Æị': attrdict( arity = 1, ldepth = 1, call = lambda z: complex(*z[:2]) ), 'ÆĿ': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.functions.combinatorial.numbers.lucas(z)) ), 'Æl': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.log, cmath.log), z) ), 'Æm': attrdict( arity = 1, ldepth = 1, call = lambda z: div(sum(z), len(z)) ), 'Æṁ': attrdict( arity = 1, ldepth = 1, call = median ), 'Æṃ': attrdict( arity = 1, ldepth = 1, call = mode ), 'ÆN': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.generate.prime(z) ), 'Æn': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.generate.nextprime(z) ), 'ÆP': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.primetest.isprime(z)) ), 'Æp': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.generate.prevprime(z) ), 'ÆR': attrdict( arity = 1, ldepth = 0, call = lambda z: list(sympy.ntheory.generate.primerange(2, z + 1)) ), 'Ær': attrdict( arity = 1, ldepth = 1, call = lambda z: jellify(from_base(z[::-1], sympy.poly('x')).all_roots()) ), 'Æṛ': attrdict( arity = 1, ldepth = 1, call = lambda z: jellify(sympy.prod(map(sympy.poly('x').__sub__, z)).all_coeffs()[::-1]) ), 'ÆT': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.tan, cmath.tan), z) ), 'ÆṬ': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.atan, cmath.atan), z) ), 'ÆṪ': attrdict( arity = 1, ldepth = 0, call = lambda z: sympy.ntheory.factor_.totient(z) if z > 0 else 0 ), 'Æṭ': attrdict( arity = 1, ldepth = 2, call = lambda z: sum(sum(r[i : i+1]) for i, r in enumerate(z)) ), 'ÆS': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.sin, cmath.sin), z) ), 'ÆṢ': attrdict( arity = 1, ldepth = 0, call = lambda z: overload((math.asin, cmath.asin), z) ), 'Æs': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.ntheory.factor_.divisor_sigma(z)) ), 'Æṣ': attrdict( arity = 1, ldepth = 0, call = lambda z: int(sympy.ntheory.factor_.divisor_sigma(z) - z) ), 'Æv': attrdict( arity = 1, ldepth = 0, call = lambda z: len(sympy.ntheory.factor_.factorint(z)) ), 'Ʋ': attrdict( arity = 1, ldepth = 0, call = lambda z: int(isqrt(z) ** 2 == z) ), 'ƽ': attrdict( arity = 1, ldepth = 0, call = isqrt ), 'Æ°': attrdict( arity = 1, ldepth = 0, call = math.degrees ), 'Æ!': attrdict( arity = 1, ldepth = 0, call = to_factorial_base ), 'Æ¡': attrdict( arity = 1, ldepth = 1, call = from_factorial_base ), 'Æ?': attrdict( arity = 1, ldepth = 0, call = to_primorial_base ), 'Æ¿': attrdict( arity = 1, ldepth = 1, call = from_primorial_base ), 'Œ!': attrdict( arity = 1, call = lambda z: jellify(itertools.permutations(iterable(z, make_range = True))) ), 'Œ?': attrdict( arity = 1, ldepth = 0, call = pemutation_at_index ), 'Œ¿': attrdict( arity = 1, call = permutation_index ), 'ŒB': attrdict( arity = 1, ldepth = 1, call = lambda z: bounce(z) ), 'ŒḄ': attrdict( arity = 1, call = lambda z: bounce(iterable(z, make_range = True)) ), 'ŒḂ': attrdict( arity = 1, call = is_palindrome ), 'Œb': attrdict( arity = 1, call = lambda z: partitions(z) if z else [[]] ), 'Œc': attrdict( arity = 1, rdepth = 0, call = lambda z: jellify(itertools.combinations(iterable(z, make_range = True), 2)) ), 'Œċ': attrdict( arity = 1, rdepth = 0, call = lambda z: jellify(itertools.combinations_with_replacement(iterable(z, make_range = True), 2)) ), 'ŒD': attrdict( arity = 1, ldepth = 2, call = diagonals ), 'ŒḌ': attrdict( arity = 1, ldepth = 2, call = from_diagonals ), 'ŒḊ': attrdict( arity = 1, call = depth ), 'Œd': attrdict( arity = 1, ldepth = 2, call = lambda z: diagonals([r[::-1] for r in z]) ), 'Œḍ': attrdict( arity = 1, ldepth = 2, call = lambda z: [r[::-1] for r in from_diagonals(z)] ), 'ŒĖ': attrdict( arity = 1, call = lambda z: list(enumerate_md(z)) ), 'Œe': attrdict( arity = 1, call = lambda z: [t for t in iterable(z, make_range = True)[1::2]] ), 'ŒG': attrdict( arity = 1, ldepth = 1, call = get_request ), 'ŒĠ': attrdict( arity = 1, call = group_md ), 'Œg': attrdict( arity = 1, ldepth = 1, call = group_equal ), 'ŒH': attrdict( arity = 1, call = lambda z: split_evenly(iterable(z, make_range = True), 2) ), 'œị': attrdict( arity = 2, ldepth = 1, call = at_index_ndim ), 'ŒJ': attrdict( arity = 1, call = indices_md ), 'Œl': attrdict( arity = 1, ldepth = 1, call = lambda z: to_case(z, lower = True) ), 'ŒM': attrdict( arity = 1, call = maximal_indices_md ), 'Œo': attrdict( arity = 1, call = lambda z: [t for t in iterable(z, make_range = True)[::2]] ), 'ŒP': attrdict( arity = 1, call = powerset ), 'ŒṖ': attrdict( arity = 1, call = partitions ), 'Œṗ': attrdict( arity = 1, ldepth = 0, call = lambda z: sorted(integer_partitions(z), key = len, reverse = True) ), 'Œp': attrdict( arity = 1, call = lambda z: jellify(itertools.product(*[iterable(t, make_range = True) for t in z])) ), 'ŒQ': attrdict( arity = 1, call = distinct_sieve ), 'ŒR': attrdict( arity = 1, ldepth = 0, call = lambda z: list(range(-abs(int(z)), abs(int(z)) + 1)) ), 'ŒṘ': attrdict( arity = 1, call = lambda z: jellify(repr(z)) ), 'Œr': attrdict( arity = 1, ldepth = 1, call = rle ), 'Œṙ': attrdict( arity = 1, ldepth = 2, call = rld ), 'Œs': attrdict( arity = 1, ldepth = 1, call = lambda z: to_case(z, swap = True) ), 'ŒT': attrdict( arity = 1, call = time_format ), 'ŒṬ': attrdict( arity = 1, ldepth = 2, call = untruth_md ), 'ŒṪ': attrdict( arity = 1, call = lambda z: [t for t, u in enumerate_md(iterable(z)) if u] ), 'Œt': attrdict( arity = 1, ldepth = 1, call = lambda z: to_case(z, title = True) ), 'ŒV': attrdict( arity = 1, ldepth = 1, call = lambda z: python_eval(''.join(map(str, z))) ), 'ŒỤ': attrdict( arity = 1, call = lambda z: sorted(indices_md(iterable(z)), key = lambda t: at_index_ndim(t, iterable(z))) ), 'Œu': attrdict( arity = 1, ldepth = 1, call = lambda z: to_case(z, upper = True) ), 'Œœ': attrdict( arity = 1, call = odd_even ), 'Œɠ': attrdict( arity = 1, call = group_lengths ), 'œ?': attrdict( arity = 2, ldepth = 0, call = pemutation_at_index ), 'œ¿': attrdict( arity = 2, call = lambda x, y: permutation_index([y.index(value) for value in x]) ), 'æ.': attrdict( arity = 2, ldepth = 1, rdepth = 1, call = dot_product ), 'æ%': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = symmetric_mod ), 'æ*': attrdict( arity = 2, ldepth = 2, rdepth = 0, call = lambda x, y: matrix_to_list((sympy.Matrix(x) ** y)) ), 'æ×': attrdict( arity = 2, ldepth = 2, rdepth = 2, call = lambda x, y: matrix_to_list((sympy.Matrix(x) * sympy.Matrix(y))) ), 'æA': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = math.atan2 ), 'æR': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = primerange ), 'æC': attrdict( arity = 2, ldepth = 1, rdepth = 0, call = convolve_power ), 'æc': attrdict( arity = 2, ldepth = 1, rdepth = 1, call = convolve ), 'æċ': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: from_base([1] + [0] * len(to_base(x, y)), y) ), 'æḟ': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: from_base([1] + [0] * (len(to_base(x, y)) - 1), y) ), 'æi': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = modinv ), 'æị': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = complex ), 'æl': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lcm ), 'ær': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = round ), 'æp': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = lambda x, y: float('%%.%dg'%y%x) ), 'æ«': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = shift_left ), 'æ»': attrdict( arity = 2, ldepth = 0, rdepth = 0, call = shift_right ), 'œ!': attrdict( arity = 2, rdepth = 0, call = lambda x, y: jellify(itertools.permutations(iterable(x, make_range = True), y)) ), 'œc': attrdict( arity = 2, rdepth = 0, call = lambda x, y: jellify(itertools.combinations(iterable(x, make_range = True), y)) ), 'œċ': attrdict( arity = 2, rdepth = 0, call = lambda x, y: jellify(itertools.combinations_with_replacement(iterable(x, make_range = True), y)) ), 'œẹ': attrdict( arity = 2, call = lambda x, y: [t for t, u in enumerate_md(iterable(x)) if u == y] ), 'œi': attrdict( arity = 2, call = index_of_md ), 'œl': attrdict( arity = 2, call = lambda x, y: trim(x, iterable(y), left = True) ), 'œP': attrdict( arity = 2, call = lambda x, y: partition_at([int(t + 1 in iterable(x)) for t in range(max(iterable(x) or [0]))], y, border = 0) ), 'œṖ': attrdict( arity = 2, call = lambda x, y: partition_at([int(t + 1 in iterable(x)) for t in range(max(iterable(x) or [0]))], y) ), 'œp': attrdict( arity = 2, call = lambda x, y: partition_at(x, y, border = 0) ), 'œṗ': attrdict( arity = 2, call = partition_at ), 'œr': attrdict( arity = 2, call = lambda x, y: trim(x, iterable(y), right = True) ), 'œS': attrdict( arity = 2, call = lambda x, y: time.sleep(overload((float, bool), y)) or x ), 'œs': attrdict( arity = 2, rdepth = 0, call = lambda x, y: split_evenly(iterable(x, make_range = True), y) ), 'œṡ': attrdict( arity = 2, rdepth = 0, call = split_once ), 'œṣ': attrdict( arity = 2, call = lambda x, y: jellify(split_around(iterable(x, make_digits = True), iterable(y))) ), 'œ&': attrdict( arity = 2, call = multiset_intersect ), 'œ-': attrdict( arity = 2, call = multiset_difference ), 'œ^': attrdict( arity = 2, call = multiset_symdif ), 'œ|': attrdict( arity = 2, call = multiset_union ), 'Ø0': attrdict( arity = 0, call = lambda: [0, 0] ), 'Ø1': attrdict( arity = 0, call = lambda: [1, 1] ), 'Ø2': attrdict( arity = 0, call = lambda: [2, 2] ), 'Ø.': attrdict( arity = 0, call = lambda: [0, 1] ), 'ؽ': attrdict( arity = 0, call = lambda: [1, 2] ), 'Ø+': attrdict( arity = 0, call = lambda: [1, -1] ), 'Ø-': attrdict( arity = 0, call = lambda: [-1, 1] ), 'Ø(': attrdict( arity = 0, call = lambda: list('()') ), 'Ø<': attrdict( arity = 0, call = lambda: list('<>') ), 'Ø[': attrdict( arity = 0, call = lambda: list('[]') ), 'Ø{': attrdict( arity = 0, call = lambda: list('{}') ), 'Ø^': attrdict( arity = 0, call = lambda: list('/\\') ), 'Ø⁵': attrdict( arity = 0, call = lambda: 250 ), 'Ø⁷': attrdict( arity = 0, call = lambda: 128 ), 'Ø°': attrdict( arity = 0, call = lambda: 360 ), 'Ø%': attrdict( arity = 0, call = lambda: 2 ** 32 ), 'ØA': attrdict( arity = 0, call = lambda: list(str_upper) ), 'ØẠ': attrdict( arity = 0, call = lambda: list(str_upper + str_lower) ), 'ØB': attrdict( arity = 0, call = lambda: list(str_digit + str_upper + str_lower) ), 'ØḄ': attrdict( arity = 0, call = lambda: list('bcdfghjklmnpqrstvwxyz') ), 'ØḂ': attrdict( arity = 0, call = lambda: list('BCDFGHJKLMNPQRSTVWXYZ') ), 'ØC': attrdict( arity = 0, call = lambda: list('BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz') ), 'ØD': attrdict( arity = 0, call = lambda: list(str_digit) ), 'ØH': attrdict( arity = 0, call = lambda: list(str_digit + 'ABCDEF') ), 'ØJ': attrdict( arity = 0, call = lambda: list(code_page) ), 'ØP': attrdict( arity = 0, call = lambda: math.pi ), 'ØṖ': attrdict( arity = 0, call = lambda: list(map(chr, range(32, 127))) ), 'ØQ': attrdict( arity = 0, call = lambda: [list('QWERTYUIOP'), list('ASDFGHJKL'), list('ZXCVBNM')] ), 'ØV': attrdict( arity = 0, call = lambda: list('ṘV') ), 'ØW': attrdict( arity = 0, call = lambda: list(str_upper + str_lower + str_digit + '_') ), 'ØY': attrdict( arity = 0, call = lambda: list('BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz') ), 'ØỴ': attrdict( arity = 0, call = lambda: list('bcdfghjklmnpqrstvwxz') ), 'ØẎ': attrdict( arity = 0, call = lambda: list('BCDFGHJKLMNPQRSTVWXZ') ), 'Øa': attrdict( arity = 0, call = lambda: list(str_lower) ), 'Øb': attrdict( arity = 0, call = lambda: list(str_upper + str_lower + str_digit + '+/') ), 'Øc': attrdict( arity = 0, call = lambda: list('AEIOUaeiou') ), 'Øe': attrdict( arity = 0, call = lambda: math.e ), 'Øẹ': attrdict( arity = 0, call = lambda: list('aeiou') ), 'Øė': attrdict( arity = 0, call = lambda: list('AEIOU') ), 'Øh': attrdict( arity = 0, call = lambda: list(str_digit + 'abcdef') ), 'Øp': attrdict( arity = 0, call = lambda: (1 + math.sqrt(5)) / 2 ), 'Øq': attrdict( arity = 0, call = lambda: [list('qwertyuiop'), list('asdfghjkl'), list('zxcvbnm')] ), 'Øv': attrdict( arity = 0, call = lambda: list('Ṙv') ), 'Øy': attrdict( arity = 0, call = lambda: list('AEIOUYaeiouy') ), 'Øỵ': attrdict( arity = 0, call = lambda: list('aeiouy') ), 'Øẏ': attrdict( arity = 0, call = lambda: list('AEIOUY') ) } quicks = { '©': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x = None, y = None: copy_to(atoms['®'], variadic_link(links[0], (x, y))) )] ), 'ß': attrdict( condition = lambda links: True, quicklink = lambda links, outmost_links, index: [create_chain(outmost_links[index])] ), '¢': attrdict( condition = lambda links: True, quicklink = lambda links, outmost_links, index: [create_chain(outmost_links[index - 1], 0)] ), 'Ç': attrdict( condition = lambda links: True, quicklink = lambda links, outmost_links, index: [create_chain(outmost_links[index - 1], 1)] ), 'ç': attrdict( condition = lambda links: True, quicklink = lambda links, outmost_links, index: [create_chain(outmost_links[index - 1], 2)] ), 'Ñ': attrdict( condition = lambda links: True, quicklink = lambda links, outmost_links, index: [create_chain(outmost_links[(index + 1) % len(outmost_links)], 1)] ), 'ñ': attrdict( condition = lambda links: True, quicklink = lambda links, outmost_links, index: [create_chain(outmost_links[(index + 1) % len(outmost_links)], 2)] ), '¦': attrdict( condition = lambda links: len(links) == 2, quicklink = lambda links, outmost_links, index: [attrdict( arity = max_arity(links + [atoms['¹']]), call = lambda x, y = None: sparse(links[0], (x, y), links[1]) )] ), '¡': attrdict( condition = lambda links: len(links) == 2, quicklink = lambda links, outmost_links, index: ([links.pop(0)] if len(links) == 2 and links[0].arity == 0 else []) + [attrdict( arity = max_arity(links), call = lambda x = None, y = None: ntimes(links, (x, y)) )] ), '¿': attrdict( condition = lambda links: len(links) == 2, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(link.arity for link in links), call = lambda x = None, y = None: while_loop(links[0], links[1], (x, y)) )] ), '/': attrdict( condition = lambda links: links and links[0].arity, quicklink = reduce ), '\\': attrdict( condition = lambda links: links and links[0].arity, quicklink = reduce_cumulative ), 'Ƒ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(1, links[0].arity), call = lambda x, y = None: int(x == variadic_link(links[0], (x, y))) )] ), 'ƒ': attrdict( condition = lambda links: links and links[0].arity, quicklink = foldl ), 'Ɲ': attrdict( condition = lambda links: links and not leading_nilad(links), quicklink = lambda links, outmost_links, index: [attrdict( arity = 1, call = lambda z: neighbors(links, z) )] ), 'Ƥ': attrdict( condition = lambda links: links and links[0].arity, quicklink = prefix ), 'ÐƤ': attrdict( condition = lambda links: links and links[0].arity, quicklink = suffix ), 'ƙ': attrdict( condition = lambda links: links and links[0].arity, quicklink = lambda links, outmost_links, index: [attrdict( arity = 2, call = lambda x, y: [monadic_link(links[0], g) for g in split_key(iterable(x, make_digits = True), iterable(y, make_digits = True))] )] ), 'ɼ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(0, links[0].arity - 1), call = lambda z = None: copy_to(atoms['®'], variadic_link(links[0], (niladic_link(atoms['®']), z))) )] ), 'Ƭ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x = None, y = None: loop_until_loop(links[0], (x, y), return_all = True, vary_rarg = False) )] ), 'ƭ': attrdict( condition = lambda links: links and ( (links[-1].arity == 0 and len(links) - 1 == links[-1].call()) or (links[-1].arity and len(links) == 2)), quicklink = tie ), '¤': quickchain(0, 2), '$': quickchain(1, 2), 'Ɗ': quickchain(1, 3), 'Ʋ': quickchain(1, 4), '¥': quickchain(2, 2), 'ɗ': quickchain(2, 3), 'ʋ': quickchain(2, 4), '#': attrdict( condition = lambda links: len(links) == 2, quicklink = lambda links, outmost_links, index: ([links.pop(0)] if len(links) == 2 and links[0].arity == 0 else []) + [attrdict( arity = max_arity(links), call = lambda x = None, y = None: nfind(links, (x, y)) )] ), '?': attrdict( condition = lambda links: len(links) == 3, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(link.arity for link in links), call = lambda x = None, y = None: variadic_link(links[0], (x, y)) if variadic_link(links[2], (x, y)) else variadic_link(links[1], (x, y)) )] ), '`': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = 1, call = lambda z: dyadic_link(links[0], (z, z)) )] ), '⁺': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: links * 2 ), 'С': attrdict( condition = lambda links: len(links) == 2, quicklink = lambda links, outmost_links, index: ([links.pop(0)] if len(links) == 2 and links[0].arity == 0 else []) + [attrdict( arity = max(link.arity for link in links), call = lambda x = None, y = None: ntimes(links, (x, y), cumulative = True) )] ), 'п': attrdict( condition = lambda links: len(links) == 2, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(link.arity for link in links), call = lambda x = None, y = None: while_loop(links[0], links[1], (x, y), cumulative = True) )] ), 'Ðe': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(1, links[0].arity), call = lambda x, y = None: sparse(links[0], (x, y), range(2, len(x) + 2, 2), indices_literal = True) )] ), 'Ðf': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x, y = None: list(filter(lambda t: variadic_link(links[0], (t, y)), iterable(x, make_range = True))) )] ), 'Ðḟ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x, y = None: list(itertools.filterfalse(lambda t: variadic_link(links[0], (t, y)), iterable(x, make_range = True))) )] ), 'ÐL': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x = None, y = None: loop_until_loop(links[0], (x, y)) )] ), 'ÐĿ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x = None, y = None: loop_until_loop(links[0], (x, y), return_all = True) )] ), 'ÐḶ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x = None, y = None: loop_until_loop(links[0], (x, y), return_loop = True) )] ), 'ÐṂ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x, y = None: extremes(min, links[0], (x, y)) )] ), 'ÐṀ': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = links[0].arity, call = lambda x, y = None: extremes(max, links[0], (x, y)) )] ), 'Ðo': attrdict( condition = lambda links: links, quicklink = lambda links, outmost_links, index: [attrdict( arity = max(1, links[0].arity), call = lambda x, y = None: sparse(links[0], (x, y), range(1, len(x) + 1, 2), indices_literal = True) )] ), } hypers = { '"': lambda link, none = None: attrdict( arity = 2, call = lambda x, y: [dyadic_link(link, (u, v)) for u, v in zip(iterable(x), iterable(y))] + iterable(x)[len(iterable(y)) :] + iterable(y)[len(iterable(x)) :] ), "'": lambda link, none = None: attrdict( arity = link.arity, call = lambda x = None, y = None: variadic_link(link, (x, y), flat = True, lflat = True, rflat = True) ), '@': lambda link, none = None: attrdict( arity = 2, call = lambda x, y: dyadic_link(link, (y, x)) ), '{': lambda link, none = None: attrdict( arity = 2, call = lambda x, y: monadic_link(link, x) ), '}': lambda link, none = None: attrdict( arity = 2, call = lambda x, y: monadic_link(link, y) ), '€': lambda link, none = None: attrdict( arity = max(1, link.arity), call = lambda x, y = None: [variadic_link(link, (t, y)) for t in iterable(x, make_range = True)] ), 'Þ': lambda link, none = None: attrdict( arity = link.arity, call = lambda x, y = None: sorted(iterable(x, make_range = True), key=lambda t: variadic_link(link, (t, y))) ), 'þ': lambda link, none = None: attrdict( arity = 2, call = lambda x, y: [[dyadic_link(link, (u, v)) for u in iterable(x, make_range = True)] for v in iterable(y, make_range = True)] ), 'Ѐ': lambda link, none = None: attrdict( arity = max(1, link.arity), call = lambda x, y = None: [variadic_link(link, (x, t)) for t in iterable(y, make_range = True)] ), '£': lambda index, links: attrdict( arity = index.arity, call = lambda x = None, y = None: niladic_chain(links[(variadic_link(index, (x, y)) - 1) % (len(links) - 1)]) ), 'Ŀ': lambda index, links: attrdict( arity = max(1, index.arity), call = lambda x, y = None: monadic_chain(links[(variadic_link(index, (x, y)) - 1) % (len(links) - 1)], x) ), 'ŀ': lambda index, links: attrdict( arity = 2, call = lambda x, y: dyadic_chain(links[(variadic_link(index, (x, y)) - 1) % (len(links) - 1)], (x, y)) ) } # Aliases quicks['Ƈ'] = quicks['Ðf'] hypers['Ɱ'] = hypers['Ѐ'] atoms ['Ẓ'] = atoms ['ÆP'] chain_separators = { 'ø': (0, '', True), 'µ': (1, '', True), ')': (1, '€', True), 'ð': (2, '', True), 'ɓ': (2, '', False) } default_chain_separation = (-1, '', True) str_arities = ''.join(chain_separators.keys()) str_strings = '“[^«»‘’”]*[«»‘’”]?' str_charlit = '”.' str_chrpair = '⁾..' str_intpair = '⁽..' str_realdec = '(?:0|-(?![1-9.])|-?\d*\.\d*|-?\d+)' str_realnum = str_realdec.join(['(?:', '?ȷ', '?|', ')']) str_complex = str_realnum.join(['(?:', '?ı', '?|', ')']) str_literal = '(?:%s)' % '|'.join([str_strings, str_charlit, str_chrpair, str_complex, str_intpair]) str_litlist = '\[*' + str_literal + '(?:(?:\]*,\[*)' + str_literal + ')*' + '\]*' str_nonlits = '|'.join(map(re.escape, list(atoms) + list(quicks) + list(hypers))) regex_chain = re.compile('(?:^(?:' + str_nonlits + '|' + str_litlist + '| )+|[' + str_arities + '])(?:' + str_nonlits + '|' + str_litlist + '| )*') regex_liter = re.compile(str_literal) regex_token = re.compile(str_nonlits + '|' + str_litlist) regex_flink = re.compile('(?=.)(?:[' + str_arities + ']|' + str_nonlits + '|' + str_litlist + '| )*¶?')