Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

Python에서 주어진 제약 조건을 사용하여 최소와 최대 사이의 공통 분수를 찾는 프로그램

<시간/>

두 개의 긴 정수 값 최대값과 최소값이 있다고 가정합니다. min <=d <=max가 되는 공통 분수 n/d를 찾아야 합니다. 그리고 |n/d - 파이| 가장 작습니다. 여기서 pi =3.14159265... 그리고 이 조건을 유지하는 분수가 두 개 이상 있으면 분모가 가장 작은 분수를 반환합니다.

따라서 입력이 최소 =1 최대 =10과 같으면 출력은 22/7이 됩니다.

이 문제를 해결하기 위해 다음 단계를 따릅니다. −

  • P :=분수 (5706674932067741 / 1816491048114374) - 3
  • a :=0, b :=1, c :=1, d :=1
  • farey :=쌍의 배열, 처음에는 (a, b) 및 (c, d) 두 쌍이 있습니다.
  • 다음을 무조건 반복 -
    • f :=b + d
    • f> 최대 - 최소인 경우
      • 루프에서 나오다
    • :=a + c
    • 페어리 끝에 쌍(e, f) 삽입
    • P <(e/f)의 값이면
      • c :=e 및 d :=f
    • 그렇지 않으면
      • a :=e 및 b :=f
  • p_min :=(P * 최소값)의 바닥
  • 최소 <=최대, do
    • c :=0, d :=0
    • 페어리의 각 쌍(a, b)에 대해 다음을 수행합니다.
      • 최소값 + b> 최대값이면
        • 루프에서 나오다
      • if |(p_min + a)/ (최소 + b) - P| <|p_min / 최소값 - P|, 다음
        • c :=a, d :=b
        • 루프에서 나오다
    • d가 0과 같으면
      • 루프에서 나오다
    • p_min :=p_min + c
    • o 최소값 :=최소값 + d
    • o 반환 분수(p_min + 3 * 최소값) / 최소값

예시

이해를 돕기 위해 다음 구현을 살펴보겠습니다. −

from fractions import Fraction

def solve(minimum, maximum):
   P = Fraction(5706674932067741, 1816491048114374) - 3

   a, b, c, d = 0, 1, 1, 1
   farey = [(a,b),(c,d)]

   while True:
      f = b + d
      if f > maximum - minimum:
         break

      e = a + c
      farey.append((e, f))
      if P < Fraction(e, f):
         c, d = e, f
      else:
         a, b = e, f

   p_min = int(P * minimum)

   while minimum <= maximum:
      c, d = 0, 0
      for a, b in farey:
         if minimum + b > maximum:
            break
         if abs(Fraction(p_min + a, minimum + b).real - P) < abs(Fraction(p_min, minimum).real - P):
            c, d = a, b
            break
      if d == 0:
         break
      p_min += c
      minimum += d
   return ("{}/{}".format(p_min + 3 * minimum, minimum))

minimum = 1
maximum = 10
print(solve(minimum, maximum))

입력

4, 27

출력

22/7