#!/usr/bin/python # here's an example input file, so you can use this in batch # it loads the fibonacci numbers, entered in decimal (frombase starts 10) # and converts them to trinary (tobase set 3 before we enter the series) # and converts the results to trinary (countbase set to 3) to be read back # in as trinary, not decimal (frombase set to 3 after entering the series, # before running reiterhi). If you're going to use huge series, see the next # comment after this to speed it up... #countbase 3 #tobase 3 #0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 #frombase 3 #reiterhi #quit mult = 0 # << if you want to do products instead of sums, set this to 1 # or say -mult on the commandline. Note, this mode treats 0's # as 1's, or almost all products end up as 0. The weird thing is # if you actually say "0" in multiply mode the result is "1". # But it serves to get interesting large results instead of 0's import random, sys # too slow? set justSum = 1, and just do high sets. # or say -high on the commandline............ see here vvv def doSums(n, verbose=0, allowNeg = 0, justSum = 1): # justSum = 1 is faster # but only gets the max # sums (no subtracts) # this allows you to use # numbers with huge # of # digits (larger numbers) # if mult = 1, justSum # is automatically true # ... multiply was linas # vepstas' idea if you # like that sort of thing # it has v. neat results global mult if mult == 1: justSum = 1 global tobase out = "" intn = fromBase(tobase, n) n = str(n) n = list(n) ops = [] ops.append("+"*len(n)) # then we'll use binary to assemble a table of operations with minuses if justSum == 0: for num in xrange(1,(2**len(n))): newop = list(ops[0]) c = 0 cc = 1 for nom in xrange(1, len(n)+1): if cc & num == cc: newop[c] = "-" c += 1 cc *= 2 newop = "".join(newop) if not ops.__contains__(newop): ops.append(newop) # print "c = "+str(c)+" cc = "+str(cc)+" num = "+str(num)+" added "+newop # not even in verbose ^ # print ops # sys.exit() # christ i dont think i can get it faster than this if verbose == 1: print ops # kind of cool #sys.exit() # but no dont num_rep={'a':10, 'b':11, 'c':12, 'd':13, 'e':14, 'f':15, 'g':16, 'h':17, 'i':18, 'j':19, 'k':20, 'l':21, 'm':22, 'n':23, 'o':24, 'p':25, 'q':26, 'r':27, 's':28, 't':29, 'u':30, 'v':31, 'w':32, 'x':33, 'y':34, 'z':35} out = "" sums = [] v = 0 for op in ops: c = 0 if mult == 0: sum = 0 # add elif mult == 1: sum = 1 # mult for o in op: v = 0 try: v = int(n[c]) except: v = -1 if v == -1: try: v = int(num_rep[n[c]]) except: v = tobase + 1 if v > tobase-1: print "Err: Unknown digit (doSums): '"+repr(n[c])+"'" return "0" if o == "+": if mult == 0: sum += v # add else: if int(v) > 0: # mult sum *= int(v) # mult (unindent this and leave the 'if' commented # if you don't care about getting a lot of 0's) elif o == "-": sum -= v c += 1 if not sums.__contains__(sum): sums.append(sum) sums.sort() if allowNeg == 0: newsums = [] negsoff = 0 for sum in sums: if sum >= 0: newsums.append(sum) negsoff += 1 if verbose == 1: print str(negsoff)+" negative sums trimmed" sums = newsums if len(sums) > 1: out = "[" for sum in sums: sum = base10toN(sum, countbase) out += str(sum).strip() out += "/" out = out[:-1] out += "]" else: out = str(sums[0]).strip() out = base10toN(int(out), countbase) return out # i wrote this def fromBase(b, l): num_rep={'a':10, 'b':11, 'c':12, 'd':13, 'e':14, 'f':15, 'g':16, 'h':17, 'i':18, 'j':19, 'k':20, 'l':21, 'm':22, 'n':23, 'o':24, 'p':25, 'q':26, 'r':27, 's':28, 't':29, 'u':30, 'v':31, 'w':32, 'x':33, 'y':34, 'z':35} k = 0 ctr = 0 l = list(str(l)) l.reverse() for t in l: f = 0 try: t = int(t) except: f = -1 if f == -1: try: t = num_rep[t] except: t = b + 1 if t > b-1: print "Err: Unknown digit (fromBase): '"+repr(l[ctr])+"'" return "0" k += t * (b**ctr) ctr += 1 return k # and i wrote this def fromBaselist(b, l): num_rep={'a':10, 'b':11, 'c':12, 'd':13, 'e':14, 'f':15, 'g':16, 'h':17, 'i':18, 'j':19, 'k':20, 'l':21, 'm':22, 'n':23, 'o':24, 'p':25, 'q':26, 'r':27, 's':28, 't':29, 'u':30, 'v':31, 'w':32, 'x':33, 'y':34, 'z':35} k = 0 ctr = 0 l.reverse() for t in l: f = 0 try: t = int(t) except: f = -1 if f == -1: try: t = num_rep[t] except: t = b + 1 if t > b - 1: print "Err: Unknown digit: '"+repr(l[ctr])+"'" return "0" k += (t**ctr) * (b[len(b)-1-ctr]) ctr += 1 return k # but i got this online def base10toN(num,n): """Change a to a base-n number. Up to base-36 is supported without special notation.""" num_rep={10:'a', 11:'b', 12:'c', 13:'d', 14:'e', 15:'f', 16:'g', 17:'h', 18:'i', 19:'j', 20:'k', 21:'l', 22:'m', 23:'n', 24:'o', 25:'p', 26:'q', 27:'r', 28:'s', 29:'t', 30:'u', 31:'v', 32:'w', 33:'x', 34:'y', 35:'z'} new_num_string='' current=num while current!=0: remainder=current%n if 36>remainder>9: remainder_string=num_rep[remainder] elif remainder>=36: remainder_string='('+str(remainder)+')' else: remainder_string=str(remainder) new_num_string=remainder_string+new_num_string current=current/n if new_num_string == "": new_num_string = "0" return new_num_string # body begins num_rep={0:'0',1:'1',2:'2',3:'3',4:'4',5:'5',6:'6',7:'7',8:'8',9:'9', 10:'a', # do not make this global we use three different ones 11:'b', 12:'c', 13:'d', 14:'e', 15:'f', 16:'g', 17:'h', 18:'i', 19:'j', 20:'k', 21:'l', 22:'m', 23:'n', 24:'o', 25:'p', 26:'q', 27:'r', 28:'s', 29:'t', 30:'u', 31:'v', 32:'w', 33:'x', 34:'y', 35:'z'} # do not make this global we use three different ones def help(): print "Commands" print "n n n (eg 1 2 3) -- mangle a series" print "lowest -- show only the lowest results from the last series (no slashes)" print "highest -- show only the highest results from the last series (no slashes)" print "random -- show random results from the last series (oh why?)" print "run -- show the last list of high/low/rand results in a series (no colons)" print "reiterhi -- reiterate highest results until all are one digit" print "reiterlo -- reiterate lowest results until all are one digit" print "frombase n -- change the base input values are treated as" print "tobase n -- change the base output values are shown as" print "countbase n -- change the base computed sums are shown as" print "base n -- change all three bases at once" print "quit -- leaves" print "reiterhi and reiterlo also run a digit frequency count on the final series so" print "give that a try. When using the reiteration commands, the output, in base" print "countbase, will be read back in as if it were written in frombase. This means" print "if you use countbase 2 and frombase 10 and reiterate, you may loop reading 11, 3" print "in binary, as eleven in decimal. To reiterate on series results in special bases" print "set frombase to the same as countbase before you reiterate. If you want to reit," print "set countbase before entering the series, then set tobase and frombase before" print "running the reiterhi/lo command" print "Try powers of 2, or powers of anything, and the results, and the" print "results of that, til a pattern appears. Then try some other things." print "Wow who knows. This has some strange effects .. Let's start" series = "help" lastout = "" newout = "" newnew = "" reit = 0 baz = 0 #wtf tobase = 10 frombase = 10 countbase = 10 if sys.argv.__contains__("-h") or sys.argv.__contains__("-help") \ or sys.argv.__contains__("--help"): print "series.py usage\n" print "./series.py [-mult]\n" print "or,\n" print "cat script | ./series.py [-mult] > outputfile" print "make sure your script sets the right bases at the right times" print "and ends with a 'quit', if you're going to do that. it's the" print "preferred way to load in very long serieses" sys.exit() if sys.argv.__contains__("-mult"): mult = 1 justsums = 1 if sys.argv.__contains__("-high"): justsums = 1 else: justsums = 0 while series != "quit": # print "series/command "+repr(series) # print "reit "+str(reit) # print "lastout "+lastout # print "baz "+str(baz) sys.stdout.flush() nohelp = 0 #christ so you dont see help while commands are reiterating or w/e if baz == 0 and not series.startswith("run") and not series.endswith("est") \ and not series == " " and not series.__contains__("reiter") and series != "help": print chr(27)+"[1Dfrombase"+str(frombase)+"/tobase"+str(tobase)+"/countbase"+str(countbase)+"> ", series = sys.stdin.readline().strip() # weird if series != " ": pass else: series = "" nohelp = 1 sys.stdout.flush() while series.replace(" ", " ") != series: series = series.replace(" ", " ") if series == "" and nohelp == 0: print "\nType 'help' for help. Type 'quit' to quit.\n" # continue if series == "help": help() series = "" continue nohelp = 0 if (series == "quit" or series == "") and baz == 0: continue if series.startswith("tobase"): try: otb = tobase tobase = int(series.replace("tobase","")) if tobase > 36: print "Err: Max tobase = 36" tobase = otb except: print "Err: No or invalid tobase specified" series = " " continue if series.startswith("countbase"): try: ocb = countbase countbase = int(series.replace("countbase","")) if countbase > 36: print "Err: Max countbase = 36" countbase = ocb except: print "Err: No or invalid countbase specified" series = " " continue if series.startswith("frombase"): try: ofb = frombase frombase = int(series.replace("frombase","")) if frombase > 36: print "Err: Max frombase = 36" frombase = ofb except: print "Err: No or invalid frombase specified" series = " " continue if series.startswith("base"): try: ofb = frombase otb = tobase ocb = countbase frombase = int(series.replace("base","")) tobase = frombase countbase = tobase if frombase > 36: print "Err: Max frombase = 36" frombase = ofb tobase = otb countbase = ocb except: print "Err: No or invalid base specified" series = " " continue if series.startswith("reiter") or reit == 1 or reit > 3: if lastout == "": print "Err: enter a number series before running a reiterate command." reit = 0 series = " " continue if series == "reiterlo" or series == "reiterhi": whichreit = series if reit == 4: series = "run "+whichreit reit = 0 continue # print "bah2" if newnew == "": if newout != "": series = "run "+series continue else: if series == "reiterhi": reit = 3 series = "highest" continue elif series == "reiterlo": reit = 3 series = "lowest" continue else: print "Err: Unknown reiter* command. Valid: reiterhi, reiterlo" reit = 0 series = " " # or it loops continue done = 1 for somenum in newnew.split(" "): if len(str(somenum).strip()) > 1: done = 0 if done == 0: series = newnew.replace("\t","").strip() # if random.choice(range(2)): sys.exit() reit = 3 newnew = "" newout = "" else: newnew = "" newout = "" print "\nReit done. Last run:" reit = 0 if whichreit == "reiterhi": baz = 1 elif whichreit == "reiterlo": baz = 2 series = " " # or it loops continue # print "bah4" if series == "highest" or baz == 1: newnew = "" newout = "" for word in lastout.split(" "): try: word = word.split("/")[-1] except: pass word = word.replace("]","") newout += word+" " print "Highest outputs of last series: " print newout # print "\nSeries is "+str(many)+" values long." if baz == 1: baz = 3 series = "run" continue if reit == 3: series = "reiterhi" else: series = " " # or it loops continue if series == "lowest" or baz == 2: newnew = "" newout = "" for word in lastout.split(" "): try: word = word.split("/")[0] except: pass word = word.replace("[","") newout += word+" " print "Lowest outputs of last series: " print newout # print "\nSeries is "+str(many)+" values long." if baz == 2: baz = 3 series = "run" continue if reit == 3: series = "reiterlo" else: series = " " # or it loops continue if series == "random": newnew = "" newout = "" for word in lastout.split(" "): try: word = random.choice(word.split("/")) except: pass word = word.replace("[","") word = word.replace("]","") newout += word+" " print "Random outputs of last series: " print newout # print "\nSeries is "+str(many)+" values long." continue # print "one" if series.startswith("run") or reit == 2: # print "two" newnew = "" if newout == "": print "No previous highest/lowest/random command exec'd. Try one" series = " " continue for word in newout.split(" "): if not word.__contains__(":"): newnew += word.strip()+" " print "\n"+newnew.strip().replace("\t","") print "Series is "+str(many)+" values long." if series.endswith("reiterhi"): series = "reiterhi" elif series.endswith("reiterlo"): series = "reiterlo" else: series = " " # or loops if reit == 2: reit = 1 tabctr = 0 print "\nDigit frequency:" for a in range(countbase): print str(num_rep[a])+": "+str(newnew.count(str(num_rep[a]))), tabctr += 1 if tabctr == 9: tabctr = 0 print "\n", else: print "\t", if tabctr != 0: print "\n" else: print if baz == 3: baz = 0 # what is baz being 3 for anymore continue series = series.split(" ") c = 0 noInt = 0 newseries = [] for n in series: n = n.lower().strip() if n == "": continue on = n n = fromBase(frombase, n) try: newseries.append(int(n)) except: noInt = 1 print "Err: "+str(n)+" is no int" series = newseries if noInt == 1: series = " " continue newnew = "" newout = "" if frombase != 10: print "Read "+str(on)+" in base "+str(frombase)+" as "+str(n)+".", print "Possible", if mult == 0: print "add/subtract", else: print "multiply", print "outputs of digits in numbers of series, in base "+str(tobase)+":" lastout = "" many = 0 for n in series: if n == "": continue if justsums == 0: thingie = str(base10toN(n,tobase))+": "+doSums(base10toN(n,tobase))+" \t " else: thingie = str(base10toN(n,tobase))+": "+doSums(base10toN(n,tobase), justSum=1)+" \t " print thingie, many += 1 sys.stdout.flush() lastout += thingie print "\nSeries is "+str(many)+" values long." if reit == 3: series = whichreit else: series = " " # or crash print