├── README.md ├── __pycache__ ├── metas.cpython-35.pyc ├── operators.cpython-35.pyc ├── primes.cpython-35.pyc └── utilities.cpython-35.pyc ├── codepage.md ├── gaia.py ├── metas.py ├── operators.py ├── primes.py └── utilities.py /README.md: -------------------------------------------------------------------------------- 1 | # Gaia 2 | 3 | A work-in-progress golfing language inspired by [CJam](https://sourceforge.net/projects/cjam/) and [Jelly](https://github.com/DennisMitchell/jelly), and to a lesser extent, [Ohm](https://github.com/nickbclifford/Ohm) and and [SOGL](https://github.com/dzaima/SOGL). 4 | 5 | ## Running Gaia 6 | 7 | To run Gaia, simply download all files, then run `python gaia.py `. Additionally, you can run it with the `-e` flag, which runs a program encoded using Gaia's codepage. 8 | 9 | Additionally, you may [Try it online!](https://tio.run/#gaia), courtesy of [DennisMitchell](https://github.com/DennisMitchell). 10 | 11 | ## Documentation 12 | 13 | Some documentation is available on the [wiki](https://github.com/splcurran/Gaia/wiki). 14 | 15 | ## Bugs 16 | 17 | As Gaia is still in development, there may be a lot of bugs that I don't catch. If you find anything you think might be a bug, please report it. 18 | -------------------------------------------------------------------------------- /__pycache__/metas.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Glan9/Gaia/8c5124651d5ff6a1335501b3c54f8718b4b80fc7/__pycache__/metas.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/operators.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Glan9/Gaia/8c5124651d5ff6a1335501b3c54f8718b4b80fc7/__pycache__/operators.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/primes.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Glan9/Gaia/8c5124651d5ff6a1335501b3c54f8718b4b80fc7/__pycache__/primes.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/utilities.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Glan9/Gaia/8c5124651d5ff6a1335501b3c54f8718b4b80fc7/__pycache__/utilities.cpython-35.pyc -------------------------------------------------------------------------------- /codepage.md: -------------------------------------------------------------------------------- 1 | # Codepage 2 | 3 | | |\_0|\_1|\_2|\_3|\_4|\_5|\_6|\_7|\_8|\_9|\_A|\_B|\_C|\_D|\_E|\_F 4 | |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|--- 5 | |**0\_**|`₀`|`₁`|`₂`|`₃`|`₄`|`₅`|`₆`|`₇`|`₈`|`₉`|`ₓ`|`₌`|`ₔ`|`∂`|`€`|`₵`| 6 | |**1\_**|`⟨`|`⟩`|`⟪`|`⟫`|`⇑`|`⇓`|`⇐`|`⇒`|`↑`|`↓`|`←`|`→`|`⇈`|`⇊`|`⇇`|`⇉`| 7 | |**2\_**| |`!`|`"`|`#`|`$`|`%`|`&`|`'`|`(`|`)`|`*`|`+`|`,`|`-`|`.`|`/`| 8 | |**3\_**|`0`|`1`|`2`|`3`|`4`|`5`|`6`|`7`|`8`|`9`|`:`|`;`|`<`|`=`|`>`|`?`| 9 | |**4\_**|`@`|`A`|`B`|`C`|`D`|`E`|`F`|`G`|`H`|`I`|`J`|`K`|`L`|`M`|`N`|`O`| 10 | |**5\_**|`P`|`Q`|`R`|`S`|`T`|`U`|`V`|`W`|`X`|`Y`|`Z`|`[`|`\`|`]`|`^`|`_`| 11 | |**6\_**|`|`a`|`b`|`c`|`d`|`e`|`f`|`g`|`h`|`i`|`j`|`k`|`l`|`m`|`n`|`o`| 12 | |**7\_**|`p`|`q`|`r`|`s`|`t`|`u`|`v`|`w`|`x`|`y`|`z`|`{`|`\|`|`}`|`~`|\n| 13 | |**8\_**|`«`|`»`|`…`|`┅`|`⌋`|`⌉`|`⊂`|`⊃`|`∧`|`∨`|`Σ`|`Π`|`‼`|`×`|`÷`|`⁻`| 14 | |**9\_**|`ø`|`Ø`|`¤`|`¶`|`§`||`₸`|`ℍ`|`Ȧ`|`Ċ`|`Ḋ`|`Ė`|`Ḟ`|`Ġ`|`Ḣ`|`Ṁ`| 15 | |**A\_**|`Ṅ`|`Ȯ`|`Ṗ`|`Ṙ`|`Ṡ`|`Ṫ`|`Ẇ`|`Ẋ`|`Ẏ`|`Ż`|`ȧ`|`ċ`|`ḋ`|`ė`|`ḟ`|`ġ`| 16 | |**B\_**|`ḣ`|`ṁ`|`ṅ`|`ȯ`|`ṗ`|`ṙ`|`ṡ`|`ṫ`|`ẇ`|`ẋ`|`ẏ`|`ż`|`Ạ`|`Ḅ`|`Ḍ`|`Ẹ`| 17 | |**C\_**|`Ḥ`|`Ḳ`|`Ḷ`|`Ṃ`|`Ṇ`|`Ọ`|`Ṛ`|`Ṣ`|`Ṭ`|`Ụ`|`Ṿ`|`Ẉ`|`Ỵ`|`Ẓ`|`ạ`|`ḅ`| 18 | |**D\_**|`ḍ`|`ẹ`|`ḥ`|`ḳ`|`ḷ`|`ṃ`|`ṇ`|`ọ`|`ṛ`|`ṣ`|`ṭ`|`ụ`|`ṿ`|`ẉ`|`ỵ`|`ẓ`| 19 | |**E\_**|`¿`|`¡`|`⁇`|`⁈`|`↻`|`↺`|`∞`|`¦`|`†`|`‡`|`∆`|`∇`|`⊢`|`⊣`|`‖`|| 20 | |**F\_**|`⌡`|`⌠`|`∫`|`ª`|`º`|`°`|||||`“`|`”`|`‘`|`’`|`„`|`‟`| 21 | 22 | -------------------------------------------------------------------------------- /gaia.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | import re 5 | import math 6 | 7 | 8 | import operators 9 | import metas 10 | import utilities 11 | 12 | sourcecode = '' 13 | stack = [] 14 | 15 | numberRegex = "^-?(\d+(\.\d*)?|\.\d*)|^-" 16 | 17 | def interpret(code): 18 | arrayMarkers = [] # Used to mark the positions of arrays being opened, with '[' 19 | functions = [] 20 | callStack = [] # Function call stack 21 | 22 | def openArray(stack): 23 | arrayMarkers.append(len(stack)) 24 | 25 | def closeArray(stack): 26 | height = 0 # The stack height of the start of the array 27 | if len(arrayMarkers) > 0: 28 | height = arrayMarkers.pop() 29 | 30 | temp = [] 31 | while len(stack)>height: 32 | temp.insert(0, stack.pop()) 33 | stack.append(temp) 34 | 35 | 36 | # Parsing 37 | 38 | """ 39 | Parse a number written in subscript digits and return the number. 40 | """ 41 | def parseSubscript(num): 42 | result = 0 43 | for d in num: 44 | result *= 10 45 | result += "₀₁₂₃₄₅₆₇₈₉".find(d) 46 | return result 47 | 48 | """ 49 | Returns the lambda function for a meta combined with one or two operators. 50 | 51 | meta: The function of the meta 52 | arity: The arity of the meta (not number of operators) 53 | op1: First operator 54 | op2: Second operator (optional) 55 | 56 | """ 57 | def determineMetaCallStyle(meta, arity, op1, op2 = None): 58 | ops = list(filter(lambda o:o!=None, [op1, op2])) 59 | 60 | if arity == 0: 61 | return lambda stack: meta(stack, ops) 62 | elif arity == 1: 63 | return lambda stack, z, mode: meta(stack, ops, mode, z) 64 | elif arity == 2: 65 | return lambda stack, x, y, mode: meta(stack, ops, mode, x, y) 66 | 67 | 68 | def createBlockOperator(block, blockStr, arity): 69 | 70 | if arity == 0: 71 | return operators.Operator( "{⟨⟪"[arity]+blockStr+"}⟩⟫"[arity], arity, lambda stack: runFunction(stack, block)) 72 | elif arity == 1: 73 | return operators.Operator( "{⟨⟪"[arity]+blockStr+"}⟩⟫"[arity], arity, lambda stack, z, mode: [ stack.append(i) for i in runFunction([z], block) ]) 74 | elif arity == 2: 75 | return operators.Operator( "{⟨⟪"[arity]+blockStr+"}⟩⟫"[arity], arity, lambda stack, x, y, mode: [ stack.append(i) for i in runFunction([x, y], block) ]) 76 | 77 | 78 | """ 79 | parseString(string, terminator) 80 | 81 | string: The part of the text between the initial opening quote and the ending quote, including additional opening quotes 82 | terminator: The ending quote 83 | """ 84 | def parseString(string, terminator): 85 | strings = [] 86 | 87 | i = 0 88 | while i < len(string): 89 | if string[i] == '\\': 90 | if i < len(string)-1 and string[i+1] in '\\“”‘’„‟¶': 91 | string = string[:i]+string[i+1:] 92 | elif string[i] == '“': 93 | strings.append(string[:i]) 94 | string = string[i+1:] 95 | i = 0 96 | elif string[i] == '¶': 97 | string = string[:i]+"\n"+string[i+1:] 98 | i += 1 99 | strings.append(string) 100 | 101 | if terminator == '‘': 102 | # Base-250 number 103 | for i in range(len(strings)): 104 | digits = utilities.codepageEncode(strings[i]) 105 | strings[i] = sum((250**i)*digits[~i] for i in range(len(digits))) 106 | elif terminator == '’': 107 | # List of codepage indices 108 | strings = [list(utilities.codepageEncode(string)) for string in strings] 109 | elif terminator == '„': 110 | newStrings = [decompose(s) for s in strings] 111 | 112 | # Check if everything is the same arity 113 | arity = None 114 | for s in newStrings: 115 | if len(s) > 0: 116 | arity = s[0].arity if arity == None else arity # Only set it if it hasn't been set yet 117 | for op in s: 118 | if op.arity != arity: 119 | raise SyntaxError("all operators in a “...„ string must have the same arity") 120 | 121 | if len(newStrings) == 1: 122 | if arity == 0: 123 | return operators.Operator('“'+strings[0]+'„', 0, (lambda string: lambda stack: [stack.append(i) for i in runOperatorString(string)])(newStrings[0])) 124 | elif arity == 1: 125 | return operators.Operator('“'+strings[0]+'„', 1, (lambda string: lambda stack, z, mode: [stack.append(i) for i in runOperatorString(string, z)])(newStrings[0])) 126 | elif arity == 2: 127 | return operators.Operator('“'+strings[0]+'„', 2, (lambda string: lambda stack, x, y, mode: [stack.append(i) for i in runOperatorString(string, x, y)])(newStrings[0])) 128 | else: 129 | if arity == 0: 130 | return operators.Operator('“'+strings[0]+'„', 0, (lambda strings: lambda stack: stack.append([runOperatorString(s) for s in strings]) )(newStrings)) 131 | elif arity == 1: 132 | return operators.Operator('“'+strings[0]+'„', 1, (lambda strings: lambda stack, z, mode: stack.append([runOperatorString(s, z) for s in strings]) )(newStrings)) 133 | elif arity == 2: 134 | return operators.Operator('“'+strings[0]+'„', 2, (lambda strings: lambda stack, x, y, mode: stack.append([runOperatorString(s, x, y) for s in strings]) )(newStrings)) 135 | 136 | 137 | else: 138 | # Default to being a normal string 139 | terminator = '”' 140 | 141 | # Make it a list only if there's more than 1 142 | if len(strings) == 1: 143 | return operators.Operator('“'+string+'”', 0, ( lambda x: lambda stack: stack.append(x) )(strings[0]) ) 144 | else: 145 | return operators.Operator('“'+string+'”', 0, ( lambda x: lambda stack: stack.append(x) )(strings) ) 146 | 147 | 148 | 149 | """ 150 | Break a line (as a string) down into operators 151 | """ 152 | def decompose(line): 153 | func = [] 154 | 155 | if re.match("^((\\\\[“”‘’„‟]|[^“”‘’„‟])*)([”‘’„‟])", line): 156 | # Match an unopened string at the start of the line 157 | match = re.match("^((\\\\[“”‘’„‟]|[^“”‘’„‟])*)([”‘’„‟])", line) 158 | string = match.group(1) 159 | terminator = match.group(3) 160 | 161 | func.append(parseString(string, terminator)) 162 | 163 | line = re.sub("^((\\\\[“”‘’„‟]|[^“”‘’„‟])*)([”‘’„‟])", '', line) 164 | 165 | while len(line) > 0: 166 | 167 | if re.match("^“((\\\\[“”‘’„‟]|[^”‘’„‟])*)([”‘’„‟]|$)", line): 168 | # Match a normal or unfinished string 169 | match = re.match("^“((\\\\[“”‘’„‟]|[^”‘’„‟])*)([”‘’„‟]|$)", line) 170 | string = match.group(1) 171 | terminator = match.group(3) 172 | func.append(parseString(string, terminator)) 173 | 174 | line = re.sub("^“((\\\\[“”‘’„‟]|[^”‘’„‟])*)([”‘’„‟]|$)", '', line) 175 | elif re.match(numberRegex, line): 176 | # Match a number literal 177 | match = re.match(numberRegex, line).group(0) 178 | if match == '-': 179 | match = '-1'+match[1:] 180 | if match[-1] == '.': 181 | match += '5' 182 | num = float(match) 183 | func.append(operators.Operator(match, 0, ( lambda x: lambda stack: stack.append(utilities.formatNum(x)) )(num) )) 184 | line = re.sub(numberRegex, '', line) 185 | if re.match('^[₀₁₂₃₄₅₆₇₈₉]+', line): 186 | # Subscript numbers after number literals form another number literal 187 | # (so you can write two literals with no separator) 188 | num = re.match("^[₀₁₂₃₄₅₆₇₈₉]+", line).group(0) 189 | func.append(operators.Operator(num, 0, ( lambda x: lambda stack: stack.append(utilities.formatNum(x)) )(parseSubscript(num)) )) 190 | line = re.sub("^[₀₁₂₃₄₅₆₇₈₉]+", '', line) 191 | elif line[0] == "'": 192 | if len(line) < 2: 193 | raise SyntaxError("Unfinished character literal") 194 | func.append(operators.Operator( line[:2], 0, (lambda c: lambda stack: stack.append(c))(line[1]))) 195 | line = line[2:] 196 | elif re.match('^[₀₁₂₃₄₅₆₇₈₉]+', line): 197 | # Match a repetition meta 198 | num = re.match("^[₀₁₂₃₄₅₆₇₈₉]+", line).group(0) 199 | meta = [num, 1, 0, (lambda n: lambda stack, ops, mode=None, x=None, y=None: [ops[0].execute(stack) for i in range(n)])(parseSubscript(num))] 200 | func = func[:-1]+[ operators.Operator(func[-1].name+meta[0], 0, determineMetaCallStyle(meta[3], 0, func[-1])) ] 201 | line = re.sub("^[₀₁₂₃₄₅₆₇₈₉]+", '', line) 202 | elif line[0] in "{⟨⟪": 203 | # Match a block 204 | openBracket = "{⟨⟪"["{⟨⟪".find(line[0])] 205 | closeBracket = "}⟩⟫"["{⟨⟪".find(line[0])] 206 | arity = "{⟨⟪".find(line[0]) 207 | blockStr = '' 208 | depth = 1 209 | while len(line) > 0 and depth > 0: 210 | line = line[1:] 211 | if line[0] == openBracket: 212 | depth += 1 213 | elif line[0] == closeBracket: 214 | depth -= 1 215 | blockStr += line[0] 216 | blockStr = blockStr[:-1] 217 | block = decompose(blockStr) 218 | 219 | func.append(createBlockOperator(block, blockStr, arity)) 220 | elif line[0] in "⇑⇓⇐⇒↑↓←→⇈⇊⇇⇉": 221 | if line[0] == '⇑': 222 | # The +[1] on each is to make sure the list is not empty, and therefore will always evaluate the right side of the 'and'. This is hacky, but the entire thing is hacky... 223 | # Call function above on whole stack 224 | func.append(operators.Operator( '⇑', 0, lambda stack: callStack.append((callStack[-1]-1)%len(functions)) or runFunction(stack, functions[callStack[-1]])+[1] and callStack.pop() )) 225 | elif line[0] == '↑': 226 | # Call function above as a monad 227 | func.append(operators.Operator( '↑', 1, lambda stack, z, mode: callStack.append((callStack[-1]-1)%len(functions)) or [ stack.append(i) for i in runFunction([z], functions[callStack[-1]]) ]+[1] and callStack.pop() )) 228 | elif line[0] == '⇈': 229 | # Call function above as a dyad 230 | func.append(operators.Operator( '⇈', 2, lambda stack, x, y, mode: callStack.append((callStack[-1]-1)%len(functions)) or [ stack.append(i) for i in runFunction([x, y], functions[callStack[-1]]) ]+[1] and callStack.pop() )) 231 | elif line[0] == '⇓': 232 | # Call function below on whole stack 233 | func.append(operators.Operator( '⇓', 0, lambda stack: callStack.append((callStack[-1]+1)%len(functions)) or runFunction(stack, functions[callStack[-1]])+[1] and callStack.pop() )) 234 | elif line[0] == '↓': 235 | # Call function below as a monad 236 | func.append(operators.Operator( '↓', 1, lambda stack, z, mode: callStack.append((callStack[-1]+1)%len(functions)) or [ stack.append(i) for i in runFunction([z], functions[callStack[-1]]) ]+[1] and callStack.pop() )) 237 | elif line[0] == '⇊': 238 | # Call function below as a dyad 239 | func.append(operators.Operator( '⇊', 2, lambda stack, x, y, mode: callStack.append((callStack[-1]+1)%len(functions)) or [ stack.append(i) for i in runFunction([x, y], functions[callStack[-1]]) ]+[1] and callStack.pop() )) 240 | elif line[0] == '⇐': 241 | # Call current function on whole stack 242 | func.append(operators.Operator( '⇐', 0, lambda stack: callStack.append(callStack[-1]) or runFunction(stack, functions[callStack[-1]])+[1] and callStack.pop() )) 243 | elif line[0] == '←': 244 | # Call current function as a monad 245 | func.append(operators.Operator( '←', 1, lambda stack, z, mode: callStack.append(callStack[-1]) or [ stack.append(i) for i in runFunction([z], functions[callStack[-1]]) ]+[1] and callStack.pop() )) 246 | elif line[0] == '⇇': 247 | # Call current function as a dyad 248 | func.append(operators.Operator( '⇇', 2, lambda stack, x, y, mode: callStack.append(callStack[-1]) or [ stack.append(i) for i in runFunction([x, y], functions[callStack[-1]]) ]+[1] and callStack.pop() )) 249 | line = line[1:] 250 | elif line[0] == '[': 251 | # Match the opening of an array 252 | func.append(operators.Operator('[', 0, openArray)) 253 | line = line[1:] 254 | elif line[0] == ']': 255 | # Match the opening of an array 256 | func.append(operators.Operator(']', 0, closeArray)) 257 | line = line[1:] 258 | elif line[0] in '∂€₵': 259 | # Match the potential start of a 2-byte operator/constant 260 | if line[:2] in operators.ops: 261 | func.append(operators.ops[line[:2]]) 262 | line = line[2:] 263 | else: 264 | line = line[1:] 265 | elif line[0] in operators.ops: 266 | # Match an operator 267 | func.append(operators.ops[line[0]]) 268 | line = line[1:] 269 | elif line[0] in metas.metas: 270 | # Match a meta 271 | meta = metas.metas[line[0]] 272 | #func.append(metas.metas[line[0]]) 273 | if meta[1] == 1: # If it acts on 1 operator 274 | if len(func) < 1: 275 | raise SyntaxError("meta "+meta[0]+" must follow 1 operator") 276 | arity = func[-1].arity if meta[2] == -1 else meta[2] 277 | func = func[:-1]+[ operators.Operator(func[-1].name+meta[0], arity, determineMetaCallStyle(meta[3], arity, func[-1])) ] 278 | elif meta[1] == 2: 279 | if len(func) < 2: 280 | raise SyntaxError("meta "+meta[0]+" must follow 2 operators") 281 | arity = meta[2] 282 | func = func[:-2]+[ operators.Operator(func[-1].name+meta[0], arity, determineMetaCallStyle(meta[3], arity, func[-2], func[-1])) ] 283 | 284 | line = line[1:] 285 | else: 286 | line = line[1:] 287 | 288 | return func 289 | 290 | """ 291 | runFunction(stack, func) 292 | 293 | Runs a function on a stack, and returns the final stack. 294 | 295 | stack: The stack to run on 296 | func: The function to run 297 | """ 298 | def runFunction(stack, func): 299 | 300 | for op in func: 301 | try: 302 | 303 | for i in arrayMarkers: 304 | arrayMarkers.insert(0, max(min(arrayMarkers.pop(), len(stack)-op.arity), 0)) 305 | 306 | op.execute(stack) 307 | except Exception as error: 308 | sys.stderr.write("Error while executing operator "+op.name+": "+str(error)+'\n') 309 | exit(1) 310 | 311 | return stack 312 | 313 | 314 | def runOperatorString(string, x = None, y = None): 315 | tempStack = [] 316 | 317 | for op in string: 318 | if x != None: 319 | tempStack.append(x) 320 | if y != None: 321 | tempStack.append(y) 322 | op.execute(tempStack) 323 | 324 | return tempStack 325 | 326 | lines = code.split('\n') 327 | 328 | 329 | for line in lines: 330 | functions.append(decompose(line)) 331 | 332 | 333 | # Running 334 | 335 | callStack.append(len(functions)-1) 336 | runFunction(stack, functions[callStack[-1]]) 337 | 338 | ########################### 339 | 340 | code = '' 341 | 342 | args = sys.argv[1:] 343 | flags = [] 344 | 345 | if len(args) > 0: 346 | if re.match('^-', args[0]): 347 | # If the next arg starts with - it has flags 348 | flags = list(args[0][1:]) 349 | args = args[1:] 350 | 351 | if len(args) > 0: 352 | source = open(args[0], 'rb') 353 | code = source.read() 354 | 355 | if 'e' in flags: 356 | code = utilities.codepageDecode(code) 357 | else: 358 | code = code.decode('utf-8') 359 | 360 | else: 361 | raise Exception("No source file specified.\n") 362 | exit(1) 363 | 364 | # e 365 | def eOperator(stack, z, mode): 366 | if mode == 1: # num 367 | stack.append(utilities.formatNum(10**z)) 368 | elif mode == 2: # str 369 | interpret(z) 370 | elif mode == 3: # list 371 | [stack.append(i) for i in z] 372 | else: 373 | operators.monadNotImplemented(mode, 'e') 374 | 375 | operators.ops['e'] = operators.Operator('e', 1, eOperator) 376 | 377 | sourcecode = code 378 | interpret(code) 379 | 380 | if len(stack) > 0 and utilities.manualOutput == False: 381 | print(utilities.outputFormat(stack[-1])) 382 | 383 | 384 | -------------------------------------------------------------------------------- /metas.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | METAS 5 | 6 | Every function here defines a meta; that is, a command that is paired with 7 | one or two operators and executes them in a special way. 8 | 9 | Each meta function should take two arguments: 10 | 11 | stack: The stack with which to work. 12 | ops: A list of operators supplied to this meta. 13 | 14 | """ 15 | 16 | import operators 17 | import utilities 18 | 19 | 20 | # ₔ 21 | def swappedArgs(stack, ops, mode = None, x = None, y = None): 22 | if ops[0].arity == 0: 23 | ops[0].execute(stack) 24 | elif ops[0].arity == 1: 25 | stack.append(x) 26 | ops[0].execute(stack) 27 | elif ops[0].arity == 2: 28 | stack.append(y) 29 | stack.append(x) 30 | ops[0].execute(stack) 31 | 32 | # ₌ 33 | def peek(stack, ops, mode = None, x = None, y = None): 34 | if ops[0].arity == 0: 35 | ops[0].execute(stack) 36 | elif ops[0].arity == 1: 37 | stack.append(x) 38 | stack.append(x) 39 | ops[0].execute(stack) 40 | elif ops[0].arity == 2: 41 | stack.append(x) 42 | stack.append(y) 43 | stack.append(x) 44 | stack.append(y) 45 | ops[0].execute(stack) 46 | 47 | # ₓ 48 | def repeat(stack, ops, mode = None, x = None, y = None): 49 | for i in range(x): 50 | ops[0].execute(stack) 51 | 52 | # ? 53 | def conditional(stack, ops, mode = None, x = None, y = None): 54 | if x: 55 | ops[0].execute(stack) 56 | else: 57 | ops[1].execute(stack) 58 | 59 | # ¿ 60 | def ifTrue(stack, ops, mode = None, x = None, y = None): 61 | if x: 62 | ops[0].execute(stack) 63 | 64 | # ¡ 65 | def ifFalse(stack, ops, mode = None, x = None, y = None): 66 | if not x: 67 | ops[0].execute(stack) 68 | 69 | # ⁇ 70 | def select(stack, ops, mode = None, x = None, y = None): 71 | result = [] 72 | tempStack = [] 73 | 74 | if ops[0].arity == 0: 75 | raise SyntaxError("⁇ can't be combined with niladic operator "+ops[0].name) 76 | 77 | elif ops[0].arity == 1: 78 | 79 | x = utilities.castToList(x) 80 | 81 | for item in x: 82 | tempStack = [item] 83 | ops[0].execute(tempStack) 84 | if tempStack.pop(): 85 | result.append(item) 86 | stack.append(result) 87 | 88 | elif ops[0].arity == 2: 89 | 90 | if mode == 7 or mode == 8 or mode == 9: 91 | # if x is a list 92 | for item in x: 93 | tempStack = [item, y] 94 | ops[0].execute(tempStack) 95 | if tempStack.pop(): 96 | result.append(item) 97 | stack.append(result) 98 | elif mode == 3 or mode == 6: 99 | # if y is a list 100 | for item in y: 101 | tempStack = [x, item] 102 | ops[0].execute(tempStack) 103 | if tempStack.pop(): 104 | result.append(item) 105 | stack.append(result) 106 | else: 107 | # if neither is a list 108 | x = utilities.castToList(x) 109 | for item in x: 110 | tempStack = [item, y] 111 | ops[0].execute(tempStack) 112 | if tempStack.pop(): 113 | result.append(item) 114 | stack.append(result) 115 | 116 | # ⁈ 117 | def reject(stack, ops, mode = None, x = None, y = None): 118 | result = [] 119 | tempStack = [] 120 | 121 | if ops[0].arity == 0: 122 | raise SyntaxError("⁈ can't be combined with niladic operator "+ops[0].name) 123 | 124 | elif ops[0].arity == 1: 125 | 126 | x = utilities.castToList(x) 127 | 128 | for item in x: 129 | tempStack = [item] 130 | ops[0].execute(tempStack) 131 | if not tempStack.pop(): 132 | result.append(item) 133 | stack.append(result) 134 | 135 | elif ops[0].arity == 2: 136 | 137 | if mode == 7 or mode == 8 or mode == 9: 138 | # if x is a list 139 | for item in x: 140 | tempStack = [item, y] 141 | ops[0].execute(tempStack) 142 | if not tempStack.pop(): 143 | result.append(item) 144 | stack.append(result) 145 | elif mode == 3 or mode == 6: 146 | # if y is a list 147 | for item in y: 148 | tempStack = [x, item] 149 | ops[0].execute(tempStack) 150 | if not tempStack.pop(): 151 | result.append(item) 152 | stack.append(result) 153 | else: 154 | # if neither is a list 155 | x = utilities.castToList(x) 156 | for item in x: 157 | tempStack = [item, y] 158 | ops[0].execute(tempStack) 159 | if not tempStack.pop(): 160 | result.append(item) 161 | stack.append(result) 162 | 163 | # ¦ 164 | def mapList(stack, ops, mode = None, x = None, y = None): 165 | result = [] 166 | tempStack = [] 167 | 168 | if ops[0].arity == 0: 169 | raise SyntaxError("¦ can't be combined with niladic operator "+ops[0].name) 170 | 171 | elif ops[0].arity == 1: 172 | 173 | if mode != 3: 174 | # If x is not a list 175 | x = utilities.castToList(x) 176 | 177 | for item in x: 178 | tempStack = [item] 179 | ops[0].execute(tempStack) 180 | result += tempStack 181 | stack.append(result) 182 | 183 | elif ops[0].arity == 2: 184 | 185 | if mode == 7 or mode == 8 or mode == 9: 186 | # if x is a list 187 | for item in x: 188 | tempStack = [item, y] 189 | ops[0].execute(tempStack) 190 | result += tempStack 191 | stack.append(result) 192 | elif mode == 3 or mode == 6: 193 | # if y is a list 194 | for item in y: 195 | tempStack = [x, item] 196 | ops[0].execute(tempStack) 197 | result += tempStack 198 | stack.append(result) 199 | else: 200 | # if neither is a list 201 | x = utilities.castToList(x) 202 | for item in x: 203 | tempStack = [item, y] 204 | ops[0].execute(tempStack) 205 | result += tempStack 206 | stack.append(result) 207 | 208 | # ⊢ 209 | def reduceList(stack, ops, mode = None, x = None, y = None): 210 | if ops[0].arity != 2: 211 | raise SyntaxError("⊢ must be combined with a dyad") 212 | 213 | x = utilities.castToList(x) 214 | 215 | if len(x) == 0: 216 | stack.append(0) 217 | else: 218 | stack.append(x[0]) 219 | x = x[1:] 220 | for i in x: 221 | stack.append(i) 222 | ops[0].execute(stack) 223 | 224 | # ⊣ 225 | def cumulativeReduceList(stack, ops, mode = None, x = None, y = None): 226 | if ops[0].arity != 2: 227 | raise SyntaxError("⊣ must be combined with a dyad") 228 | 229 | x = utilities.castToList(x) 230 | 231 | reduction = [] 232 | 233 | for p in [x[:i] for i in range(1, len(x)+1)]: 234 | if len(p) == 0: 235 | reduction.append(0) 236 | else: 237 | reduction.append(p[0]) 238 | p = p[1:] 239 | for i in p: 240 | reduction.append(i) 241 | ops[0].execute(reduction) 242 | 243 | stack.append(reduction) 244 | 245 | # # 246 | def search(stack, ops, mode = None, x = None, y = None): 247 | result = [] 248 | tempStack = [] 249 | i = 1 250 | 251 | if ops[0].arity == 0: 252 | raise SyntaxError("# can't be combined with niladic operator "+ops[0].name) 253 | 254 | elif ops[0].arity == 1: 255 | 256 | if mode != 1: 257 | # if x is not a number 258 | x = utilities.castToNumber(x) 259 | 260 | while len(result) < int(x): 261 | tempStack = [i] 262 | ops[0].execute(tempStack) 263 | if tempStack.pop(): 264 | result.append(i) 265 | i += 1 266 | stack.append(result) 267 | 268 | elif ops[0].arity == 2: 269 | 270 | if mode == 1 or mode == 2 or mode == 3: 271 | # if x is a number 272 | while len(result) < int(x): 273 | tempStack = [i, y] 274 | ops[0].execute(tempStack) 275 | if tempStack.pop(): 276 | result.append(i) 277 | i += 1 278 | stack.append(result) 279 | elif mode == 4 or mode == 7: 280 | # if y is a number 281 | while len(result) < int(y): 282 | tempStack = [x, i] 283 | ops[0].execute(tempStack) 284 | if tempStack.pop(): 285 | result.append(i) 286 | i += 1 287 | stack.append(result) 288 | else: 289 | # if neither is a number 290 | x = utilities.castToNumber(x) 291 | while len(result) < int(x): 292 | tempStack = [i, y] 293 | ops[0].execute(tempStack) 294 | if tempStack.pop(): 295 | result.append(i) 296 | i += 1 297 | stack.append(result) 298 | 299 | # † 300 | def vectorize(stack, ops, mode = None, x = None, y = None): 301 | 302 | if ops[0].arity == 0: 303 | raise SyntaxError("† can't be combined with a nilad") 304 | 305 | if ops[0].arity == 1: 306 | tempStack = [x] 307 | ops[0].execute(tempStack) 308 | tempStack = tempStack[::-1] 309 | while tempStack: 310 | stack.append(tempStack.pop()) 311 | 312 | tempStack = [y] 313 | ops[0].execute(tempStack) 314 | tempStack = tempStack[::-1] 315 | while tempStack: 316 | stack.append(tempStack.pop()) 317 | 318 | if ops[0].arity == 2: 319 | result = [] 320 | tempStack = [] 321 | 322 | x = utilities.castToList(x) 323 | y = utilities.castToList(y) 324 | 325 | l = min(len(x), len(y)) 326 | 327 | for i in range(l): 328 | tempStack = [x[i], y[i]] 329 | ops[0].execute(tempStack) 330 | result += tempStack 331 | 332 | result += x[l:] + y[l:] 333 | 334 | stack.append(result) 335 | 336 | # ‡ 337 | def cartesian(stack, ops, mode = None, x = None, y = None): 338 | 339 | if ops[0].arity == 0: 340 | raise SyntaxError("† can't be combined with a nilad") 341 | 342 | if ops[0].arity == 1: 343 | tempStack = [x] 344 | ops[0].execute(tempStack) 345 | tempStack = tempStack[::-1] 346 | while tempStack: 347 | stack.append(tempStack.pop()) 348 | 349 | stack.append(y) 350 | 351 | if ops[0].arity == 2: 352 | result = [] 353 | tempStack = [] 354 | row = [] 355 | 356 | x = utilities.castToList(x) 357 | y = utilities.castToList(y) 358 | 359 | for i in x: 360 | for j in y: 361 | tempStack = [i, j] 362 | ops[0].execute(tempStack) 363 | row += tempStack 364 | result.append(row) 365 | row = [] 366 | 367 | stack.append(result) 368 | 369 | # ↺ 370 | def whileLoop(stack, ops, mode = None, x = None, y = None): 371 | 372 | while True: 373 | ops[0].execute(stack) 374 | 375 | if stack.pop(): 376 | ops[1].execute(stack) 377 | else: 378 | break 379 | 380 | # ↻ 381 | def untilLoop(stack, ops, mode = None, x = None, y = None): 382 | 383 | while True: 384 | ops[0].execute(stack) 385 | 386 | if not stack.pop(): 387 | ops[1].execute(stack) 388 | else: 389 | break 390 | 391 | # ° 392 | def untilDoneLoop(stack, ops, mode = None, x = None, y = None): 393 | lastValue = None 394 | 395 | while True: 396 | ops[0].execute(stack) 397 | if not (lastValue == None or len(stack) == 0 or stack[-1] != lastValue): 398 | break 399 | lastValue = stack[-1] 400 | 401 | # º 402 | def untilDifferentLoop(stack, ops, mode = None, x = None, y = None): 403 | lastValue = None 404 | 405 | while True: 406 | ops[0].execute(stack) 407 | if not (lastValue == None or len(stack) == 0 or stack[-1] == lastValue): 408 | break 409 | lastValue = stack[-1] 410 | 411 | # ª 412 | def whileUniqueLoop(stack, ops, mode = None, x = None, y = None): 413 | values = [] 414 | 415 | while True: 416 | ops[0].execute(stack) 417 | if not (len(values) == 0 or len(stack) == 0 or stack[-1] not in values): 418 | break 419 | values.append(stack[-1]) 420 | 421 | # ∞ 422 | def infiniteLoop(stack, ops, mode = None, x = None, y = None): 423 | while True: 424 | ops[0].execute(stack) 425 | 426 | # ∆ 427 | def findIndex(stack, ops, mode = None, x = None, y = None): 428 | tempStack = [] 429 | 430 | if ops[0].arity == 0: 431 | raise SyntaxError("∆ can't be combined with niladic operator "+ops[0].name) 432 | 433 | elif ops[0].arity == 1: 434 | 435 | x = utilities.castToList(x) 436 | 437 | for i in range(len(x)): 438 | tempStack = [x[i]] 439 | ops[0].execute(tempStack) 440 | if tempStack.pop(): 441 | stack.append(i+1) 442 | return 443 | stack.append(0) 444 | 445 | elif ops[0].arity == 2: 446 | 447 | if mode == 7 or mode == 8 or mode == 9: 448 | # if x is a list 449 | for i in range(len(x)): 450 | tempStack = [x[i], y] 451 | ops[0].execute(tempStack) 452 | if tempStack.pop(): 453 | stack.append(i+1) 454 | return 455 | stack.append(0) 456 | elif mode == 3 or mode == 6: 457 | # if y is a list 458 | for i in range(len(y)): 459 | tempStack = [x, y[i]] 460 | ops[0].execute(tempStack) 461 | if tempStack.pop(): 462 | stack.append(i+1) 463 | return 464 | stack.append(0) 465 | else: 466 | # if neither is a list 467 | x = utilities.castToList(x) 468 | for i in range(len(x)): 469 | tempStack = [x[i], y] 470 | ops[0].execute(tempStack) 471 | if tempStack.pop(): 472 | stack.append(i+1) 473 | return 474 | stack.append(0) 475 | 476 | # ∇ 477 | def findElement(stack, ops, mode = None, x = None, y = None): 478 | tempStack = [] 479 | 480 | if ops[0].arity == 0: 481 | raise SyntaxError("∇ can't be combined with niladic operator "+ops[0].name) 482 | 483 | elif ops[0].arity == 1: 484 | 485 | x = utilities.castToList(x) 486 | 487 | for i in x: 488 | tempStack = [i] 489 | ops[0].execute(tempStack) 490 | if tempStack.pop(): 491 | stack.append(i) 492 | return 493 | 494 | elif ops[0].arity == 2: 495 | 496 | if mode == 7 or mode == 8 or mode == 9: 497 | # if x is a list 498 | for i in x: 499 | tempStack = [i, y] 500 | ops[0].execute(tempStack) 501 | if tempStack.pop(): 502 | stack.append(i) 503 | return 504 | elif mode == 3 or mode == 6: 505 | # if y is a list 506 | for i in y: 507 | tempStack = [x, i] 508 | ops[0].execute(tempStack) 509 | if tempStack.pop(): 510 | stack.append(i) 511 | return 512 | else: 513 | # if neither is a list 514 | x = utilities.castToList(x) 515 | for i in x: 516 | tempStack = [i, y] 517 | ops[0].execute(tempStack) 518 | if tempStack.pop(): 519 | stack.append(i) 520 | return 521 | 522 | # ∫ 523 | def sortByKey(stack, ops, mode = None, x = None, y = None): 524 | result = [] 525 | tempStack = [] 526 | 527 | if ops[0].arity == 0: 528 | raise SyntaxError("∫ can't be combined with niladic operator "+ops[0].name) 529 | 530 | elif ops[0].arity == 1: 531 | 532 | if mode != 3: 533 | # If x is not a list 534 | x = utilities.castToList(x) 535 | 536 | for i in range(len(x)): 537 | tempStack = [x[i]] 538 | ops[0].execute(tempStack) 539 | result.append([tempStack[-1], i]) 540 | tempStack=[] 541 | 542 | result = sorted(result) 543 | stack.append([x[p[1]] for p in result]) 544 | 545 | elif ops[0].arity == 2: 546 | 547 | if mode == 7 or mode == 8 or mode == 9: 548 | # if x is a list 549 | for i in range(len(x)): 550 | tempStack = [x[i], y] 551 | ops[0].execute(tempStack) 552 | result.append([tempStack[-1], i]) 553 | tempStack=[] 554 | result = sorted(result) 555 | stack.append([x[p[1]] for p in result]) 556 | elif mode == 3 or mode == 6: 557 | # if y is a list 558 | for i in range(len(y)): 559 | tempStack = [x, y[i]] 560 | ops[0].execute(tempStack) 561 | result.append([tempStack[-1], i]) 562 | tempStack=[] 563 | result = sorted(result) 564 | stack.append([y[p[1]] for p in result]) 565 | else: 566 | # if neither is a list 567 | x = utilities.castToList(x) 568 | for i in range(len(x)): 569 | tempStack = [x[i], y] 570 | ops[0].execute(tempStack) 571 | result.append([tempStack[-1], i]) 572 | tempStack=[] 573 | result = sorted(result) 574 | stack.append([x[p[1]] for p in result]) 575 | 576 | # ⌡ 577 | def minByKey(stack, ops, mode = None, x = None, y = None): 578 | result = [] 579 | tempStack = [] 580 | 581 | if ops[0].arity == 0: 582 | raise SyntaxError("⌡ can't be combined with niladic operator "+ops[0].name) 583 | 584 | elif ops[0].arity == 1: 585 | 586 | if mode != 3: 587 | # If x is not a list 588 | x = utilities.castToList(x) 589 | 590 | for i in range(len(x)): 591 | tempStack = [x[i]] 592 | ops[0].execute(tempStack) 593 | result.append([tempStack[-1], i]) 594 | tempStack=[] 595 | 596 | result = sorted(result) 597 | if result: 598 | stack.append(x[result[0][1]]) 599 | else: 600 | stack.append(0) 601 | 602 | elif ops[0].arity == 2: 603 | 604 | if mode == 7 or mode == 8 or mode == 9: 605 | # if x is a list 606 | for i in range(len(x)): 607 | tempStack = [x[i], y] 608 | ops[0].execute(tempStack) 609 | result.append([tempStack[-1], i]) 610 | tempStack=[] 611 | 612 | result = sorted(result) 613 | if result: 614 | stack.append(x[result[0][1]]) 615 | else: 616 | stack.append(0) 617 | elif mode == 3 or mode == 6: 618 | # if y is a list 619 | for i in range(len(y)): 620 | tempStack = [x, y[i]] 621 | ops[0].execute(tempStack) 622 | result.append([tempStack[-1], i]) 623 | tempStack=[] 624 | 625 | result = sorted(result) 626 | if result: 627 | stack.append(y[result[0][1]]) 628 | else: 629 | stack.append(0) 630 | else: 631 | # if neither is a list 632 | x = utilities.castToList(x) 633 | for i in range(len(x)): 634 | tempStack = [x[i], y] 635 | ops[0].execute(tempStack) 636 | result.append([tempStack[-1], i]) 637 | tempStack=[] 638 | 639 | result = sorted(result) 640 | if result: 641 | stack.append(x[result[0][1]]) 642 | else: 643 | stack.append(0) 644 | 645 | # ⌠ 646 | def maxByKey(stack, ops, mode = None, x = None, y = None): 647 | result = [] 648 | tempStack = [] 649 | 650 | if ops[0].arity == 0: 651 | raise SyntaxError("⌠ can't be combined with niladic operator "+ops[0].name) 652 | 653 | elif ops[0].arity == 1: 654 | 655 | if mode != 3: 656 | # If x is not a list 657 | x = utilities.castToList(x) 658 | 659 | for i in range(len(x)): 660 | tempStack = [x[i]] 661 | ops[0].execute(tempStack) 662 | result.append([tempStack[-1], i]) 663 | tempStack=[] 664 | 665 | result = sorted(result) 666 | if result: 667 | stack.append(x[result[-1][1]]) 668 | else: 669 | stack.append(0) 670 | 671 | elif ops[0].arity == 2: 672 | 673 | if mode == 7 or mode == 8 or mode == 9: 674 | # if x is a list 675 | for i in range(len(x)): 676 | tempStack = [x[i], y] 677 | ops[0].execute(tempStack) 678 | result.append([tempStack[-1], i]) 679 | tempStack=[] 680 | 681 | result = sorted(result) 682 | if result: 683 | stack.append(x[result[-1][1]]) 684 | else: 685 | stack.append(0) 686 | elif mode == 3 or mode == 6: 687 | # if y is a list 688 | for i in range(len(y)): 689 | tempStack = [x, y[i]] 690 | ops[0].execute(tempStack) 691 | result.append([tempStack[-1], i]) 692 | tempStack=[] 693 | 694 | result = sorted(result) 695 | if result: 696 | stack.append(y[result[-1][1]]) 697 | else: 698 | stack.append(0) 699 | else: 700 | # if neither is a list 701 | x = utilities.castToList(x) 702 | for i in range(len(x)): 703 | tempStack = [x[i], y] 704 | ops[0].execute(tempStack) 705 | result.append([tempStack[-1], i]) 706 | tempStack=[] 707 | 708 | result = sorted(result) 709 | if result: 710 | stack.append(x[result[-1][1]]) 711 | else: 712 | stack.append(0) 713 | 714 | """ 715 | METAS DICT 716 | 717 | Each value should be an array of [symbol, #operators, arity, function] 718 | 719 | Arity is either fixed (i.e. 1 for things like conditional), or -1 if the arity is equal to the operator's arity (e.g. for map) 720 | 721 | """ 722 | 723 | metas = { 724 | 'ₔ': ['ₔ', 1, -1, swappedArgs], 725 | '₌': ['₌', 1, -1, peek], 726 | 'ₓ': ['ₓ', 1, 1, repeat], 727 | '?': ['?', 2, 1, conditional], 728 | '¿': ['¿', 1, 1, ifTrue], 729 | '¡': ['¡', 1, 1, ifFalse], 730 | '⁇': ['⁇', 1, -1, select], 731 | '⁈': ['⁈', 1, -1, reject], 732 | '¦': ['¦', 1, -1, mapList], 733 | '⊢': ['⊢', 1, 1, reduceList], 734 | '⊣': ['⊣', 1, 1, cumulativeReduceList], 735 | '#': ['#', 1, -1, search], 736 | '†': ['†', 1, 2, vectorize], 737 | '‡': ['‡', 1, 2, cartesian], 738 | '↺': ['↺', 2, 0, whileLoop], 739 | '↻': ['↻', 2, 0, untilLoop], 740 | '°': ['°', 1, 0, untilDoneLoop], 741 | 'º': ['º', 1, 0, untilDifferentLoop], 742 | 'ª': ['ª', 1, 0, whileUniqueLoop], 743 | '∞': ['∞', 1, 0, infiniteLoop], 744 | '∆': ['∆', 1, -1, findIndex], 745 | '∇': ['∇', 1, -1, findElement], 746 | '∫': ['∫', 1, -1, sortByKey], 747 | '⌡': ['⌡', 1, -1, minByKey], 748 | '⌠': ['⌠', 1, -1, maxByKey] 749 | } -------------------------------------------------------------------------------- /operators.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | import re 5 | import math 6 | import datetime 7 | import time 8 | import functools 9 | import itertools 10 | import random 11 | 12 | import utilities 13 | 14 | """ 15 | OPERATORS 16 | 17 | Here the operators are defined. Each operator is a function that accepts the stack 18 | as an argument and modifies it in place. 19 | 20 | """ 21 | 22 | class Operator(object): 23 | 24 | def __init__(self, name, arity, func): 25 | self.name = name 26 | self.arity = arity 27 | self.func = func 28 | 29 | def execute(self, stack): 30 | if self.arity == 0: 31 | self.func(stack) 32 | elif self.arity == 1: 33 | if len(stack) > 0: 34 | z = stack.pop() 35 | else: 36 | z = utilities.getInput() 37 | mode = {int: 1, float: 1, str: 2, list: 3}[type(z)] 38 | self.func(stack, z, mode) 39 | elif self.arity == 2: 40 | if len(stack) >= 2: 41 | y = stack.pop() 42 | x = stack.pop() 43 | elif len(stack) == 1: 44 | x = stack.pop() 45 | y = utilities.getInput() 46 | else: 47 | x = utilities.getInput() 48 | y = utilities.getInput() 49 | self.func(stack, x, y, dyadMode(x,y)) 50 | 51 | 52 | 53 | """ HELPER FUNCTIONS """ 54 | 55 | def dyadMode(x, y): 56 | # Returns the mode the dyad should execute, based on the types of its arguments 57 | tx = type(x) 58 | ty = type(y) 59 | if tx == int or tx == float: 60 | if ty == int or ty == float: 61 | return 1 62 | elif ty == str: 63 | return 2 64 | elif ty == list: 65 | return 3 66 | elif tx == str: 67 | if ty == int or ty == float: 68 | return 4 69 | elif ty == str: 70 | return 5 71 | elif ty == list: 72 | return 6 73 | elif tx == list: 74 | if ty == int or ty == float: 75 | return 7 76 | elif ty == str: 77 | return 8 78 | elif ty == list: 79 | return 9 80 | else: 81 | return 0 82 | 83 | 84 | def monadNotImplemented(mode, char): 85 | raise NotImplementedError('('+["num", "str", "list"][mode-1]+") "+char+" not implemented") 86 | 87 | def dyadNotImplemented(mode, char): 88 | raise NotImplementedError('('+["num", "str", "list"][(mode-1)//3]+", "+["num", "str", "list"][mode%3-1]+") "+char+" not implemented") 89 | 90 | 91 | # Increments an alphabetic string to the next string, alphabetically 92 | def incrementWord(word): 93 | if len(word) == 0: 94 | return 'a' 95 | else: 96 | if word[-1] == 'z': 97 | if len(word) == 1: 98 | return 'aa' 99 | else: 100 | return incrementWord(word[:-1])+'a' 101 | elif word[-1] == 'Z': 102 | if len(word) == 1: 103 | return 'AA' 104 | else: 105 | return incrementWord(word[:-1])+'A' 106 | else: 107 | return word[:-1]+chr(ord(word[-1])+1) 108 | 109 | 110 | """ OPERATOR FUNCTIONS """ 111 | 112 | ''' NILADS ''' 113 | 114 | # ø 115 | def emptySetOperator(stack): 116 | stack.append([]) 117 | 118 | # Ø 119 | def emptyStringOperator(stack): 120 | stack.append("") 121 | 122 | # ¶ 123 | def pilcrowOperator(stack): 124 | stack.append('\n') 125 | 126 | # § 127 | def sectionOperator(stack): 128 | stack.append(' ') 129 | 130 | # @ 131 | def atOperator(stack): 132 | stack.append(utilities.getInput()) 133 | 134 | # €. 135 | def extDotOperator(stack): 136 | print('STACK: '+utilities.outputFormat(stack)) 137 | 138 | # ₵a 139 | def constaOperator(stack): 140 | stack.append('abcdefghijklmnopqrstuvwxyz') 141 | 142 | # ₵A 143 | def constAOperator(stack): 144 | stack.append('ABCDEFGHIJKLMNOPQRSTUVWXYZ') 145 | 146 | # ₵v 147 | def constvOperator(stack): 148 | stack.append('aeiou') 149 | 150 | # ₵V 151 | def constVOperator(stack): 152 | stack.append('AEIOU') 153 | 154 | # ₵x 155 | def constxOperator(stack): 156 | stack.append('bcdfghjklmnpqrstvwxz') 157 | 158 | # ₵X 159 | def constXOperator(stack): 160 | stack.append('BCDFGHJKLMNPQRSTVWXZ') 161 | 162 | # ₵c 163 | def constcOperator(stack): 164 | stack.append('bcdfghjklmnpqrstvwxyz') 165 | 166 | # ₵C 167 | def constCOperator(stack): 168 | stack.append('BCDFGHJKLMNPQRSTVWXYZ') 169 | 170 | # ₵y 171 | def constyOperator(stack): 172 | stack.append('aeiouy') 173 | 174 | # ₵Y 175 | def constYOperator(stack): 176 | stack.append('AEIOUY') 177 | 178 | # ₵D 179 | def constDOperator(stack): 180 | stack.append('0123456789') 181 | 182 | # ₵H 183 | def constHOperator(stack): 184 | stack.append('0123456789ABCDEF') 185 | 186 | # ₵h 187 | def consthOperator(stack): 188 | stack.append('0123456789abcdef') 189 | 190 | # ₵q 191 | def constqOperator(stack): 192 | stack.append(['qwertyuiop', 'asdfghjkl', 'zxcvbnm']) 193 | 194 | # ₵Q 195 | def constQOperator(stack): 196 | stack.append(['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM']) 197 | 198 | # ₵R 199 | def constROperator(stack): 200 | stack.append(""" !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~""") 201 | 202 | # ₵r 203 | def constrOperator(stack): 204 | stack.append(utilities.codepage) 205 | 206 | # ₵W 207 | def constWOperator(stack): 208 | stack.append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_") 209 | 210 | # ₸ 211 | def struckTOperator(stack): 212 | stack.append(10) 213 | 214 | # ℍ 215 | def struckHOperator(stack): 216 | stack.append(100) 217 | 218 | # ₵P 219 | def constPOperator(stack): 220 | stack.append(math.pi) 221 | 222 | # ₵E 223 | def constEOperator(stack): 224 | stack.append(math.e) 225 | 226 | # ∂a 227 | def dateaOperator(stack): 228 | stack.append(1 if datetime.datetime.today().hour >= 12 else 0) 229 | 230 | # ∂A 231 | def dateAOperator(stack): 232 | stack.append("PM" if datetime.datetime.today().hour >= 12 else "AM") 233 | 234 | # ∂d 235 | def datedOperator(stack): 236 | stack.append(datetime.datetime.today().day) 237 | 238 | # ∂D 239 | def dateDOperator(stack): 240 | stack.append("{:0>2}".format(datetime.datetime.today().day)) 241 | 242 | # ∂h 243 | def datehOperator(stack): 244 | stack.append(datetime.datetime.today().hour) 245 | 246 | # ∂H 247 | def dateHOperator(stack): 248 | stack.append("{:0>2}".format(datetime.datetime.today().hour)) 249 | 250 | # ∂i 251 | def dateiOperator(stack): 252 | stack.append(datetime.datetime.today().hour%12 or 12) 253 | 254 | # ∂I 255 | def dateIOperator(stack): 256 | stack.append("{:0>2}".format(datetime.datetime.today().hour%12 or 12)) 257 | 258 | # ∂k 259 | def datekOperator(stack): 260 | stack.append([31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]) 261 | 262 | # ∂K 263 | def dateKOperator(stack): 264 | stack.append([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]) 265 | 266 | # ∂l 267 | def datelOperator(stack): 268 | year = datetime.datetime.today().year 269 | stack.append(1 if ((year % 4 == 0 and year % 100 != 0) or year % 400 == 0) else 0) 270 | 271 | # ∂L 272 | def dateLOperator(stack): 273 | year = datetime.datetime.today().year 274 | while not ((year % 4 == 0 and year % 100 != 0) or year % 400 == 0): 275 | year += 1 276 | stack.append(year) 277 | 278 | # ∂m 279 | def datemOperator(stack): 280 | stack.append(datetime.datetime.today().month) 281 | 282 | # ∂M 283 | def dateMOperator(stack): 284 | stack.append("{:0>2}".format(datetime.datetime.today().month)) 285 | 286 | # ∂n 287 | def datenOperator(stack): 288 | stack.append(datetime.datetime.today().minute) 289 | 290 | # ∂N 291 | def dateNOperator(stack): 292 | stack.append("{:0>2}".format(datetime.datetime.today().minute)) 293 | 294 | # ∂o 295 | def dateoOperator(stack): 296 | stack.append(["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]) 297 | 298 | # ∂O 299 | def dateOOperator(stack): 300 | stack.append(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]) 301 | 302 | # ∂q 303 | def dateqOperator(stack): 304 | stack.append(["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]) 305 | 306 | # ∂Q 307 | def dateQOperator(stack): 308 | stack.append(["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]) 309 | 310 | # ∂t 311 | def datetOperator(stack): 312 | stack.append([datetime.datetime.today().hour, datetime.datetime.today().minute, datetime.datetime.today().second]) 313 | 314 | # ∂T 315 | def dateTOperator(stack): 316 | stack.append([datetime.datetime.today().hour%12 or 12, datetime.datetime.today().minute, datetime.datetime.today().second, 1 if datetime.datetime.today().hour >= 12 else 0]) 317 | 318 | # ∂s 319 | def datesOperator(stack): 320 | stack.append(datetime.datetime.today().second) 321 | 322 | # ∂S 323 | def dateSOperator(stack): 324 | stack.append("{:0>2}".format(datetime.datetime.today().second)) 325 | 326 | # ∂u 327 | def dateuOperator(stack): 328 | stack.append(datetime.datetime.today().microsecond//1000) 329 | 330 | # ∂U 331 | def dateUOperator(stack): 332 | stack.append(datetime.datetime.today().microsecond) 333 | 334 | # ∂w 335 | def datewOperator(stack): 336 | stack.append(datetime.datetime.today().isoweekday()%7+1) 337 | 338 | # ∂W 339 | def dateWOperator(stack): 340 | stack.append(datetime.datetime.today().isoweekday()) 341 | 342 | # ∂x 343 | def datexOperator(stack): 344 | stack.append([datetime.datetime.today().year, datetime.datetime.today().month, datetime.datetime.today().day]) 345 | 346 | # ∂X 347 | def dateXOperator(stack): 348 | d = datetime.datetime.today() 349 | stack.append([d.year, d.month, d.today().day, d.isoweekday()%7+1, d.hour, d.minute, d.second, d.microsecond//1000]) 350 | 351 | # ∂y 352 | def dateyOperator(stack): 353 | stack.append(datetime.datetime.today().year) 354 | 355 | # ∂Y 356 | def dateYOperator(stack): 357 | stack.append(datetime.datetime.today().year%100) 358 | 359 | # ∂z 360 | def datezOperator(stack): 361 | stack.append(time.timezone//-3600) 362 | 363 | # ∂Z 364 | def dateZOperator(stack): 365 | stack.append(int(time.time()*1000)) 366 | 367 | ''' MONADS ''' 368 | 369 | # ! 370 | def exclamationOperator(stack, z, mode): 371 | if mode > 0: # same for all types... 372 | stack.append(1 if not z else 0) 373 | else: 374 | monadNotImplemented(mode, '') 375 | 376 | # $ 377 | def dollarOperator(stack, z, mode): 378 | if mode == 1: # num 379 | result = [] 380 | sign = -1 if z<0 else 1 381 | z = abs(z) 382 | while z != 0: 383 | result.insert(0, (z % 10)*sign) 384 | z //= 10 385 | stack.append(result) 386 | elif mode == 2: # str 387 | stack.append(list(z)) 388 | elif mode == 3: # list 389 | stack.append(''.join(utilities.castToString(i) for i in z)) 390 | else: 391 | monadNotImplemented(mode, '') 392 | 393 | # ( 394 | def leftParenthesisOperator(stack, z, mode): 395 | if mode == 1: # num 396 | stack.append(utilities.formatNum(z-1)) 397 | elif mode == 2: # str 398 | if len(z) > 0: 399 | stack.append(z[0]) 400 | elif mode == 3: # list 401 | if len(z) > 0: 402 | stack.append(z[0]) 403 | else: 404 | monadNotImplemented(mode, '') 405 | 406 | # ) 407 | def rightParenthesisOperator(stack, z, mode): 408 | if mode == 1: # num 409 | stack.append(utilities.formatNum(z+1)) 410 | elif mode == 2: # str 411 | if len(z) > 0: 412 | stack.append(z[-1]) 413 | elif mode == 3: # list 414 | if len(z) > 0: 415 | stack.append(z[-1]) 416 | else: 417 | monadNotImplemented(mode, '') 418 | 419 | # : 420 | def colonOperator(stack, z, mode): 421 | if mode > 0: # same for all types... 422 | stack.append(z) 423 | stack.append(z) 424 | else: 425 | monadNotImplemented(mode, '') 426 | 427 | # b 428 | def bOperator(stack, z, mode): 429 | if mode == 1: # num 430 | stack.append(utilities.toBase(int(z), 2)) 431 | #elif mode == 2: # str 432 | elif mode == 3: # list 433 | stack.append(utilities.fromBase([utilities.castToNumber(i) for i in z], 2)) 434 | else: 435 | monadNotImplemented(mode, '') 436 | 437 | # c 438 | def cOperator(stack, z, mode): 439 | if mode == 1: # num 440 | stack.append(chr(int(z))) 441 | elif mode == 2: # str 442 | if z: 443 | stack.append(ord(z[0])) 444 | elif mode == 3: # list 445 | z = [utilities.castToNumber(i) for i in z] 446 | stack.append(utilities.fromBase(z, max(z)+1)) 447 | else: 448 | monadNotImplemented(mode, '') 449 | 450 | # d 451 | def dOperator(stack, z, mode): 452 | if mode == 1: # num 453 | z = abs(int(z)) 454 | stack.append([i for i in range(1, z+1) if z%i==0]) 455 | elif mode == 2: # str 456 | stack.append(utilities.castToNumber(z)) 457 | elif mode == 3: # list 458 | stack.append(utilities.castToNumber(z)) 459 | else: 460 | monadNotImplemented(mode, '') 461 | 462 | # e is defined in gaia.py 463 | 464 | # f 465 | def fOperator(stack, z, mode): 466 | if mode == 1: # num 467 | stack.append(math.factorial(int(z))) 468 | elif mode == 2: # str 469 | stack.append([''.join(p) for p in itertools.permutations(z)]) 470 | elif mode == 3: # list 471 | stack.append([list(p) for p in itertools.permutations(z)]) 472 | else: 473 | monadNotImplemented(mode, '') 474 | 475 | # g 476 | def gOperator(stack, z, mode): 477 | if mode == 1: # num 478 | 1#stack.append() 479 | elif mode == 2: # str 480 | args = sys.argv 481 | args = args[1:] 482 | if len(args) > 0: 483 | if re.match('^-', args[0]): 484 | # If the next arg starts with - it has flags 485 | flags = list(args[0][1:]) 486 | args = args[1:] 487 | 488 | filepath = args[0] 489 | filepath = re.sub('(/|^)[^/]*$','\g<1>',filepath) # Get the filepath for where the source is 490 | if z == '': 491 | z = args[0] # If z is empty then use the source file 492 | else: 493 | z = filepath + z 494 | 495 | stack.append(open(z, 'r', encoding='utf-8').read()) 496 | elif mode == 3: # list 497 | gradeup = lambda l:[x[1]+1 for x in sorted([[l[i], i] for i in range(len(l))])] 498 | stack.append(gradeup(z)) 499 | else: 500 | monadNotImplemented(mode, '') 501 | 502 | # h 503 | def hOperator(stack, z, mode): 504 | if mode == 1: # num 505 | stack.append(utilities.toBase(int(z), 16)) 506 | elif mode == 2: # str 507 | stack.append() 508 | elif mode == 3: # list 509 | stack.append(utilities.fromBase(z, 16)) 510 | else: 511 | monadNotImplemented(mode, '') 512 | 513 | # i 514 | def iOperator(stack, z, mode): 515 | if mode > 0: 516 | stack.append(z) 517 | else: 518 | monadNotImplemented(mode, '') 519 | 520 | # l 521 | def lOperator(stack, z, mode): 522 | if mode == 1: # num 523 | stack.append(len(str(z))) 524 | elif mode == 2: # str 525 | stack.append(len(z)) 526 | elif mode == 3: # list 527 | stack.append(len(z)) 528 | else: 529 | monadNotImplemented(mode, '') 530 | 531 | # n 532 | def nOperator(stack, z, mode): 533 | #if mode == 1: # num 534 | #elif mode == 2: # str 535 | if mode == 3: # list 536 | def depth(l): 537 | if type(l) != list: 538 | return 0 539 | d = 1 540 | for i in l: 541 | if type(l) == list: 542 | d = max(d, 1+depth(i)) 543 | return d 544 | stack.append(depth(z)) 545 | else: 546 | monadNotImplemented(mode, '') 547 | 548 | # o 549 | def oOperator(stack, z, mode): 550 | if mode == 2: # str 551 | stack.append(1 if sorted(z) in [z, z[::-1]] else 0) 552 | elif mode == 3: # list 553 | stack.append(1 if sorted(z) in [z, z[::-1]] else 0) 554 | else: 555 | monadNotImplemented(mode, '') 556 | 557 | # p 558 | def pOperator(stack, z, mode): 559 | if mode > 0: # any types 560 | sys.stdout.write(utilities.outputFormat(z)) 561 | utilities.manualOutput = True 562 | else: 563 | monadNotImplemented(mode, '') 564 | 565 | # q 566 | def qOperator(stack, z, mode): 567 | if mode > 0: # any types 568 | print(utilities.outputFormat(z)) 569 | utilities.manualOutput = True 570 | else: 571 | monadNotImplemented(mode, '') 572 | 573 | # r 574 | def rOperator(stack, z, mode): 575 | if mode == 1: # num 576 | stack.append(int(z)%2) 577 | elif mode == 2: # str 578 | stack.append() 579 | elif mode == 3: # list 580 | result = [] 581 | for i in range(len(z)): 582 | for j in range(len(z)): 583 | if i != j and [z[j], z[i]] not in result: 584 | result.append([z[i], z[j]]) 585 | stack.append(result) 586 | else: 587 | monadNotImplemented(mode, '') 588 | 589 | # s 590 | def sOperator(stack, z, mode): 591 | if mode == 1: # num 592 | stack.append(utilities.formatNum(z*z)) 593 | elif mode == 2: # str 594 | stack.append([[i, z[i-1]] for i in range(1,len(z)+1)]) 595 | elif mode == 3: # list 596 | stack.append([[i, z[i-1]] for i in range(1,len(z)+1)]) 597 | else: 598 | monadNotImplemented(mode, '') 599 | 600 | # t 601 | def tOperator(stack, z, mode): 602 | if mode == 1: # num 603 | n = int(z) 604 | p = 0 605 | factors = [] 606 | while n > 1: 607 | count = 0 608 | while n%utilities.getPrime(p) == 0: 609 | n //= utilities.getPrime(p) 610 | count += 1 611 | if count > 0: 612 | factors.append(utilities.getPrime(p)) 613 | p += 1 614 | for f in factors: 615 | z *= (f-1)/f 616 | stack.append(utilities.formatNum(z)) 617 | #elif mode == 2: # str 618 | elif mode == 3: # list 619 | z = [i if type(i)==list else [i] for i in z] 620 | 621 | maxrow = max(map(len, z)) 622 | newmatrix = [] 623 | 624 | for c in range(maxrow): 625 | newrow = [] 626 | for r in z: 627 | if len(r) > c: 628 | newrow.append(r[c]) 629 | newmatrix.append(newrow) 630 | stack.append(newmatrix) 631 | else: 632 | monadNotImplemented(mode, 't') 633 | 634 | # u 635 | def uOperator(stack, z, mode): 636 | if mode == 1: # num 637 | stack.append(utilities.formatNum(math.sqrt(z))) 638 | elif mode == 2: # str 639 | stack.append(''.join([z[i] for i in range(len(z)) if z[i] not in z[:i]])) 640 | elif mode == 3: # list 641 | stack.append([z[i] for i in range(len(z)) if z[i] not in z[:i]]) 642 | else: 643 | monadNotImplemented(mode, '') 644 | 645 | # v 646 | def vOperator(stack, z, mode): 647 | if mode == 1: # num 648 | sign = -1 if z < 0 else 1 649 | z = abs(z) 650 | stack.append(sign*utilities.formatNum(float(str(z)[::-1]))) 651 | elif mode == 2: # str 652 | stack.append(z[::-1]) 653 | elif mode == 3: # list 654 | stack.append(z[::-1]) 655 | else: 656 | monadNotImplemented(mode, '') 657 | 658 | # w 659 | def wOperator(stack, z, mode): 660 | if mode > 0: # any types 661 | stack.append([z]) 662 | else: 663 | monadNotImplemented(mode, '') 664 | 665 | # y 666 | def yOperator(stack, z, mode): 667 | if mode == 1: # num 668 | stack.append(1 if int(z)==z else 0) 669 | elif mode == 2: # str 670 | stack.append() 671 | elif mode == 3: # list 672 | if z: 673 | stack.append(1 if all(i == z[0] for i in z) else 0) 674 | else: 675 | stack.append(1) 676 | else: 677 | monadNotImplemented(mode, '') 678 | 679 | # \ 680 | def backslashOperator(stack, z , mode): 681 | if mode == 0: 682 | monadNotImplemented(mode, '') 683 | 684 | # _ 685 | def underscoreOperator(stack, z, mode): 686 | if mode == 1: # num 687 | stack.append(utilities.formatNum(-z)) 688 | #elif mode == 2: # str 689 | elif mode == 3: # list 690 | stack.append(utilities.flatten(z)) 691 | else: 692 | monadNotImplemented(mode, '') 693 | 694 | # ~ 695 | def tildeOperator(stack, z, mode): 696 | if mode == 1: # num 697 | stack.append(~int(z)) 698 | elif mode == 2: # str 699 | stack.append(''.join([c.upper() if c.islower() else (c.lower() if c.isupper() else c) for c in z])) 700 | elif mode == 3: # list 701 | stack.append() 702 | else: 703 | monadNotImplemented(mode, '') 704 | 705 | # … 706 | def lowEllipsisOperator(stack, z, mode): 707 | if mode == 1: # num 708 | z = int(z) 709 | if z == 0: 710 | stack.append([]) 711 | elif z > 0: 712 | stack.append(list(range(z))) 713 | elif z < 0: 714 | stack.append(list(range(0, z, -1))) 715 | elif mode == 2: # str 716 | stack.append([z[:i+1] for i in range(len(z))]) 717 | elif mode == 3: # list 718 | stack.append([z[:i+1] for i in range(len(z))]) 719 | else: 720 | monadNotImplemented(mode, '') 721 | 722 | # ┅ 723 | def highEllipsisOperator(stack, z, mode): 724 | if mode == 1: # num 725 | z = int(z) 726 | if z == 0: 727 | stack.append([0]) 728 | elif z > 0: 729 | stack.append(list(range(1, z+1))) 730 | elif z < 0: 731 | stack.append(list(range(-1, z-1, -1))) 732 | elif mode == 2: # str 733 | stack.append([z[-len(z)+i:] for i in range(len(z))]) 734 | elif mode == 3: # list 735 | stack.append([z[-len(z)+i:] for i in range(len(z))]) 736 | else: 737 | monadNotImplemented(mode, '') 738 | 739 | # ⌋ 740 | def floorOperator(stack, z, mode): 741 | if mode == 1: # num 742 | stack.append(int(math.floor(z))) 743 | elif mode == 2: # str 744 | stack.append(z.lower()) 745 | elif mode == 3: # list 746 | #z = [utilities.castToNumber(i) for i in z] 747 | if z == []: 748 | stack.append(0) 749 | else: 750 | stack.append(min(z)) 751 | else: 752 | monadNotImplemented(mode, '') 753 | 754 | # ⌉ 755 | def ceilOperator(stack, z, mode): 756 | if mode == 1: # num 757 | stack.append(int(math.ceil(z))) 758 | elif mode == 2: # str 759 | stack.append(z.upper()) 760 | elif mode == 3: # list 761 | #z = [utilities.castToNumber(i) for i in z] 762 | if z == []: 763 | stack.append(0) 764 | else: 765 | stack.append(max(z)) 766 | else: 767 | monadNotImplemented(mode, '') 768 | 769 | # Σ 770 | def sigmaOperator(stack, z, mode): 771 | if mode == 1: # num 772 | tempStack = [] 773 | dollarOperator(tempStack, z, mode) 774 | stack.append(sum(tempStack[0])) 775 | #elif mode == 2: # str 776 | elif mode == 3: # list 777 | stack.append(sum(utilities.castToNumber(i) for i in z)) 778 | else: 779 | monadNotImplemented(mode, '') 780 | 781 | # Π 782 | def piOperator(stack, z, mode): 783 | if mode == 1: # num 784 | tempStack = [] 785 | dollarOperator(tempStack, z, mode) 786 | stack.append(functools.reduce(lambda a,b:a*b, tempStack[0])) 787 | #elif mode == 2: # str 788 | elif mode == 3: # list 789 | if z == []: 790 | stack.append(1) 791 | else: 792 | stack.append(functools.reduce(lambda a,b:a*b, [utilities.castToNumber(i) for i in utilities.flatten(z)])) 793 | else: 794 | monadNotImplemented(mode, '') 795 | 796 | # ‼ 797 | def doubleExclamationOperator(stack, z, mode): 798 | if mode > 0: # Any types 799 | stack.append(1 if z else 0) 800 | else: 801 | monadNotImplemented(mode, '') 802 | 803 | # ċ 804 | def cHighDotOperator(stack, z, mode): 805 | if mode == 1: # num 806 | stack.append([0]*abs(int(z))) 807 | elif mode == 2: # str 808 | stack.append([ord(i) for i in z]) 809 | elif mode == 3: # list 810 | stack.append(list(range(1,len(z)+1))) 811 | else: 812 | monadNotImplemented(mode, '') 813 | 814 | # 815 | def dHighDotOperator(stack, z, mode): 816 | if mode == 1: # num 817 | z = int(z) 818 | if z < 4: 819 | stack.append([z, 1]) 820 | else: 821 | p = 0 822 | result = [] 823 | while z > 1: 824 | count = 0 825 | while z%utilities.getPrime(p) == 0: 826 | z //= utilities.getPrime(p) 827 | count += 1 828 | if count > 0: 829 | result.append([utilities.getPrime(p), count]) 830 | p += 1 831 | stack.append(result) 832 | elif mode == 2 or mode == 3: # str or list 833 | if len(z)==0: 834 | stack.append([]) 835 | result = [] 836 | for i in range(len(z)): 837 | for j in range(len(z), 0, -1): 838 | if i < j: 839 | result.append(z[i:j]) 840 | stack.append(result) 841 | else: 842 | monadNotImplemented(mode, '') 843 | 844 | # ḍ 845 | def dLowDotOperator(stack, z, mode): 846 | if mode == 1: # num 847 | z = int(z) 848 | if z < 4: 849 | stack.append([z]) 850 | else: 851 | p = 0 852 | result = [] 853 | while z > 1: 854 | while z%utilities.getPrime(p) == 0: 855 | result.append(utilities.getPrime(p)) 856 | z //= utilities.getPrime(p) 857 | p += 1 858 | stack.append(result) 859 | elif mode == 2 or mode == 3: # str or list 860 | def partitions(z): 861 | if len(z) == 0: 862 | return [[]] 863 | if len(z) == 1: 864 | return [[z]] 865 | return [[z[:i]]+t for i in range(1, len(z)+1) for t in partitions(z[i:])] 866 | stack.append(partitions(z)) 867 | else: 868 | monadNotImplemented(mode, '') 869 | 870 | # ė 871 | def eHighDotOperator(stack, z, mode): 872 | if mode == 1: # num 873 | stack.append(utilities.formatNum(math.cos(z))) 874 | elif mode == 2 or mode == 3: # str or list 875 | if len(z) == 0: 876 | stack.append([]) 877 | else: 878 | current = None 879 | count = 0 880 | result = [] 881 | for i in z: 882 | if current != i: 883 | if current != None: 884 | result.append([count, current]) 885 | current = i 886 | count = 1 887 | else: 888 | count += 1 889 | stack.append(result) 890 | else: 891 | monadNotImplemented(mode, '') 892 | 893 | # ẹ 894 | def eLowDotOperator(stack, z, mode): 895 | if mode == 1: # num 896 | stack.append(utilities.formatNum(math.acos(z))) 897 | #elif mode == 2: 898 | elif mode == 3: # str or list 899 | if len(z) == 0: 900 | stack.append([]) 901 | else: 902 | result = "" 903 | for i in z: 904 | i = utilities.castToList(i) 905 | if len(i) >= 2: 906 | if type(i[1]) == str and type(result) == str: 907 | result += (i[1] * utilities.castToNumber(i[0])) 908 | else: 909 | result = list(result) 910 | result += [i[1]] * utilities.castToNumber(i[0]) 911 | stack.append(result) 912 | else: 913 | monadNotImplemented(mode, '') 914 | 915 | # ḟ 916 | def fHighDotOperator(stack, z, mode): 917 | if mode == 1: # num 918 | def subfactorial(n): 919 | soFar = [1, 0] 920 | if n < 0: 921 | raise ValueError("can't comput subfactorial of negative number") 922 | if n < 2: 923 | return soFar[n] 924 | 925 | i = 2 926 | while i <= n: 927 | soFar.append((i-1)*(soFar[i-1]+soFar[i-2])) 928 | i += 1 929 | 930 | return soFar[-1] 931 | 932 | stack.append(subfactorial(int(z))) 933 | elif mode == 2: # str 934 | stack.append([''.join(p) for p in itertools.permutations(z) if all(''.join(p)[i] != z[i] for i in range(len(z)))]) 935 | elif mode == 3: # list 936 | stack.append([list(p) for p in itertools.permutations(z) if all(list(p)[i] != z[i] for i in range(len(z)))]) 937 | else: 938 | monadNotImplemented(mode, '') 939 | 940 | # ḣ 941 | def hHighDotOperator(stack, z, mode): 942 | if mode == 1: # num 943 | stack.append(utilities.formatNum(z*2)) 944 | elif mode == 2: # str 945 | stack.append(z[:-1] if z else "") 946 | elif mode == 3: # list 947 | stack.append(z[:-1] if z else []) 948 | else: 949 | monadNotImplemented(mode, '') 950 | 951 | # ḥ 952 | def hLowDotOperator(stack, z, mode): 953 | if mode == 1: # num 954 | stack.append(utilities.formatNum(z/2)) 955 | elif mode == 2: # str 956 | stack.append(z[1:] if z else "") 957 | elif mode == 3: # list 958 | stack.append(z[1:] if z else []) 959 | else: 960 | monadNotImplemented(mode, '') 961 | 962 | # ṁ 963 | def mHighDotOperator(stack, z, mode): 964 | if mode == 1: # num 965 | z = int(z) 966 | stack.append(stack.pop(len(stack)-((z-1)%len(stack))-1)) 967 | #elif mode == 2: # str 968 | elif mode == 3: # list 969 | if z==[]: 970 | stack.append([]) 971 | else: 972 | m = max(z) 973 | stack.append([i for i in z if i==m]) 974 | else: 975 | monadNotImplemented(mode, '') 976 | 977 | # ṃ 978 | def mLowDotOperator(stack, z, mode): 979 | if mode == 1: # num 980 | z = int(z) 981 | stack.append(stack[len(stack)-((z-1)%len(stack))-1]) 982 | #elif mode == 2: # str 983 | elif mode == 3: # list 984 | if z==[]: 985 | stack.append([]) 986 | else: 987 | m = min(z) 988 | stack.append([i for i in z if i==m]) 989 | else: 990 | monadNotImplemented(mode, '') 991 | 992 | # ṅ 993 | def nHighDotOperator(stack, z, mode): 994 | if mode == 1: # num 995 | if (z > 0): 996 | stack.append(utilities.getPrimes(int(z))) 997 | else: 998 | stack.append([]) 999 | elif mode == 2: # str 1000 | if len(z) > 0: 1001 | stack.append(z[:-1]) 1002 | stack.append(z[-1]) 1003 | elif mode == 3: # list 1004 | if len(z) > 0: 1005 | stack.append(z[:-1]) 1006 | stack.append(z[-1]) 1007 | else: 1008 | monadNotImplemented(mode, '') 1009 | 1010 | # ṇ 1011 | def nLowDotOperator(stack, z, mode): 1012 | if mode == 1: # num 1013 | if (z > 0): 1014 | stack.append(utilities.getPrime(int(z))) 1015 | elif mode == 2: # str 1016 | if len(z) > 0: 1017 | stack.append(z[1:]) 1018 | stack.append(z[0]) 1019 | elif mode == 3: # list 1020 | if len(z) > 0: 1021 | stack.append(z[1:]) 1022 | stack.append(z[0]) 1023 | else: 1024 | monadNotImplemented(mode, '') 1025 | 1026 | # ȯ 1027 | def oHighDotOperator(stack, z, mode): 1028 | if mode == 1: # num 1029 | stack.append(abs(z)) 1030 | elif mode == 2: # str 1031 | stack.append(''.join(sorted(z))) 1032 | elif mode == 3: # list 1033 | stack.append(sorted(z)) 1034 | else: 1035 | monadNotImplemented(mode, '') 1036 | 1037 | # ọ 1038 | def oLowDotOperator(stack, z, mode): 1039 | if mode == 1: # num 1040 | stack.append(-1 if z < 0 else (1 if z > 0 else 0)) 1041 | elif mode == 2: # str 1042 | stack.append(z.strip()) 1043 | elif mode == 3: # list 1044 | if len(z) <= 1: 1045 | stack.append([]) 1046 | else: 1047 | stack.append([z[i+1]-z[i] for i in range(len(z)-1)]) 1048 | else: 1049 | monadNotImplemented(mode, '') 1050 | 1051 | # ṗ 1052 | def pHighDotOperator(stack, z, mode): 1053 | if mode == 1: # num 1054 | z = int(z) 1055 | if z < 2: 1056 | stack.append(0) 1057 | else: 1058 | while utilities.getPrime(-1) < z: 1059 | utilities.generatePrime() 1060 | stack.append(1 if z in utilities.getPrimes(-1) else 0) 1061 | #elif mode == 2: # str 1062 | #elif mode == 3: # list 1063 | else: 1064 | monadNotImplemented(mode, '') 1065 | 1066 | # ṙ 1067 | def rHighDotOperator(stack, z, mode): 1068 | # TODO this isn't quite right because of the weird issue with the quote characters 1069 | if mode == 1: # num 1070 | stack.append(str(z)) 1071 | elif mode == 2: # str 1072 | stack.append('“'+re.sub('[\\\\“”‘’„‟]', '\\\\\g<0>', z)+'”') # TODO this should be used for the output format... 1073 | elif mode == 3: # list 1074 | stack.append(utilities.outputFormat(z)) 1075 | else: 1076 | monadNotImplemented(mode, '') 1077 | 1078 | # ṛ 1079 | def rLowDotOperator(stack, z, mode): 1080 | random.seed() 1081 | if mode == 1: # num 1082 | stack.append(random.randint(1, int(z)+1)) 1083 | elif mode == 2: # str 1084 | stack.append(random.choice(z)) 1085 | elif mode == 3: # list 1086 | stack.append(random.choice(z)) 1087 | else: 1088 | monadNotImplemented(mode, '') 1089 | 1090 | # ṡ 1091 | def sHighDotOperator(stack, z, mode): 1092 | if mode == 1: # num 1093 | stack.append(utilities.formatNum(math.sin(z))) 1094 | elif mode == 2: # str 1095 | stack.append(z.split(' ')) 1096 | elif mode == 3: # list 1097 | stack.append(' '.join(map(utilities.castToString, z))) 1098 | else: 1099 | monadNotImplemented(mode, '') 1100 | 1101 | # ṣ 1102 | def sLowDotOperator(stack, z, mode): 1103 | if mode == 1: # num 1104 | stack.append(utilities.formatNum(math.asin(z))) 1105 | elif mode == 2: # str 1106 | stack.append(z.split('\n')) 1107 | elif mode == 3: # list 1108 | stack.append('\n'.join(map(utilities.castToString, z))) 1109 | else: 1110 | monadNotImplemented(mode, '') 1111 | 1112 | # ṫ 1113 | def tHighDotOperator(stack, z, mode): 1114 | if mode == 1: # num 1115 | stack.append(utilities.formatNum(math.tan(z))) 1116 | elif mode == 2: # str 1117 | if z == "": 1118 | stack.append("") 1119 | else: 1120 | stack.append(z + z[-2::-1]) 1121 | elif mode == 3: # list 1122 | if z == []: 1123 | stack.append([]) 1124 | else: 1125 | stack.append(z + z[-2::-1]) 1126 | else: 1127 | monadNotImplemented(mode, '') 1128 | 1129 | # ṭ 1130 | def tLowDotOperator(stack, z, mode): 1131 | if mode == 1: # num 1132 | stack.append(utilities.formatNum(math.atan(z))) 1133 | elif mode == 2 or mode == 3: # str or list 1134 | stack.append(1 if z[::-1]==z else 0) 1135 | else: 1136 | monadNotImplemented(mode, '') 1137 | 1138 | # ụ 1139 | def uLowDotOperator(stack, z, mode): 1140 | if mode == 1: # num 1141 | if z >= 0: 1142 | stack.append(1 if int(math.sqrt(z)) == math.sqrt(z) else 0) 1143 | else: 1144 | stack.append(0) 1145 | elif mode == 2: # str 1146 | stack.append([s.split() for s in z.split('\n')]) 1147 | elif mode == 3: # list 1148 | stack.append('\n'.join(' '.join(utilities.castToString(w) for w in s) if type(s)==list else utilities.castToString(s) for s in z)) 1149 | else: 1150 | monadNotImplemented(mode, '') 1151 | 1152 | # ẋ 1153 | def xHighDotOperator(stack, z, mode): 1154 | if mode == 1: # num 1155 | stack.append(utilities.formatNum(1/z)) 1156 | elif mode == 2: # str 1157 | result = [] 1158 | 1159 | currentRun = None 1160 | start = 0 1161 | for i in range(len(z)): 1162 | if currentRun == None: 1163 | currentRun = z[i] 1164 | if z[i] != currentRun: 1165 | currentRun = z[i] 1166 | result.append(z[start:i]) 1167 | start = i 1168 | result.append(z[start:]) 1169 | stack.append(result) 1170 | elif mode == 3: # list 1171 | result = [] 1172 | 1173 | currentRun = None 1174 | start = 0 1175 | for i in range(len(z)): 1176 | if currentRun == None: 1177 | currentRun = z[i] 1178 | if z[i] != currentRun: 1179 | currentRun = z[i] 1180 | result.append(z[start:i]) 1181 | start = i 1182 | result.append(z[start:]) 1183 | stack.append(result) 1184 | else: 1185 | monadNotImplemented(mode, '') 1186 | 1187 | # ẏ 1188 | def yHighDotOperator(stack, z, mode): 1189 | if mode == 1: # num 1190 | stack.append(1 if z > 0 else 0) 1191 | elif mode == 2: # str 1192 | stack.append(1 if all(c in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' for c in z) else 0) 1193 | elif mode == 3: # list 1194 | stack.append(1 if all(z) else 0) 1195 | else: 1196 | monadNotImplemented(mode, '') 1197 | 1198 | # ỵ 1199 | def yLowDotOperator(stack, z, mode): 1200 | if mode == 1: # num 1201 | stack.append(1 if z < 0 else 0) 1202 | elif mode == 2: # str 1203 | stack.append(1 if all(c in 'abcdefghijklmnopqrstuvwxyz' for c in z) else 0) 1204 | elif mode == 3: # list 1205 | stack.append(1 if all(not i for i in z) else 0) 1206 | else: 1207 | monadNotImplemented(mode, '') 1208 | 1209 | # z 1210 | def zOperator(stack, z, mode): 1211 | if mode == 1: # num 1212 | stack.append(utilities.formatNum(2**z)) 1213 | #elif mode == 2: # str 1214 | elif mode == 3: # list 1215 | p=lambda s:[s[:1]+t for t in p(s[1:])]+p(s[1:])if s else [s] 1216 | stack.append(p(z)) 1217 | else: 1218 | monadNotImplemented(mode, '') 1219 | 1220 | #-- Extended Monads -- # 1221 | 1222 | # €[ 1223 | def extLeftBracketOperator(stack, z, mode): 1224 | if mode == 1: # num 1225 | 1#stack.append() 1226 | #elif mode == 2: # str 1227 | elif mode == 3: # list 1228 | z = [re.sub("^\s*([\s\S]*?)\s*$", "\g<1>", utilities.castToString(i)) for i in z] 1229 | maxLength = max(len(i) for i in z) 1230 | 1231 | result = [i+(maxLength-len(i))*' ' for i in z] 1232 | stack.append(result) 1233 | else: 1234 | monadNotImplemented(mode, '') 1235 | 1236 | # €| 1237 | def extPipeOperator(stack, z, mode): 1238 | if mode == 1: # num 1239 | 1#stack.append() 1240 | #elif mode == 2: # str 1241 | elif mode == 3: # list 1242 | z = [re.sub("^\s*([\s\S]*?)\s*$", "\g<1>", utilities.castToString(i)) for i in z] 1243 | maxLength = max(len(i) for i in z) 1244 | 1245 | result = [(math.ceil((maxLength-len(i))/2)*' ')+i+(math.floor((maxLength-len(i))/2)*' ') for i in z] 1246 | stack.append(result) 1247 | else: 1248 | monadNotImplemented(mode, '') 1249 | 1250 | # €] 1251 | def extRightBracketOperator(stack, z, mode): 1252 | if mode == 1: # num 1253 | 1#stack.append() 1254 | #elif mode == 2: # str 1255 | elif mode == 3: # list 1256 | z = [re.sub("^\s*([\s\S]*?)\s*$", "\g<1>", utilities.castToString(i)) for i in z] 1257 | maxLength = max(len(i) for i in z) 1258 | 1259 | result = [(maxLength-len(i))*' '+i for i in z] 1260 | stack.append(result) 1261 | else: 1262 | monadNotImplemented(mode, '') 1263 | 1264 | ''' DYADS ''' 1265 | 1266 | # % 1267 | def percentOperator(stack, x, y, mode): 1268 | if mode == 1: # num, num 1269 | stack.append(utilities.formatNum(x % y)) 1270 | elif mode == 2: # num, str 1271 | stack.append(y[::int(x)]) 1272 | elif mode == 3: # num, list 1273 | stack.append(y[::int(x)]) 1274 | elif mode == 4: # str, num 1275 | stack.append(x[::int(y)]) 1276 | elif mode == 5: # str, str 1277 | s = x.split(y) 1278 | result = [] 1279 | for i in s[:-1]: 1280 | result += [i, y] 1281 | result .append(s[-1]) 1282 | stack.append(result) 1283 | elif mode == 6 or mode == 8: # str, list; list, str 1284 | s = x if mode == 6 else y 1285 | l = y if mode == 6 else x 1286 | 1287 | result = [] 1288 | start = 0 1289 | 1290 | for i in range(len(l)): 1291 | if l[i] == s: 1292 | result.append(l[start:i]) 1293 | result.append([s]) 1294 | start = i+1 1295 | result.append(l[start:]) 1296 | 1297 | stack.append(result) 1298 | elif mode == 7: # list, num 1299 | stack.append(x[::int(y)]) 1300 | elif mode == 9: # list, list 1301 | result = [] 1302 | i=0 1303 | while i 0: # any types 1404 | stack.append([x, y]) 1405 | else: 1406 | dyadNotImplemented(mode, '') 1407 | 1408 | # / 1409 | def slashOperator(stack, x, y, mode): 1410 | if mode == 1: # num, num 1411 | stack.append(utilities.formatNum(x // y)) 1412 | elif mode == 2: # num, str 1413 | if x <= 0: 1414 | raise ValueError("invalid size for splitting: "+str(int(x))) 1415 | stack.append([y[i:i+int(x)] for i in range(0, len(y), int(x))]) 1416 | elif mode == 3: # num, list 1417 | if x <= 0: 1418 | raise ValueError("invalid size for splitting: "+str(int(x))) 1419 | stack.append([y[i:i+int(x)] for i in range(0, len(y), int(x))]) 1420 | elif mode == 4: # str, num 1421 | if y <= 0: 1422 | raise ValueError("invalid size for splitting: "+str(int(y))) 1423 | stack.append([x[i:i+int(y)] for i in range(0, len(x), int(y))]) 1424 | elif mode == 5: # str, str 1425 | result = x.split(y) 1426 | while "" in result: 1427 | result.remove("") 1428 | stack.append(result) 1429 | elif mode == 6 or mode == 8: # str, list; list, str 1430 | l = y if mode == 6 else x 1431 | s = x if mode == 6 else y 1432 | 1433 | result = [] 1434 | i=0 1435 | while i 0: # Don't append an empty list 1438 | result.append(l[:i]) 1439 | l = l[i+1:] 1440 | i = 0 1441 | else: 1442 | i += 1 1443 | 1444 | result.append(l) 1445 | stack.append(result) 1446 | 1447 | elif mode == 7: # list, num 1448 | if y <= 0: 1449 | raise ValueError("invalid size for splitting: "+str(int(y))) 1450 | stack.append([x[i:i+int(y)] for i in range(0, len(x), int(y))]) 1451 | elif mode == 9: # list, list 1452 | result = [] 1453 | i=0 1454 | while i 0: # Don't append an empty list 1457 | result.append(x[:i]) 1458 | x = x[i+len(y):] 1459 | i = 0 1460 | else: 1461 | i += 1 1462 | 1463 | result.append(x) 1464 | stack.append(result) 1465 | else: 1466 | dyadNotImplemented(mode, '') 1467 | 1468 | # ; 1469 | def semicolonOperator(stack, x, y, mode): 1470 | if mode > 0: # any types 1471 | stack.append(x) 1472 | stack.append(y) 1473 | stack.append(x) 1474 | else: 1475 | dyadNotImplemented(mode, '') 1476 | 1477 | # < 1478 | def lessThanOperator(stack, x, y, mode): 1479 | if mode == 1: # num, num 1480 | stack.append(1 if x < y else 0) 1481 | elif mode == 2: # num, str 1482 | stack.append(y[:x]) 1483 | elif mode == 3: # num, list 1484 | stack.append(y[:x]) 1485 | elif mode == 4: # str, num 1486 | stack.append(x[:y]) 1487 | elif mode == 5: # str, str 1488 | stack.append(1 if x < y else 0) 1489 | #elif mode == 6: # str, list 1490 | elif mode == 7: # list, num 1491 | stack.append(x[:y]) 1492 | #elif mode == 8: # list, str 1493 | elif mode == 9: # list, list 1494 | stack.append(1 if x < y else 0) 1495 | else: 1496 | dyadNotImplemented(mode, '') 1497 | 1498 | # = 1499 | def equalsOperator(stack, x, y, mode): 1500 | if mode == 1: # num, num 1501 | stack.append(1 if x == y else 0) 1502 | elif mode == 2: # num, str 1503 | stack.append(y[(int(x)-1)%len(y)]) 1504 | elif mode == 3: # num, list 1505 | stack.append(y[(int(x)-1)%len(y)]) 1506 | elif mode == 4: # str, num 1507 | stack.append(x[(int(y)-1)%len(x)]) 1508 | elif mode == 5: # str, str 1509 | stack.append(1 if x == y else 0) 1510 | #elif mode == 6: # str, list 1511 | elif mode == 7: # list, num 1512 | stack.append(x[(int(y)-1)%len(x)]) 1513 | #elif mode == 8: # list, str 1514 | elif mode == 9: # list, list 1515 | stack.append(1 if x == y else 0) 1516 | else: 1517 | dyadNotImplemented(mode, '') 1518 | 1519 | # > 1520 | def greaterThanOperator(stack, x, y, mode): 1521 | if mode == 1: # num, num 1522 | stack.append(1 if x > y else 0) 1523 | elif mode == 2: # num, str 1524 | stack.append(y[x:]) 1525 | elif mode == 3: # num, list 1526 | stack.append(y[x:]) 1527 | elif mode == 4: # str, num 1528 | stack.append(x[y:]) 1529 | elif mode == 5: # str, str 1530 | stack.append(1 if x > y else 0) 1531 | #elif mode == 6: # str, list 1532 | elif mode == 7: # list, num 1533 | stack.append(x[y:]) 1534 | #elif mode == 8: # list, str 1535 | elif mode == 9: # list, list 1536 | stack.append(1 if x > y else 0) 1537 | else: 1538 | dyadNotImplemented(mode, '') 1539 | 1540 | # ^ 1541 | def caretOperator(stack, x, y, mode): 1542 | if mode == 1: # num, num 1543 | stack.append(int(x) ^ int(y)) 1544 | #elif mode == 2: # num, str 1545 | #elif mode == 3: # num, list 1546 | #elif mode == 4: # str, num 1547 | elif mode == 5: # str, str 1548 | result = "" 1549 | 1550 | for c in x: 1551 | if c not in y and c not in result: 1552 | result += c 1553 | 1554 | for c in y: 1555 | if c not in x and c not in result: 1556 | result += c 1557 | 1558 | stack.append(result) 1559 | #elif mode == 6: # str, list 1560 | #elif mode == 7: # list, num 1561 | #elif mode == 8: # list, str 1562 | elif mode == 9: # list, list 1563 | result = [] 1564 | 1565 | for i in x: 1566 | if i not in y and i not in result: 1567 | result.append(i) 1568 | 1569 | for i in y: 1570 | if i not in x and i not in result: 1571 | result.append(i) 1572 | 1573 | stack.append(result) 1574 | else: 1575 | dyadNotImplemented(mode, '') 1576 | 1577 | # | 1578 | def pipeOperator(stack, x, y, mode): 1579 | if mode == 1: # num, num 1580 | stack.append(int(x) | int(y)) 1581 | #elif mode == 2: # num, str 1582 | #elif mode == 3: # num, list 1583 | #elif mode == 4: # str, num 1584 | elif mode == 5: # str, str 1585 | result = "" 1586 | for c in x+y: 1587 | if c not in result: 1588 | result += c 1589 | stack.append(result) 1590 | #elif mode == 6: # str, list 1591 | #elif mode == 7: # list, num 1592 | #elif mode == 8: # list, str 1593 | elif mode == 9: # list, list 1594 | result = [] 1595 | for i in x+y: 1596 | if i not in result: 1597 | result.append(i) 1598 | stack.append(result) 1599 | else: 1600 | dyadNotImplemented(mode, '') 1601 | 1602 | # « 1603 | def leftArrowQuoteOperator(stack, x, y, mode): 1604 | if mode == 1: # num, num 1605 | stack.append(int(x) << int(y)) 1606 | elif mode == 2: # num, str 1607 | stack.append(y[int(x):]+y[:int(x)]) 1608 | elif mode == 3: # num, list 1609 | stack.append(y[int(x):]+y[:int(x)]) 1610 | elif mode == 4: # str, num 1611 | stack.append(x[int(y):]+x[:int(y)]) 1612 | elif mode == 5: # str, str 1613 | stack.append(1 if (x[:len(y)] == y) else 0) 1614 | #elif mode == 6: # str, list 1615 | elif mode == 7: # list, num 1616 | stack.append(x[int(y):]+x[:int(y)]) 1617 | #elif mode == 8: # list, str 1618 | elif mode == 9: # list, list 1619 | stack.append(1 if (x[:len(y)] == y) else 0) 1620 | else: 1621 | dyadNotImplemented(mode, '') 1622 | 1623 | # » 1624 | def rightArrowQuoteOperator(stack, x, y, mode): 1625 | if mode == 1: # num, num 1626 | stack.append(int(x) >> int(y)) 1627 | elif mode == 2: # num, str 1628 | stack.append(y[-int(x):]+y[:-int(x)]) 1629 | elif mode == 3: # num, list 1630 | stack.append(y[-int(x):]+y[:-int(x)]) 1631 | elif mode == 4: # str, num 1632 | stack.append(x[-int(y):]+x[:-int(y)]) 1633 | elif mode == 5: # str, str 1634 | stack.append(1 if (x[-len(y):] == y) else 0) 1635 | #elif mode == 6: # str, list 1636 | elif mode == 7: # list, num 1637 | stack.append(x[-int(y):]+x[:-int(y)]) 1638 | #elif mode == 8: # list, str 1639 | elif mode == 9: # list, list 1640 | stack.append(1 if (x[-len(y):] == y) else 0) 1641 | else: 1642 | dyadNotImplemented(mode, '') 1643 | 1644 | # ⊂ 1645 | def subsetOperator(stack, x, y, mode): 1646 | if mode == 1: # num, num 1647 | stack.append(1 if x <= y else 0) 1648 | elif mode == 2 or mode == 4: # num, str; str, num 1649 | s = y if mode == 2 else x 1650 | n = int(x if mode == 2 else y) 1651 | 1652 | char = s[0] if len(s)>0 else ' ' 1653 | while len(s) < n: 1654 | s = char+s 1655 | 1656 | stack.append(s) 1657 | elif mode == 3 or mode == 7: # num, list 1658 | l = y if mode == 3 else x 1659 | n = int(x if mode == 3 else y) 1660 | 1661 | ele = l[0] if len(l)>0 else 0 1662 | while len(l) < n: 1663 | l = [ele]+l 1664 | 1665 | stack.append(l) 1666 | elif mode == 5: # str, str 1667 | stack.append(1 if all(i in y for i in x) else 0) 1668 | #elif mode == 6: # str, list 1669 | #elif mode == 8: # list, str 1670 | elif mode == 9: # list, list 1671 | stack.append(1 if all(i in y for i in x) else 0) 1672 | else: 1673 | dyadNotImplemented(mode, '') 1674 | 1675 | # ⊃ 1676 | def supersetOperator(stack, x, y, mode): 1677 | if mode == 1: # num, num 1678 | stack.append(1 if x >= y else 0) 1679 | elif mode == 2 or mode == 4: # num, str; str, num 1680 | s = y if mode == 2 else x 1681 | n = int(x if mode == 2 else y) 1682 | 1683 | char = s[-1] if len(s)>0 else ' ' 1684 | while len(s) < n: 1685 | s = s+char 1686 | 1687 | stack.append(s) 1688 | elif mode == 3 or mode == 7: # num, list 1689 | l = y if mode == 3 else x 1690 | n = int(x if mode == 3 else y) 1691 | 1692 | ele = l[-1] if len(l)>0 else 0 1693 | while len(l) < n: 1694 | l = l+[ele] 1695 | 1696 | stack.append(l) 1697 | elif mode == 5: # str, str 1698 | stack.append(1 if all(i in x for i in y) else 0) 1699 | #elif mode == 6: # str, list 1700 | #elif mode == 8: # list, str 1701 | elif mode == 9: # list, list 1702 | stack.append(1 if all(i in x for i in y) else 0) 1703 | else: 1704 | dyadNotImplemented(mode, '') 1705 | 1706 | # ∧ 1707 | def andOperator(stack, x, y, mode): 1708 | if mode > 0: # Same for any types... 1709 | stack.append(x and y) 1710 | else: 1711 | dyadNotImplemented(mode, '') 1712 | 1713 | # ∨ 1714 | def orOperator(stack, x, y, mode): 1715 | if mode > 0: # Same for any types... 1716 | stack.append(x or y) 1717 | else: 1718 | dyadNotImplemented(mode, '') 1719 | 1720 | # × 1721 | def timesOperator(stack, x, y, mode): 1722 | if mode == 1: # num, num 1723 | stack.append(utilities.formatNum(x * y)) 1724 | elif mode == 2: # num, str 1725 | result = abs(int(x)) * y 1726 | stack.append(result[::-1] if x < 0 else result) 1727 | elif mode == 3: # num, list 1728 | result = abs(int(x)) * y 1729 | stack.append(result[::-1] if x < 0 else result) 1730 | elif mode == 4: # str, num 1731 | result = abs(int(y)) * x 1732 | stack.append(result[::-1] if y < 0 else result) 1733 | elif mode == 5: # str, str 1734 | stack.append([i+j for i in x for j in y]) 1735 | elif mode == 6: # str, list 1736 | stack.append(x.join(map(str, y))) 1737 | elif mode == 7: # list, num 1738 | result = abs(int(y)) * x 1739 | stack.append(result[::-1] if y < 0 else result) 1740 | elif mode == 8: # list, str 1741 | stack.append(y.join(map(str, x))) # TODO this is weird when the list has sublists 1742 | elif mode == 9: # list, list 1743 | stack.append([[i, j] for i in x for j in y]) 1744 | else: 1745 | dyadNotImplemented(mode, '×') 1746 | 1747 | # ÷ 1748 | def divisionOperator(stack, x, y, mode): 1749 | if mode == 1: # num, num 1750 | stack.append(utilities.formatNum(x / y)) 1751 | elif mode == 2 or mode == 3 or mode == 4 or mode == 7: # num, str (2) or str, num (4) or num, list (3) or list, num (7) 1752 | n = x if mode == 2 or mode == 3 else y 1753 | s = y if mode == 2 or mode == 3 else x 1754 | 1755 | n = int(n) # Takes an integer specifically as argument 1756 | if n > len(s) or n < 1: 1757 | raise ValueError(str(n)+" is not a valid number of splits for "+utilities.outputFormat(s)+" (length "+str(len(s))+")") 1758 | 1759 | cuts = [0]*n 1760 | result = [] 1761 | 1762 | for i in range(len(s)): 1763 | cuts[i%n] += 1 1764 | 1765 | for cut in cuts: 1766 | result.append(s[:cut]) 1767 | s = s[cut:] 1768 | 1769 | stack.append(result) 1770 | elif mode == 5: # str, str 1771 | stack.append(x.split(y)) 1772 | elif mode == 6 or mode == 8: # str, list; list, str 1773 | l = y if mode == 6 else x 1774 | s = x if mode == 6 else y 1775 | 1776 | result = [] 1777 | i=0 1778 | while i y else 0)) 1885 | elif mode == 2 or mode == 4: # num, str; str, num 1886 | n = str(x if mode == 2 else y) 1887 | s = y if mode == 2 else x 1888 | 1889 | stack.append(s.count(n)) 1890 | elif mode == 3: # num, list 1891 | stack.append(y.count(x)) 1892 | elif mode == 5: # str, str 1893 | stack.append(x.count(y)) 1894 | elif mode == 6: # str, list 1895 | stack.append(y.count(x)) 1896 | elif mode == 7: # list, num 1897 | stack.append(x.count(y)) 1898 | elif mode == 8: # list, str 1899 | stack.append(x.count(y)) 1900 | elif mode == 9: # list, list 1901 | count = 0 1902 | i = 0 1903 | while i < len(x): 1904 | if x[i:i+len(y)] == y: 1905 | count += 1 1906 | i += len(y) 1907 | else: 1908 | i += 1 1909 | stack.append(count) 1910 | else: 1911 | dyadNotImplemented(mode, '') 1912 | 1913 | # D 1914 | def DOperator(stack, x, y, mode): 1915 | if mode == 1: # num, num 1916 | stack.append(abs(x-y)) 1917 | elif mode == 2 or mode == 4: # num, str; str num 1918 | n = x if mode == 2 else y 1919 | s = y if mode == 2 else x 1920 | 1921 | if s == "": 1922 | stack.append("") 1923 | else: 1924 | index = (int(n)-1)%len(s) 1925 | stack.append(s[:index]+s[index+1:]) 1926 | elif mode == 3 or mode == 7: # num, list; list, num 1927 | n = x if mode == 3 else y 1928 | l = y if mode == 3 else x 1929 | 1930 | if l == []: 1931 | stack.append([]) 1932 | else: 1933 | index = (int(n)-1)%len(l) 1934 | stack.append(l[:index]+l[index+1:]) 1935 | elif mode == 5 or mode == 9: # str, str; list, list 1936 | (x, y) = (list(x[:]), list(y[:])) 1937 | for i in y: 1938 | if i in x: 1939 | x.remove(i) 1940 | 1941 | if mode == 5: 1942 | x = ''.join(x) 1943 | stack.append(x) 1944 | #elif mode == 6: # str, list 1945 | #elif mode == 8: # list, str 1946 | else: 1947 | dyadNotImplemented(mode, '') 1948 | 1949 | # E 1950 | def EOperator(stack, x, y, mode): 1951 | if mode == 1: # num, num 1952 | stack.append(x * 10**y) 1953 | elif mode == 2 or mode == 4: # num, str; str, num 1954 | n = x if mode < 4 else y 1955 | s = list(y if mode < 4 else x) 1956 | 1957 | if len(s) == 0: 1958 | stack.append(s) 1959 | else: 1960 | index = (int(n)-1)%len(s) 1961 | 1962 | v = s.pop(index) 1963 | stack.append("".join(s)) 1964 | stack.append(v) 1965 | elif mode == 3 or mode == 7: # num, list; list, num 1966 | n = x if mode == 3 else y 1967 | l = y if mode == 3 else x 1968 | 1969 | if len(l) == 0: 1970 | stack.append(l) 1971 | else: 1972 | index = (int(n)-1)%len(l) 1973 | 1974 | v = l.pop(index) 1975 | stack.append(l) 1976 | stack.append(v) 1977 | #elif mode == 5: # str, str 1978 | #elif mode == 6: # str, list 1979 | #elif mode == 8: # list, str 1980 | elif mode == 9: # list, list 1981 | if x == []: 1982 | stack.append([]) 1983 | else: 1984 | x = x[:] # Deep copy x 1985 | indices = [(int(utilities.castToNumber(i))-1)%len(x) for i in y] 1986 | result = [] 1987 | 1988 | for i in indices: 1989 | result.append(x[i]) 1990 | x[i] = None 1991 | 1992 | while None in x: 1993 | x.remove(None) 1994 | 1995 | stack.append(x) 1996 | stack.append(result) 1997 | else: 1998 | dyadNotImplemented(mode, '') 1999 | 2000 | # Ė 2001 | def EHighDotOperator(stack, x, y, mode): 2002 | if mode == 1: # num, num 2003 | stack.append(1 if (x==0 and y==0) or (x % y == 0) else 0) 2004 | elif mode == 2: # num, str 2005 | x = str(x) 2006 | stack.append(1 if x in y else 0) 2007 | elif mode == 3: # num, list 2008 | stack.append(1 if x in y else 0) 2009 | elif mode == 4: # str, num 2010 | y = str(y) 2011 | stack.append(1 if y in x else 0) 2012 | elif mode == 5: # str, str 2013 | stack.append(1 if y in x else 0) 2014 | elif mode == 6: # str, list 2015 | stack.append(1 if x in y else 0) 2016 | elif mode == 7: # list, num 2017 | stack.append(1 if y in x else 0) 2018 | elif mode == 8: # list, str 2019 | stack.append(1 if y in x else 0) 2020 | elif mode == 9: # list, list 2021 | stack.append(1 if y in x else 0) 2022 | else: 2023 | dyadNotImplemented(mode, '') 2024 | 2025 | # I 2026 | def IOperator(stack, x, y, mode): 2027 | if mode == 1: # num, num 2028 | stack.append(round(x, y)) 2029 | elif mode == 2: # num, str 2030 | x = str(x) 2031 | stack.append(y.index(x)+1 if x in y else 0) 2032 | elif mode == 3: # num, list 2033 | stack.append(y.index(x)+1 if x in y else 0) 2034 | elif mode == 4: # str, num 2035 | y = str(y) 2036 | stack.append(x.index(y)+1 if y in x else 0) 2037 | elif mode == 5: # str, str 2038 | stack.append(x.find(y)+1) 2039 | elif mode == 6: # str, list 2040 | stack.append(y.index(x)+1 if x in y else 0) 2041 | elif mode == 7: # list, num 2042 | stack.append(x.index(y)+1 if y in x else 0) 2043 | elif mode == 8: # list, str 2044 | stack.append(x.index(y)+1 if y in x else 0) 2045 | elif mode == 9: # list, list 2046 | if len(y)>len(x): 2047 | stack.append(0) 2048 | else: 2049 | for i in range(len(x)): 2050 | if x[i:i+len(y)]==y: 2051 | stack.append(i+1) 2052 | return 2053 | stack.append(0) 2054 | else: 2055 | dyadNotImplemented(mode, '') 2056 | 2057 | # K 2058 | def KOperator(stack, x, y, mode): 2059 | if mode == 1: # num, num 2060 | n = int(x) 2061 | k = int(y) 2062 | if k < 0 or k > n: 2063 | stack.append(0) 2064 | else: 2065 | stack.append(math.factorial(n)/(math.factorial(k)*math.factorial(n-k))) 2066 | #elif mode == 2: # num, str 2067 | elif mode == 3 or mode == 7: # num, list 2068 | n = int(x if mode == 3 else y) 2069 | l = y if mode == 3 else x 2070 | 2071 | def subsets(l, n): 2072 | if n > len(l) or n < 0: 2073 | return [] 2074 | elif n == len(l): 2075 | return [l] 2076 | elif n == 0: 2077 | return [[]] 2078 | elif n == 1: 2079 | return [[i] for i in l] 2080 | else: 2081 | result = [] 2082 | for i in range(len(l)-n+1): 2083 | result += [[l[i]] + s for s in subsets(l[i+1:], n-1)] 2084 | return result 2085 | 2086 | stack.append(subsets(l, n)) 2087 | #elif mode == 4: # str, num 2088 | elif mode == 5: # str, str 2089 | stack.append(''.join(c for c in x if c in y)) 2090 | #elif mode == 6: # str, list 2091 | #elif mode == 8: # list, str 2092 | elif mode == 9: # list, list 2093 | stack.append([i for i in x if i in y]) 2094 | else: 2095 | dyadNotImplemented(mode, '') 2096 | 2097 | # Ṁ 2098 | def MHighDotOperator(stack, x, y, mode): 2099 | if mode == 1: # num, num 2100 | stack.append(max(x,y)) 2101 | #elif mode == 2: # num, str 2102 | elif mode == 3 or mode == 7: # num, list; list, num 2103 | n = x if mode == 3 else y 2104 | l = y if mode == 3 else x 2105 | 2106 | n = int(n)%4 2107 | l = [i if type(i) == list else [i] for i in l] 2108 | 2109 | for i in range(n): 2110 | width = max(len(i) for i in l) 2111 | l = [[e[j] for e in l[::-1] if len(e)>j] for j in range(width)] 2112 | 2113 | stack.append(l) 2114 | #elif mode == 4: # str, num 2115 | elif mode == 5: # str, str 2116 | stack.append(max(x,y)) 2117 | #elif mode == 6: # str, list 2118 | #elif mode == 8: # list, str 2119 | elif mode == 9: # list, list 2120 | stack.append(max(x,y)) 2121 | else: 2122 | dyadNotImplemented(mode, '') 2123 | 2124 | # Ṃ 2125 | def MLowDotOperator(stack, x, y, mode): 2126 | if mode == 1: # num, num 2127 | stack.append(min(x,y)) 2128 | #elif mode == 2: # num, str 2129 | elif mode == 3 or mode == 7: # num, list; list, num 2130 | n = x if mode == 3 else y 2131 | l = y if mode == 3 else x 2132 | 2133 | n = int(n)%4 2134 | l = [i if type(i) == list else [i] for i in l] 2135 | 2136 | for i in range(n): 2137 | width = max(len(i) for i in l) 2138 | l = [[e[j] for e in l if len(e)>j] for j in range(width-1, -1, -1)] 2139 | 2140 | stack.append(l) 2141 | #elif mode == 4: # str, num 2142 | elif mode == 5: # str, str 2143 | stack.append(min(x,y)) 2144 | #elif mode == 6: # str, list 2145 | #elif mode == 8: # list, str 2146 | elif mode == 9: # list, list 2147 | stack.append(min(x,y)) 2148 | else: 2149 | dyadNotImplemented(mode, '') 2150 | 2151 | # N 2152 | def NOperator(stack, x, y, mode): 2153 | if mode == 1: # num, num 2154 | x = int(x) 2155 | y = int(y) 2156 | if x == y: 2157 | stack.append([]) 2158 | elif y < x: 2159 | stack.append(list(range(x, y, -1))) 2160 | else: 2161 | stack.append(list(range(x, y))) 2162 | #elif mode == 2: # num, str 2163 | #elif mode == 3: # num, list 2164 | #elif mode == 4: # str, num 2165 | elif mode == 5: # str, str 2166 | x = x[:] 2167 | y = list(y[:]) 2168 | 2169 | result = "" 2170 | 2171 | for i in x: 2172 | if i in y: 2173 | result += i 2174 | y.remove(i) 2175 | 2176 | stack.append(result) 2177 | #elif mode == 6: # str, list 2178 | #elif mode == 7: # list, num 2179 | #elif mode == 8: # list, str 2180 | elif mode == 9: # list, list 2181 | x = x[:] 2182 | y = y[:] 2183 | 2184 | result = [] 2185 | 2186 | for i in x: 2187 | if i in y: 2188 | result.append(i) 2189 | y.remove(i) 2190 | 2191 | stack.append(result) 2192 | else: 2193 | dyadNotImplemented(mode, '') 2194 | 2195 | # S 2196 | def SOperator(stack, x, y, mode): 2197 | if mode == 1: # num, num 2198 | (x,y) = (int(x), int(y)) 2199 | while y != 0: 2200 | (x,y) = (y,x%y) 2201 | stack.append(1 if x == 1 else 0) 2202 | elif mode == 2 or mode == 3: # num, str; num, list 2203 | stack.append([y[:int(x)], y[int(x):]]) 2204 | elif mode == 4 or mode == 7: # str, num; list, num 2205 | stack.append([x[:int(y)], x[int(y):]]) 2206 | elif mode == 6 or mode == 8: # str, list; list, str 2207 | l = x if mode == 8 else y 2208 | s = y if mode == 8 else x 2209 | 2210 | if s in l: 2211 | index = l.index(s) 2212 | stack.append([l[:index], l[index+1:]]) 2213 | else: 2214 | stack.append(l) 2215 | elif mode == 5: # str, str 2216 | s = x.split(y) 2217 | stack.append([s[0], y.join(s[1:])]) 2218 | elif mode == 9: # list, list 2219 | for i in range(len(x)): 2220 | if x[i:i+len(y)] == y: 2221 | stack.append([x[:i], x[i+len(y):]]) 2222 | return 2223 | stack.append(x) 2224 | else: 2225 | dyadNotImplemented(mode, '') 2226 | 2227 | # Ṡ 2228 | def SHighDotOperator(stack, x, y, mode): 2229 | if mode == 1: # num, num 2230 | stack.append(utilities.formatNum(x ** (1/y))) 2231 | elif mode == 2 or mode == 4 or mode == 3 or mode == 7: # num, str; str, num; num, list; list, num 2232 | n = int(x if mode == 2 or mode == 3 else y) 2233 | l = y if mode == 2 or mode == 3 else x 2234 | 2235 | stack.append([l[i:i+n] for i in range(len(l)-n+1)]) 2236 | elif mode == 5 or mode == 9: # str, str; list, list 2237 | result = [] 2238 | start = 0 2239 | 2240 | for i in range(len(x)): 2241 | if x[i] in y: 2242 | result.append(x[start:i]) 2243 | start = i+1 2244 | result.append(x[start:]) 2245 | stack.append(result) 2246 | #elif mode == 6: # str, list 2247 | #elif mode == 8: # list, str 2248 | else: 2249 | dyadNotImplemented(mode, '') 2250 | 2251 | # U 2252 | def UOperator(stack, x, y, mode): 2253 | if mode == 1: # num, num 2254 | x = int(x) 2255 | y = int(y) 2256 | if x == y: 2257 | stack.append([x]) 2258 | elif y < x: 2259 | stack.append(list(range(x, y-1, -1))) 2260 | else: 2261 | stack.append(list(range(x, y+1))) 2262 | #elif mode == 2: # num, str 2263 | #elif mode == 3: # num, list 2264 | #elif mode == 4: # str, num 2265 | elif mode == 5: # str, str 2266 | x = x[:] 2267 | y = list(y[:]) 2268 | 2269 | result = "" 2270 | 2271 | for i in x: 2272 | if i in y: 2273 | y.remove(i) 2274 | 2275 | stack.append(x + ''.join(y)) 2276 | #elif mode == 6: # str, list 2277 | #elif mode == 7: # list, num 2278 | #elif mode == 8: # list, str 2279 | elif mode == 9: # list, list 2280 | x = x[:] 2281 | y = y[:] 2282 | 2283 | for i in x: 2284 | if i in y: 2285 | y.remove(i) 2286 | 2287 | stack.append(x+y) 2288 | else: 2289 | dyadNotImplemented(mode, '') 2290 | 2291 | # Z 2292 | def ZOperator(stack, x, y, mode): 2293 | if mode == 1: # num, num 2294 | stack.append(utilities.formatNum(x // y)) 2295 | stack.append(utilities.formatNum(x % y)) 2296 | elif mode == 2: # num, str 2297 | result = [] 2298 | x = int(x) 2299 | if x < 1 or x > len(y): 2300 | raise ValueError("invalid size for unzipping: "+str(x)) 2301 | for i in range(x): 2302 | index = i 2303 | step = [] 2304 | while index < len(y): 2305 | step.append(y[index]) 2306 | index += x 2307 | result.append(''.join(step)) 2308 | stack.append(result) 2309 | elif mode == 3: # num, list 2310 | result = [] 2311 | x = int(x) 2312 | if x < 1 or x > len(y): 2313 | raise ValueError("invalid size for unzipping: "+str(x)) 2314 | for i in range(x): 2315 | index = i 2316 | step = [] 2317 | while index < len(y): 2318 | step.append(y[index]) 2319 | index += x 2320 | result.append(step) 2321 | stack.append(result) 2322 | elif mode == 4: # str, num 2323 | result = [] 2324 | y = int(y) 2325 | if y < 1 or y > len(x): 2326 | raise ValueError("invalid size for unzipping "+str(y)) 2327 | for i in range(y): 2328 | index = i 2329 | step = [] 2330 | while index < len(x): 2331 | step.append(x[index]) 2332 | index += y 2333 | result.append(''.join(step)) 2334 | stack.append(result) 2335 | elif mode == 5 or mode == 9: # str, str; list, list 2336 | result = [] 2337 | minlen = min(len(x), len(y)) 2338 | for i in range(minlen): 2339 | result.append(x[i]) 2340 | result.append(y[i]) 2341 | result += x[minlen:] + y[minlen:] 2342 | if mode == 5: 2343 | result = ''.join(result) 2344 | stack.append(result) 2345 | #elif mode == 6: # str, list 2346 | elif mode == 7: # list, num 2347 | result = [] 2348 | y = int(y) 2349 | if y < 1 or y > len(x): 2350 | raise ValueError("invalid size for unzipping "+str(y)) 2351 | for i in range(y): 2352 | index = i 2353 | step = [] 2354 | while index < len(x): 2355 | step.append(x[index]) 2356 | index += y 2357 | result.append(step) 2358 | stack.append(result) 2359 | #elif mode == 8: # list, str 2360 | else: 2361 | dyadNotImplemented(mode, '') 2362 | 2363 | # ¤ 2364 | def currencyOperator(stack, x, y, mode): 2365 | if mode > 0: # any types... 2366 | stack.append(y) 2367 | stack.append(x) 2368 | else: 2369 | dyadNotImplemented(mode, '') 2370 | 2371 | 2372 | #-- Extended Dyads -- # 2373 | 2374 | 2375 | 2376 | 2377 | 2378 | """ 2379 | Blank operator function, just easy to copy-paste 2380 | 2381 | 2382 | # 2383 | def ___Operator(stack, z, mode): 2384 | if mode == 1: # num 2385 | stack.append() 2386 | elif mode == 2: # str 2387 | stack.append() 2388 | elif mode == 3: # list 2389 | stack.append() 2390 | else: 2391 | monadNotImplemented(mode, '') 2392 | 2393 | 2394 | # 2395 | def ___Operator(stack, x, y, mode): 2396 | if mode == 1: # num, num 2397 | stack.append() 2398 | elif mode == 2: # num, str 2399 | stack.append() 2400 | elif mode == 3: # num, list 2401 | stack.append() 2402 | elif mode == 4: # str, num 2403 | stack.append() 2404 | elif mode == 5: # str, str 2405 | stack.append() 2406 | elif mode == 6: # str, list 2407 | stack.append() 2408 | elif mode == 7: # list, num 2409 | stack.append() 2410 | elif mode == 8: # list, str 2411 | stack.append() 2412 | elif mode == 9: # list, list 2413 | stack.append() 2414 | else: 2415 | dyadNotImplemented(mode, '') 2416 | 2417 | """ 2418 | 2419 | 2420 | 2421 | """ 2422 | OPS DICT 2423 | 2424 | Each value should be an Operator object 2425 | """ 2426 | 2427 | ops = { 2428 | # Nilads 2429 | '€.': Operator('€.', 0, extDotOperator), 2430 | '₵A': Operator('₵A', 0, constAOperator), 2431 | '₵a': Operator('₵a', 0, constaOperator), 2432 | '₵C': Operator('₵C', 0, constCOperator), 2433 | '₵c': Operator('₵c', 0, constcOperator), 2434 | '₵D': Operator('₵D', 0, constDOperator), 2435 | '₵E': Operator('₵E', 0, constEOperator), 2436 | '₵H': Operator('₵H', 0, constHOperator), 2437 | '₵h': Operator('₵h', 0, consthOperator), 2438 | '₵P': Operator('₵P', 0, constPOperator), 2439 | '₵Q': Operator('₵Q', 0, constQOperator), 2440 | '₵q': Operator('₵q', 0, constqOperator), 2441 | '₵R': Operator('₵R', 0, constROperator), 2442 | '₵r': Operator('₵r', 0, constrOperator), 2443 | '₵V': Operator('₵V', 0, constVOperator), 2444 | '₵v': Operator('₵v', 0, constvOperator), 2445 | '₵W': Operator('₵W', 0, constWOperator), 2446 | '₵X': Operator('₵X', 0, constXOperator), 2447 | '₵x': Operator('₵x', 0, constxOperator), 2448 | '₵Y': Operator('₵Y', 0, constYOperator), 2449 | '₵y': Operator('₵y', 0, constyOperator), 2450 | '∂A': Operator('∂A', 0, dateAOperator), 2451 | '∂a': Operator('∂a', 0, dateaOperator), 2452 | '∂D': Operator('∂D', 0, dateDOperator), 2453 | '∂d': Operator('∂d', 0, datedOperator), 2454 | '∂H': Operator('∂H', 0, dateHOperator), 2455 | '∂h': Operator('∂h', 0, datehOperator), 2456 | '∂I': Operator('∂I', 0, dateIOperator), 2457 | '∂i': Operator('∂i', 0, dateiOperator), 2458 | '∂K': Operator('∂K', 0, dateKOperator), 2459 | '∂k': Operator('∂k', 0, datekOperator), 2460 | '∂L': Operator('∂L', 0, dateLOperator), 2461 | '∂l': Operator('∂l', 0, datelOperator), 2462 | '∂M': Operator('∂M', 0, dateMOperator), 2463 | '∂m': Operator('∂m', 0, datemOperator), 2464 | '∂N': Operator('∂N', 0, dateNOperator), 2465 | '∂n': Operator('∂n', 0, datenOperator), 2466 | '∂O': Operator('∂O', 0, dateOOperator), 2467 | '∂o': Operator('∂o', 0, dateoOperator), 2468 | '∂Q': Operator('∂Q', 0, dateQOperator), 2469 | '∂q': Operator('∂q', 0, dateqOperator), 2470 | '∂S': Operator('∂S', 0, dateSOperator), 2471 | '∂s': Operator('∂s', 0, datesOperator), 2472 | '∂T': Operator('∂T', 0, dateTOperator), 2473 | '∂t': Operator('∂t', 0, datetOperator), 2474 | '∂U': Operator('∂U', 0, dateUOperator), 2475 | '∂u': Operator('∂u', 0, dateuOperator), 2476 | '∂W': Operator('∂W', 0, dateWOperator), 2477 | '∂w': Operator('∂w', 0, datewOperator), 2478 | '∂X': Operator('∂X', 0, dateXOperator), 2479 | '∂x': Operator('∂x', 0, datexOperator), 2480 | '∂Y': Operator('∂Y', 0, dateYOperator), 2481 | '∂y': Operator('∂y', 0, dateyOperator), 2482 | '∂Z': Operator('∂Z', 0, dateZOperator), 2483 | '∂z': Operator('∂z', 0, datezOperator), 2484 | 'ø': Operator('ø', 0, emptySetOperator), 2485 | 'Ø': Operator('Ø', 0, emptyStringOperator), 2486 | '₸': Operator('₸', 0, struckTOperator), 2487 | 'ℍ': Operator('ℍ', 0, struckHOperator), 2488 | '¶': Operator('¶', 0, pilcrowOperator), 2489 | '§': Operator('§', 0, sectionOperator), 2490 | '@': Operator('@', 0, atOperator), 2491 | # Monads 2492 | '!': Operator('!', 1, exclamationOperator), 2493 | '$': Operator('$', 1, dollarOperator), 2494 | '(': Operator('(', 1, leftParenthesisOperator), 2495 | ')': Operator(')', 1, rightParenthesisOperator), 2496 | ':': Operator(':', 1, colonOperator), 2497 | 'b': Operator('b', 1, bOperator), 2498 | 'c': Operator('c', 1, cOperator), 2499 | 'd': Operator('d', 1, dOperator), 2500 | 'f': Operator('f', 1, fOperator), 2501 | 'g': Operator('g', 1, gOperator), 2502 | 'h': Operator('h', 1, hOperator), 2503 | 'i': Operator('i', 1, iOperator), 2504 | 'l': Operator('l', 1, lOperator), 2505 | 'n': Operator('n', 1, nOperator), 2506 | 'o': Operator('o', 1, oOperator), 2507 | 'p': Operator('p', 1, pOperator), 2508 | 'q': Operator('q', 1, qOperator), 2509 | 'r': Operator('r', 1, rOperator), 2510 | 's': Operator('s', 1, sOperator), 2511 | 't': Operator('t', 1, tOperator), 2512 | 'u': Operator('u', 1, uOperator), 2513 | 'v': Operator('v', 1, vOperator), 2514 | 'w': Operator('w', 1, wOperator), 2515 | 'y': Operator('y', 1, yOperator), 2516 | 'z': Operator('z', 1, zOperator), 2517 | '\\': Operator('\\', 1, backslashOperator), 2518 | '_': Operator('_', 1, underscoreOperator), 2519 | '~': Operator('~', 1, tildeOperator), 2520 | '…': Operator('…', 1, lowEllipsisOperator), 2521 | '┅': Operator('┅', 1, highEllipsisOperator), 2522 | 'Σ': Operator('Σ', 1, sigmaOperator), 2523 | 'Π': Operator('Π', 1, piOperator), 2524 | '‼': Operator('‼', 1, doubleExclamationOperator), 2525 | '⌋': Operator('⌋', 1, floorOperator), 2526 | '⌉': Operator('⌉', 1, ceilOperator), 2527 | 'Σ': Operator('Σ', 1, sigmaOperator), 2528 | 'ċ': Operator('ċ', 1, cHighDotOperator), 2529 | 'ḋ': Operator('ḋ', 1, dHighDotOperator), 2530 | 'ḍ': Operator('ḍ', 1, dLowDotOperator), 2531 | 'ė': Operator('ė', 1, eHighDotOperator), 2532 | 'ẹ': Operator('ẹ', 1, eLowDotOperator), 2533 | 'ḟ': Operator('ḟ', 1, fHighDotOperator), 2534 | 'ḣ': Operator('ḣ', 1, hHighDotOperator), 2535 | 'ḥ': Operator('ḥ', 1, hLowDotOperator), 2536 | 'ṁ': Operator('ṁ', 1, mHighDotOperator), 2537 | 'ṃ': Operator('ṃ', 1, mLowDotOperator), 2538 | 'ṅ': Operator('ṅ', 1, nHighDotOperator), 2539 | 'ṇ': Operator('ṇ', 1, nLowDotOperator), 2540 | 'ȯ': Operator('ȯ', 1, oHighDotOperator), 2541 | 'ọ': Operator('ọ', 1, oLowDotOperator), 2542 | 'ṗ': Operator('ṗ', 1, pHighDotOperator), 2543 | 'ṙ': Operator('ṙ', 1, rHighDotOperator), 2544 | 'ṛ': Operator('ṛ', 1, rLowDotOperator), 2545 | 'ṡ': Operator('ṡ', 1, sHighDotOperator), 2546 | 'ṣ': Operator('ṣ', 1, sLowDotOperator), 2547 | 'ṭ': Operator('ṭ', 1, tLowDotOperator), 2548 | 'ṫ': Operator('ṫ', 1, tHighDotOperator), 2549 | 'ụ': Operator('ụ', 1, uLowDotOperator), 2550 | 'ẋ': Operator('ẋ', 1, xHighDotOperator), 2551 | 'ẏ': Operator('ẏ', 1, yHighDotOperator), 2552 | 'ỵ': Operator('ỵ', 1, yLowDotOperator), 2553 | '€|': Operator('€|', 1, extPipeOperator), 2554 | '€[': Operator('€[', 1, extLeftBracketOperator), 2555 | '€]': Operator('€]', 1, extRightBracketOperator), 2556 | # Dyads 2557 | '%': Operator('%', 2, percentOperator), 2558 | '&': Operator('&', 2, ampersandOperator), 2559 | '*': Operator('*', 2, asteriskOperator), 2560 | '+': Operator('+', 2, plusOperator), 2561 | ',': Operator(',', 2, commaOperator), 2562 | '/': Operator('/', 2, slashOperator), 2563 | ';': Operator(';', 2, semicolonOperator), 2564 | '<': Operator('<', 2, lessThanOperator), 2565 | '=': Operator('=', 2, equalsOperator), 2566 | '>': Operator('>', 2, greaterThanOperator), 2567 | '^': Operator('^', 2, caretOperator), 2568 | '|': Operator('|', 2, pipeOperator), 2569 | '«': Operator('«', 2, leftArrowQuoteOperator), 2570 | '»': Operator('»', 2, rightArrowQuoteOperator), 2571 | '⊂': Operator('⊂', 2, subsetOperator), 2572 | '⊃': Operator('⊃', 2, supersetOperator), 2573 | '∧': Operator('∧', 2, andOperator), 2574 | '∨': Operator('∨', 2, orOperator), 2575 | '⁻': Operator('⁻', 2, minusOperator), 2576 | '×': Operator('×', 2, timesOperator), 2577 | '÷': Operator('÷', 2, divisionOperator), 2578 | '¤': Operator('¤', 2, currencyOperator), 2579 | 'B': Operator('B', 2, BOperator), 2580 | #'Ḅ': Operator('Ḅ', 2, BLowDotOperator), 2581 | 'C': Operator('C', 2, COperator), 2582 | 'D': Operator('D', 2, DOperator), 2583 | 'E': Operator('E', 2, EOperator), 2584 | 'Ė': Operator('Ė', 2, EHighDotOperator), 2585 | 'I': Operator('I', 2, IOperator), 2586 | 'K': Operator('K', 2, KOperator), 2587 | 'N': Operator('N', 2, NOperator), 2588 | 'Ṁ': Operator('Ṁ', 2, MHighDotOperator), 2589 | 'Ṃ': Operator('Ṃ', 2, MLowDotOperator), 2590 | 'S': Operator('S', 2, SOperator), 2591 | 'Ṡ': Operator('Ṡ', 2, SHighDotOperator), 2592 | 'U': Operator('U', 2, UOperator), 2593 | 'Z': Operator('Z', 2, ZOperator) 2594 | 2595 | 2596 | } 2597 | -------------------------------------------------------------------------------- /utilities.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import re 3 | import array 4 | 5 | import primes 6 | 7 | codepage = """₀₁₂₃₄₅₆₇₈₉ₓ₌ₔ∂€₵⟨⟩⟪⟫⇑⇓⇐⇒↑↓←→⇈⇊⇇⇉ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 8 | «»…┅⌋⌉⊂⊃∧∨ΣΠ‼×÷⁻øØ¤¶§ ₸ℍȦĊḊĖḞĠḢṀṄȮṖṘṠṪẆẊẎŻȧċḋėḟġḣṁṅȯṗṙṡṫẇẋẏżẠḄḌẸḤḲḶṂṆỌṚṢṬỤṾẈỴẒạḅḍẹḥḳḷṃṇọṛṣṭụṿẉỵẓ¿¡⁇⁈↻↺∞¦†‡∆∇⊢⊣‖ ⌡⌠∫ªº° “”‘’„‟""" # TODO: finish code page 9 | 10 | manualOutput = False 11 | inputs = [] 12 | randoms = [0] 13 | 14 | def flatten(l): 15 | result = [] 16 | for i in l: 17 | if type(i) == list: 18 | # If the element is a list, recursively flatten it and append its elements 19 | result += flatten(i) 20 | else: 21 | # Otherwise just append that element 22 | result.append(i) 23 | return result 24 | 25 | def toBase(num, base): 26 | sign = -1 if num < 0 and base > 0 else 1 27 | num = abs(num) 28 | 29 | if num == 0: 30 | return [0] 31 | if base == 0: 32 | return [num] 33 | if base == 1: 34 | return [sign]*num 35 | 36 | digits = [] 37 | while num: 38 | num, digit = divmod(num, base) 39 | if digit < 0: 40 | num += 1 41 | digit -= base 42 | digits.insert(0, digit*sign) 43 | 44 | return digits 45 | 46 | def fromBase(digits, base): 47 | return sum(digits[~i]*(base**i) for i in range(len(digits))) 48 | 49 | def formatNum(num): 50 | return int(num) if num == int(num) else num 51 | 52 | def getInput(): 53 | try: 54 | line = input().strip() 55 | value = None 56 | 57 | match = re.match("^-?(\d+(\.\d+)?|\.\d+)$", line) 58 | if match: 59 | if match.group(2): # Only do float parsing if it actually has a fractional part 60 | value = formatNum(float(line)) 61 | else: 62 | value = int(match.group(0)) 63 | 64 | elif re.match("^\s*“[^”]*”\s*$", line): 65 | value = re.match("^\s*“([^”]*)”\s*$", line).group(1) 66 | else: 67 | value = line 68 | inputs.append(value) 69 | return value 70 | except EOFError: 71 | return inputs[-1] 72 | ## TODO: Finish this function (add list parsing?) 73 | 74 | def codepageEncode(code): 75 | result = [] 76 | for c in code: 77 | if codepage.find(c) != -1: 78 | result.append(codepage.index(c)) 79 | 80 | return array.array('B', result).tostring() 81 | 82 | def codepageDecode(code): 83 | result = "" 84 | for byte in code: 85 | result += codepage[byte] 86 | 87 | return result 88 | 89 | def outputFormat(value): 90 | if type(value) == int: 91 | return str(value) 92 | elif type(value) == float: 93 | return str(formatNum(value)) 94 | elif type(value) == str: 95 | return value 96 | elif type(value) == list: 97 | result = '[' 98 | for i in value: 99 | if type(i) == list: 100 | result += outputFormat(i) 101 | elif type(i) == str: 102 | result += '"'+i+'"' 103 | else: 104 | result += str(formatNum(i)) 105 | result += ' ' 106 | result = re.sub(" ?$", "]", result) 107 | return result 108 | 109 | 110 | def castToNumber(v): 111 | if type(v) == int or type(v) == float: 112 | return formatNum(v) 113 | elif type(v) == str: 114 | match = re.match("^\s*((-|\+)?(\d+(\.\d+)?|\.\d+))", v) 115 | 116 | return 0 if match == None else formatNum(float(match.group(1))) 117 | elif type(v) == list: 118 | return fromBase([castToNumber(d) for d in v], 10) 119 | 120 | def castToString(v): 121 | if type(v) == int or type(v) == float: 122 | return str(formatNum(v)) 123 | elif type(v) == str: 124 | return v 125 | elif type(v) == list: 126 | newList = [castToString(item) for item in v] 127 | return "".join(newList) 128 | 129 | def castToList(v): 130 | if type(v) == int or type(v) == float: 131 | sign = -1 if v < 0 else 1 132 | v = abs(int(v)) 133 | 134 | return list(map(lambda x:x*sign, list(range(1, v+1) if v>0 else [0]))) 135 | 136 | elif type(v) == str: 137 | return list(v) 138 | elif type(v) == list: 139 | return v 140 | 141 | # Add a new prime to the prime list 142 | def generatePrime(): 143 | p = primes.primes[-1] + 1 144 | while not all(p%n for n in primes.primes): 145 | p += 1 146 | primes.primes.append(p) 147 | 148 | # Get the nth prime 149 | def getPrime(n): 150 | while len(primes.primes) < n: 151 | generatePrime() 152 | return primes.primes[n-1] 153 | 154 | # Get the first n primes 155 | def getPrimes(n): 156 | while len(primes.primes) < n: 157 | generatePrime() 158 | return primes.primes[:n] 159 | --------------------------------------------------------------------------------