def get_prob(tile, char): is_prime = isprime(tile) if (is_prime and char == P) or (not is_prime and char == N): return Frac(2, 3) elif (is_prime and char == N) or (not is_prime and char == P): return Frac(1, 3) raise Exception(f"no option, {tile=}, {char=}")
def __init__(self, p1: Point, p2: Point): super().__init__(p1, p2, should_calc_mb=False) self.p1 = Point(Frac(p1.x), Frac(p1.y)) self.p2 = Point(Frac(p2.x), Frac(p2.y)) m, b = self.get_mb() self.m: Frac = m self.b: Frac = b self.is_m_inf = self.m == inf
def ans(): generated_list: List[int] = generate_list(100) generated_list.reverse() f: Frac = Frac(generated_list[0]) for i in generated_list[1:]: f = Frac(i) + f.flip() n = f.simplify().n return digits_sum(n)
def ans(): max_d = 10**6 best_frac = Frac(0) # get all fractions close to 3/7 for i in range(1, max_d + 1): if i % 7 == 0: continue fi = Frac((3 * i) // 7, i) if best_frac < fi: # and they are for sure smaller than 3/7 best_frac = fi return best_frac.n
def ans(): seq = "PPPPNNPPPNPPNPN"[::-1] max_tile = 500 probabilities: List[List[Frac]] = list() # first char probabilities.append( [Frac(0)] + [get_prob(tile, seq[0]) for tile in range(1, max_tile + 1)]) # next chars for i, c in enumerate(seq[1:]): probs_01 = [Frac(0), probabilities[i][2] * get_prob(1, c)] prob_500 = [probabilities[i][max_tile - 1] * get_prob(max_tile, c)] probs_others = [ get_prob(tile, c) * Frac(1, 2) * (probabilities[i][tile - 1] + probabilities[i][tile + 1]) for tile in range(2, max_tile) ] probabilities.append(probs_01 + probs_others + prob_500) return sum(probabilities[-1], Frac(0)) * Frac(1, max_tile)
def intersection_point(self, other: QLine, possible_parallel: bool = True) -> Optional[Point]: """ intersecting point between lines. uses the code of intersection check for speed-up: if we called the is_intersecting func we would calculate basically the same thing twice :param other: other line :return: intersecting point of the lines. None if no intersection """ if possible_parallel and self.m == other.m: if self.b == other.b: return None if self.p1 in {other.p1, other.p2}: return self.p1 if self.p2 in {other.p1, other.p2}: return self.p2 return None # else, they are not parallel, they either intersect in a single point, or do not intersect # if self is parallel to the y axis. we know other is for sure not, because they are not parallel if self.is_m_inf: # get the y of the other line at the x value of the inf line line1_x = self.p1.x if not other.is_in_x_range(line1_x): return None inter_y = other.m * line1_x + other.b if self.is_in_y_range(inter_y) and other.is_in_y_range(inter_y): return Point(line1_x, inter_y) return None # if other is parallel to the y axis. we know self is for sure not, because they are not parallel elif other.is_m_inf: return other.intersection_point(self) """ # calculate the x,y of the intersection based on the known formula, but the point may be anywhere in the grid. problem: this way of calculating is very heavy, it creates 3 Frac objects. so we should find the best optimal formula that is one-time Frac calculation: We want to calculate: (other.b - self.b) / (self.m - other.m). sm,om,sb,ob = self.m,other.m,self.b,other.b """ sm, om, sb, ob = self.m, other.m, self.b, other.b top_top = ob.n * sb.d - ob.d * sb.n top_bot = ob.d * sb.d bot_top = sm.n * om.d - om.n * sm.d bot_bot = sm.d * om.d inter_x: Frac = Frac(top_top * bot_bot, top_bot * bot_top) # return True if the point of intersection is exactly on the line cuts that are self and other if self.is_in_x_range(inter_x) and other.is_in_x_range(inter_x): inter_y: float = self.m * inter_x + self.b return Point(inter_x, inter_y) return None
def continued_fraction_of_sqrt(x: int) -> List[int]: """ returns the coefficients cycle of the continued fraction of sqrt(input). empty list if input is perfect square :param x: number to get continued fraction of its square :return: the coefficients cycle of the continued fraction of sqrt(input) """ sqrt_x: float = math.sqrt(x) if sqrt_x.is_integer(): return [] s: Set[QPair] = set() # set of all pairs of QPairs l: List[QPair] = list() # list of these pairs, the result cycle # create the initial pair start_value: FracWithSqrt = FracWithSqrt(Frac(1), Frac(0), x) pair: QPair = start_value.split_int_nonint() # calculate the continued fractions until we get a repetition while pair not in s: s.add(pair) l.append(pair) # get new pair r: FracWithSqrt = pair.rem.flip() pair = r.split_int_nonint() # the whole parts of the pairs until the repetition in the cycle return [i.whole for i in l[l.index(pair):]]