def __init__(self, n, l, ml, spin): """ An orbital :param n: shell :param l: angular momentum :param ml: projected angular momentum (azimuthal, etc.) :param spin: electron spin """ if not isinstance(n, int) or n < 1: raise ValueError( "Shells (n) must be integers greater than 0, got: n = {n}") if not isinstance(l, int) or l < 0: raise ValueError( f"Angular momentum (l) must be an integer >= 0, got: l = {l}") if not isinstance(ml, int) or ml < -l or ml > l: raise ValueError( "Projected angular momentum (ml) must be an integer such that -l <= ml <= l, " f"got: l = {l}, ml = {ml}") up = [1, Frac(1, 2), 'alpha', 'α'] down = [-1, -Frac(1, 2), 'beta', 'β'] if spin in up: self.spin = Frac(1, 2) elif spin in down: self.spin = -Frac(1, 2) else: raise ValueError(f"Spin must be in {up} or {down}, got: {spin}") self.n = n self.l = l self.ml = ml self.orb_symbol = None
def deriv(self): u = self.arg du = u.deriv() if self.id == 'ln': return Num(1) / u * du elif self.id == 'sqrt': return Num(Frac(1, 2)) * u**Num(-Frac(1, 2)) * du elif self.id == 'sin': return cos(u) * du elif self.id == 'cos': return -sin(u) * du elif self.id == 'tan': return sqr(sec(u)) * du elif self.id == 'cot': return -sqr(csc(u)) * du elif self.id == 'sec': return sec(u) * tan(u) * du elif self.id == 'csc': return -(csc(u) * cot(u)) * du elif self.id in ['arcsin', 'asin']: return (Num(1) / sqrt(Num(1) - sqr(u))) * du elif self.id in ['arccos', 'acos']: return -(Num(1) / sqrt(Num(1) - sqr(u))) * du elif self.id in ['arctan', 'atan']: return (Num(1) / (u**Num(2) + Num(1))) * du elif self.id in ['arccsc', 'acsc']: return -(Num(1) / (abs(u) * sqrt(sqr(u) - 1))) * du elif self.id in ['arcsec', 'asec']: return (Num(1) / (abs(u) * sqrt(sqr(u) - 1))) * du elif self.id in ['arccot', 'acot']: return -(Num(1) / (u**Num(2) + Num(1))) * du else: return Undefined()
class Belt(Enum): Y = Frac("15") R = Frac("30") B = Frac("45") @classmethod def by_name(cls, s: str) -> Belt: return {"y": cls.Y, "r": cls.R, "b": cls.B}[s[0].lower()] @property def name(self): if self == self.Y: return "yellow belt" elif self == self.R: return "red belt" elif self == self.B: return "blue belt" else: raise AssertionError(f"{self} didn't get a name") def __str__(self): return { self.Y: "yellow belt", self.R: "red belt", self.B: "blue belt" }[self]
def solve_rates( self, outflow: Frac, **solver_kwargs ) -> t.Tuple[t.List[BeltAssignment], int, t.List[Item.Flow]]: """ Solves the number of units to fill a full belt """ # NOTE we divide by 2 since the line solution is for half the flow # see: symmetric layout assumed (TODO) by belt_solver out_rate = outflow / 2 # base output per sec per unit rps = Frac(self.speed) * self.base_rps # NOTE this is the needed manufactories per side need_mfs = Frac(out_rate / rps) / self.prod assert self.recipe is not None need_flows = [ dc_replace(base_flow, num=base_flow.num * need_mfs * rps) for base_flow in self.recipe.inputs ] belt_assignment = solve_belts(need_flows) return belt_assignment, need_mfs, need_flows
def get_trans_probs(SSP: FracVec) -> FracMatrix: test_probs_eq_1("funct get_trans_probs", SSP) trans_table: FracMatrix = [[ZERO for _ in range(1, 10)] for _ in range(1, 10)] # in Python upper bound is exclusive # for each pair of states for s1 in range(1, 10): # indices are biased # state 1, for example, is stored in index 0 for s2 in ADJECANCY_LIST[s1 - 1]: acc_prob: Frac = min(ONE, Frac(SSP[s2 - 1], SSP[s1 - 1])) # r: Frac = Frac(*random().as_integer_ratio()) # prop_prob: Frac = Frac(1, len(ADJECANCY_LIST[s1 - 1])) prop_prob: Frac = Frac(1, 4) trans_table[s1 - 1][s2 - 1] = acc_prob * prop_prob non_self_ps = ZERO for neighbour in ADJECANCY_LIST[s1 - 1]: non_self_ps += trans_table[s1 - 1][neighbour - 1] log.debug(f'non-self ps = {non_self_ps}') if non_self_ps < ONE: log.debug( f"non-self transitions didn't add up to 1.0 (got {non_self_ps}), adding a self transition" ) trans_table[s1 - 1][s1 - 1] = ONE - non_self_ps return trans_table
def probs(n,m): #returns a set of probabilities of winning, #drawing and losing given your opponent must take n steps and you must take m win = Frac() draw = Frac() loss = Frac() i=0 while (i<6): i+=1 j=0 while j<6: j+=1 if(n-i<=0): if(n-i-(m-j)<0): loss+=Frac(1,36) elif (n-i-(m-j)>0): win+=Frac(1,36) elif (n-i-(m-j)==0): draw+=Frac(1,36) else: print("Error: difference neither above, below, or equal to 0") else: #n-i>0 ie the opponent has not reached the end if (m-j<=0): win+=Frac(1,36) else: #m-j>0 ie we have not reached the end cascade=probs(n-i,m-j) win+=(Frac(1/36)*cascade[0]) draw+=(Frac(1/36)*cascade[1]) loss+=(Frac(1/36)*cascade[2]) return [win,draw,loss]
def test_mul_calculation(n1, n2, d1, d2): xt = omk.TimeSignature(n1, d1) yt = omk.TimeSignature(n2, d2) xf = Frac(n1, d1) yf = Frac(n2, d2) assert xt * yt == xf * yf
def __mul__(self, A): n = len(self.coeff) - 1 t = len(A.coeff) - 1 coeff = [Frac(0) for i in range(n + t + 1)] for i in range(n + 1): for j in range(t + 1): coeff[j + i] += Frac(self.coeff[i] * A.coeff[j]) return Polynomio(coeff)
def exercise_2() -> Tuple[FracVec, FracMatrix]: # the sum of all SSP needs to be 1.0 SSP: FracVec = [ # [ BOT ROW ] # all in bot row need to add up to 1/6 # because top_row = 1/18 + 1/18 + 1/18 = 3/18 = 1/6 Frac(1, 18), # s1 Frac(1, 18), # s2 Frac(1, 18), # s3 # [ MID ROW ] # all in mid row need to add up to 2/6 # because mid_row = 2/18 + 2/18 + 2/18 = 6/18 = 2/6 Frac(2, 18), # s4 Frac(2, 18), # s5 Frac(2, 18), # s6 # [ TOP ROW ] # distribute remaining probability evenly across the top row # # (1 - (p(top) + p(bot))) / 3 = 1/6 # # p = 1.0 = p(top) + p(bot) + p(bot) = 1/6 + 2/6 + 3/6 Frac(1, 6), # s7 Frac(1, 6), # s8 Frac(1, 6), # s9 ] return SSP, get_trans_probs(SSP)
def __add__(self, A): coeffi = [] if len(A.coeff) > len(self.coeff): coeffi[:] = A.coeff for i in range(len(self.coeff)): coeffi[i] += Frac(self.coeff[i]) else: coeffi[:] = self.coeff for i in range(len(A.coeff)): coeffi[i] += Frac(A.coeff[i]) return Polynomio(coeffi)
def __add(self, other: 'Frac') -> 'Frac': if isinstance(other, int): if other == 0: return self return Frac(self.numerator + self.denominator * other, self.denominator) a, b = self.denominator, other.denominator if a == b: return Frac(self.numerator + other.numerator, a) d, m = divmod(a, b) if m == 0: return Frac(self.numerator + other.numerator * d, a) return Frac(self.numerator * b + other.numerator * a, a * b)
def __mul__(self, x): frac_prod = Frac(self) * Frac(x) try: x_d = x._d except AttributeError: x_d = 0 den = max([self._d, x_d, frac_prod.denominator]) m = Frac(den, frac_prod.denominator) num = frac_prod.numerator * m return self.__class__(num, den)
def test_calc_vals_and_term_symbol(): iterator = atomic_spinorbitals_iterator(1, 0) occ1 = list(occupy(iterator, 1)) assert_equal(calc_vals(occ1[0]), (0, Frac(1, 2))) assert_equal(calc_vals(occ1[1]), (0, Frac(-1, 2))) assert_equal(find_term_symbol(occ1[0]), TermSymbol(2, 0)) orbs1 = [AtomicSpinOrbital(n=3, l=2, ml=-2, spin='alpha'), AtomicSpinOrbital(n=5, l=4, ml=-1, spin='beta')] assert_equal(calc_vals(orbs1), (-3, 0)) assert_equal(find_term_symbol(orbs1), TermSymbol(1, 3)) assert_equal(TermSymbol(3, 2).num_microstates(), 15)
def solution_n2(wabbits: List[Tuple[int, str]], p_numerator: int, p_denominator: int) -> str: from fractions import Fraction as Frac p = Frac(p_numerator, p_denominator) types = [typ for _, typ in wabbits] children: List[List[int]] = [[] for _ in range(len(wabbits))] edges: List[List[int]] = [[] for _ in range(len(wabbits))] for idx, (parent, typ) in enumerate(wabbits): if parent == -1: continue edges[parent].append(idx) edges[idx].append(parent) children[parent].append(idx) trans_probs = [ [(1 - p)**2, 2 * p * (1 - p), p**2], [p * (1 - p), (1 - p)**2 + p**2, p * (1 - p)], [p**2, 2 * p * (1 - p), (1 - p)**2], ] def dfs(x: int, parent: Optional[int] = None) -> List[Frac]: # Compute P(subtree | node gene) probs = [Frac(1), Frac(1), Frac(1)] for child in edges[x]: if child == parent: continue prob = dfs(child, x) probs = [ probs[i] * sum(trans_probs[i][j] * prob[j] for j in range(3)) for i in range(3) ] cur_typ = wabbits[x][1] if cur_typ == "R": probs[2] = 0 elif cur_typ == "G": probs[0] = probs[1] = 0 return probs total_prob = sum(prob * init for prob, init in zip(dfs( 0), [Frac(1, 4), Frac(1, 2), Frac(1, 4)])) # print(total_prob) ans = 0 for idx, (_, typ) in enumerate(wabbits): if typ != "?": continue cur_prob = dfs(idx)[2] / 4 # print(idx, cur_prob) ans += cur_prob ans /= total_prob ans += Frac(sum(typ == 'G' for typ in types)) # print(ans) return str(ans.numerator) + str(ans.denominator)
def bin_float(float_str): split_ = float_str.replace("-", "").split('.') integ_part = bin_int(split_[0]) numer_str = split_[1] denom_str = "1" + "0" * len(numer_str) N = int(numer_str) D = int(denom_str) F = Frac(N, D) #Automatically reduces fraction N = F.numerator #Pull back out D = F.denominator #recuced numer and denomm float_part = "" while (len(float_part) <= 10): if N < D: ret = "0" N *= 2 elif N > D: ret = "1" N = N - D elif N == D: float_part += "1" break float_part += ret return integ_part + '.' + float_part
def frictie_factor(re): # Opvragen van frictie factor # re = re if re > 3000: q = str( input("Mag je uit gaan van een wrijvingsloze toestand? (ja/nee) ")) if q == "ja": ff = 0.3164 / re**Frac(1, 4) elif q == "nee": q2 = str( input( "Valt de frictiefactor af te lezen van het Moody Diagram? (ja/nee)" )) if q2 == "ja": ff = float(input("Wat is de frictie factor?")) elif q2 == "nee": r = float(input("Wat is de relatieve randruwheid?")) # test = r/(a*10**-2) ff = 0.25 / math.log10( (r / 3.7 * a + (5.74 / (re**0.9))))**2 # Swamee-jain vergelijking elif re < 2000: ff = 64 / re print("Frictie factor = ", round(ff, 4)) return round(ff, 4)
def calculate(): B, N = map(int, raw_input().split()) M = map(int, raw_input().split()) if B >= N: print N return per = sum(Frac(1, m) for m in M) t = max(int((N - 1) / per) - 3, 0) while True: done = 0 reminder = 1000000 doing = [] for i, m in enumerate(M, 1): d, r = divmod(t, m) done += d doing.append((t - r, i)) reminder = min(reminder, m - r) doing.sort() if done < N <= done + B: print doing[N - done - 1][1] break t += reminder
def dfs(x: int, parent: Optional[int] = None) -> List[Frac]: # Compute P(subtree | node gene) probs = [Frac(1), Frac(1), Frac(1)] for child in edges[x]: if child == parent: continue prob = dfs(child, x) probs = [ probs[i] * sum(trans_probs[i][j] * prob[j] for j in range(3)) for i in range(3) ] cur_typ = wabbits[x][1] if cur_typ == "R": probs[2] = 0 elif cur_typ == "G": probs[0] = probs[1] = 0 return probs
def test_SOTermSymbol(): iterator = atomic_spinorbitals_iterator(1, 0) occ1 = list(occupy(iterator, 1)) assert_equal(find_term_symbol(occ1[0], j=True), SOTermSymbol(2, 0, Frac(1, 2))) iterator = atomic_spinorbitals_iterator(1, 0) occ1 = list(occupy(iterator, 1)) assert_equal(find_term_symbol(occ1[0], j=True), SOTermSymbol(2, 0, Frac(1, 2))) orbs1 = [AtomicSpinOrbital(n=3, l=2, ml=-2, spin='alpha'), AtomicSpinOrbital(n=5, l=4, ml=-1, spin='beta')] assert_equal(calc_vals(orbs1), (-3, 0)) assert_equal(find_term_symbol(orbs1, j=True), SOTermSymbol(1, 3, 3)) j_states = list(TermSymbol(3, 2).form_jstates()) assert_equal(j_states, [SOTermSymbol(3, 2, 1), SOTermSymbol(3, 2, 2), SOTermSymbol(3, 2, 3)])
def interpolation(xs, ys): n = len(xs) PolyAns = Polynomio([]) for i in range(n): xi = xs[i] denomi = Frac(1) A = Polynomio([Frac(1)]) for j in range(n): xj = Frac(xs[j]) if i != j: denomi = denomi * Frac(xi - xj) A = A * Polynomio([-xj, 1]) PolyAns = PolyAns + A * Polynomio([Frac(ys[i], denomi)]) return PolyAns
def dot(self, dots=1): """ >>> NoteLength(1, 4).dot() NoteLength(1, 4).dot(1) """ return sum([self*Frac(1,(2**n)) for n in range(0,dots+1)])
def exercise_1() -> Tuple[FracVec, FracMatrix]: # 9 states with equal probability of being in every one # so the probability is 1/9 for being in each of them SSP: FracVec = [Frac(1, 9) for i in range(1, 10)] return SSP, get_trans_probs(SSP)
def main(): parser = ArgumentParser() parser.add_argument( "recipe", help="name of the recipe to use, as it appears in the factorio files", ) parser.add_argument("output", help="how much output is required. Number or belt.") parser.add_argument("--manuf", default="assembler3", help="manufactory to use for recipe") parser.add_argument( "--modules", default="p3,p3,p3,p3", help="list of modules to use. " 'comma separated, count prefixed; e.g "e2,s2", "s3,3p3"', ) parser.add_argument( "--recipe-version", default="expensive", help='which recipe costs to use. "normal" or "expensive"', ) args = parser.parse_args(sys.argv[1:]) Recipe.initialize(which=Recipe.Version(args.recipe_version)) recipe = Recipe.by_name(args.recipe) modules = [] raw_modules = args.modules.split(",") for rawmod in raw_modules: if rawmod[0] in "123456789": mod = Item.Module.by_name(rawmod[1:]) count = int(rawmod[0]) else: mod = Item.Module.by_name(rawmod) count = 1 modules.extend(count * [mod]) manuf = Manuf.by_name(args.manuf).value try: num_output = Frac(args.output) except TypeError: num_output = Belt.by_name(args.output).value if num_output > 45: raise NotImplementedError( "Outputs of greater than one blue belt not supported!") elif num_output <= 0: raise ValueError("Output must be positive!") prod_manuf = manuf.with_recipe(recipe).with_modules(modules) print("Info/Params: optimizing with parameters:") pprint(vars(args)) prod_manuf.solve_report(num_output)
def test_scalar_product(n=33): legs = legendre(n) selection = [0, 5, 7, n - 1] for i in selection: for j in selection: assert (scalar_product(legs[i], legs[j]) == ((i == j) and Frac(2, 2 * i + 1)))
def __mul__(self, x): """ >>> NoteLength(1, 4) * 2 NoteLength(1, 2) >>> NoteLength(1, 4) * 0.5 NoteLength(1, 8) """ return self.__class__(Frac(self) * x)
def __truediv__(self, x): """ >>> NoteLength(1, 4) * 2 NoteLength(1, 2) >>> NoteLength(1, 4) * 0.5 NoteLength(1, 8) """ return self.__class__(Frac(self) / x)
def loads(self, data): take = lambda prefix: (line.replace(prefix, "", 1).strip() for line in data if line.startswith(prefix)) take1 = lambda prefix: next(take(prefix)) # I know that this isn't perfect, but it's the most convenient way to do it try: self.title = take1("#Title") except StopIteration: self.title = "Escape from Math Island!" self.text = "\n".join(take("#Text")) self.start = Coord(*map(int, take1("#Start").split())) self.end = Coord(*map(int, take1("#End").split())) self.startfuel = Frac(take1("#Fuel")) self._map = [[Tiles[c] for c in line.replace(" ","").strip()] for line in data if line.strip() and not line.startswith("#")] self.height = len(self._map) self.width = len(self._map[0]) self.fuel = {Coord(int(x), int(y)): Frac(f) for x, y, f in [ line.split() for line in take("#Refuel")]}
def with_modules(self, modules: t.List[Item.Module]) -> BaseManuf: if len(modules) > self.module_slots: raise ValueError( f"Too many modules for a {self.name} manufactory!") if (self.recipe and any(m.prod != Frac(0) for m in modules) and not self.recipe.proddable): raise ValueError( "Assigning productivity modules to non-proddable recipe!") return dc_replace(self, modules=modules)
def with_recipe(self, recipe: Recipe) -> BaseManuf: print(recipe) if (self.modules and any(m.prod != Frac(0) for m in self.modules) and not recipe.proddable): raise ValueError( "Assigning non-proddable recipe to manuf. with prodmods!") if recipe.category not in self.recipe_cap: raise ValueError(f"Recipe ({recipe.category})incompatible with " f"this manufactory ({self.recipe_cap}") return dc_replace(self, recipe=recipe)
def legendre(n): """Return the first n Legendre polynomials. The polynomials have *standard* normalization, i.e. int_{-1}^1 dx L_n(x) L_m(x) = delta(m, n) * 2 / (2 * n + 1). The return value is a list of list of fraction.Fraction instances. """ result = [[Frac(1)], [Frac(0), Frac(1)]] if n <= 2: return result[:n] for i in range(2, n): # Use Bonnet's recursion formula. new = (i + 1) * [Frac(0)] new[1:] = (r * (2 * i - 1) for r in result[-1]) new[:-2] = (n - r * (i - 1) for n, r in zip(new[:-2], result[-2])) new[:] = (n / i for n in new) result.append(new) return result