示例#1
0
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=}")
示例#2
0
 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
示例#3
0
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)
示例#4
0
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
示例#5
0
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)
示例#6
0
 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
示例#7
0
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):]]