태그 보관물: rational-numbers

rational-numbers

첫 번째주기 숫자 삭제 쓰면 결과는 다음과 같습니다. 0.9 761904 761904 761904

우리는 합리적인 숫자가 십진수로 쓰여질 때마다 결과가 종료되거나 (결과적으로) 주기적이라는 것을 알고 있습니다. 예를 들어 41/42를 10 진수로 쓰면 결과는 다음과 같습니다.

0.9 761904 761904 761904 761904 761904 761904 761904 ...

초기 자릿수 0.9순서 761904와 순서가 반복해서 반복됩니다. (이것에 대한 편리한 표기법 0.9(761904)은 괄호가 반복 자릿수 블록을 둘러싸 는 곳입니다.)

이 과제의 목표는 양의 유리수를 취하고 반복 시퀀스의 일부인 첫 번째 숫자를 삭제 한 후 결과 유리수를 반환하는 것입니다. 예를 들어, 41/42로이 작업을 수행하면

0.9  61904 761904 761904 761904 761904 761904 761904 ...

또는 0.9(619047)짧게 말하면 101/105입니다.

유리수에 1/4 =와 같이 종료 소수점 확장이 있으면 0.25아무 일도 일어나지 않습니다. 1/4 0.250000000...또는 1/4로 생각할 수 0.249999999...있지만 두 경우 모두 반복 부분의 첫 번째 숫자를 삭제하면 숫자가 변경되지 않습니다.

세부

  • 입력은 분자와 분모를 나타내는 양의 정수 쌍 또는 (선택한 언어에서 허용하고 원하는 경우) 일종의 유리수 객체로 양의 유리수입니다.
  • 결과는 또한 어느 형식이든 합리적인 숫자입니다. 결과가 정수이면 유리수 대신 정수를 반환 할 수 있습니다.
  • 한 쌍의 숫자를 입력으로 받아들이면 상대적으로 소수라고 가정 할 수 있습니다. 출력으로 한 쌍의 숫자를 생성하는 경우 상대적으로 소수 여야합니다.
  • 반복 블록을 시작하는 첫 번째 숫자를 찾으십시오 . 예를 들어, 41/42를 쓸 수는 0.97(619047)있지만 2041/2100 (소수점 확장 0.97(190476))을 올바른 답으로 만들지는 않습니다 .
  • 당신이 얻는 입력에서 첫 번째주기 숫자는 소수점 뒤에 있다고 가정 하여 120/11= 10.909090909...유효하지 않은 입력 : (첫 번째주기 숫자는 0in 으로 간주 될 수 있음 10). 그러한 입력에 대해 원하는 것을 할 수 있습니다.
  • 이것은 . 가장 짧은 솔루션이 승리합니다.

테스트 사례

41/42 => 101/105
101/105 => 193/210
193/210 => 104/105
104/105 => 19/21
1/3 => 1/3
1/4 => 1/4
2017/1 => 2017/1
1/7 => 3/7
1/26 => 11/130
1234/9999 => 2341/9999


답변

Wolfram Language (Mathematica) , 59 바이트

FromDigits@MapAt[RotateLeft@*List@@#&,RealDigits@#,{1,-1}]&

온라인으로 사용해보십시오!

설명

RealDigits@#

입력의 10 진수를 찾으십시오.

MapAt[RotateLeft@*List@@#&, ..., {1,-1}]

반복되는 숫자가 있으면 RotateLeft 입니다. ( List@@#이성수가 종료되는 경우 코드가 마지막 10 진수 회전을 시도하지 못하게합니다).

FromDigits@

합리적인 것으로 변환하십시오.


답변

젤리 , 36 32 31 30 바이트

Outgolfer Erik 덕분에 -1 바이트 !

ọ2,5Ṁ⁵*©×Ɠ÷µ×⁵_Ḟ$+Ḟ,®×³+.Ḟ÷g/$

온라인으로 사용해보십시오!

정확해야합니다. 부동 소수점 부정확도에 대해 3 바이트를 추가합니다 +.Ḟ.

입력을 되돌릴 수없는 것에 의존합니다.


설명

이것은 다음에 의존합니다 :

  • 분자를 n/d가장 간단한 형태로 만드십시오 . 그런 다음 ọ2,5Ṁ적용되는 링크 d는 기수 포인트 다음에 비 주기적 숫자를 제공합니다.

ọ2,5Ṁ⁵*©×Ɠ÷µ×⁵_Ḟ$+Ḟ,®×³+.Ḟ÷g/$     Main link (monad take d as input)

    Ṁ                              Maximum
ọ                                  order of
 2,5                               2 or 5 on d
     ⁵*                            10 power
       ©                           Store value to register ®.
        ×Ɠ                         Multiply by eval(input()) (n)
          ÷                        Divide by first argument (d).
                                   Now the current value is n÷d×®.
           µ                       With that value,
            ×⁵                     Multiply by ⁵ = 10
              _Ḟ$                  subtract floor of self
                 +Ḟ                add floor or value (above)
                                   Given 123.45678, will get 123.5678
                                   (this remove first digit after `.`)
                   ,®              Pair with ®.
                     ׳            Scale
                       +.Ḟ         Round to integer
                          ÷g/$     Simplify fraction

답변

파이썬 2 , 237 (235) 214 바이트

Mr. Xcoder 덕분에 -21 바이트

from fractions import*
F=Fraction
n,d=input()
i=n/d
n%=d
R=[]
D=[]
while~-(n in R):R+=n,;n*=10;g=n/d;n%=d;D+=g,
x=R.index(n)
r=D[x+1:]+[D[x]]
print i+F(`r`[1::3])/F('9'*len(r))/10**x+F("0."+"".join(map(str,D[:x])))

온라인으로 사용해보십시오!

입력은 튜플로 수행됩니다 (numerator, denominator). 출력은 fractions.Fraction객체입니다.

이것은 긴 분할 스타일 방법을 사용하여 답의 시작 및 반복 숫자를 얻은 다음 첫 번째 반복 숫자를 끝으로 이동하고 문자열 조작을 사용 fraction.Fraction하여 비율로 다시 변환합니다.

언 골프 버전 :

import fractions

num, denom = input()
integer_part, num = divmod(num, denom)

remainders = []
digits = []
current_remainder = num
while current_remainder not in remainders:
    remainders.append(current_remainder)
    current_remainder *= 10
    digit, current_remainder = divmod(current_remainder, denom)
    digits.append(digit)

remainder_index = remainders.index(current_remainder)
start_digits = digits[:remainder_index]
repeated_digits = digits[remainder_index:]

repeated_digits.append(repeated_digits.pop(0))

start_digits_str = "".join(map(str, start_digits))
repeated_digits_str = "".join(map(str, repeated_digits))

print(integer_part+int(repeated_digits_str)/fractions.Fraction('9'*(len(repeated_digits_str)))/10**len(start_digits_str)+fractions.Fraction("0."+start_digits_str))

답변

파이썬 (3) , 177 (173) 169 바이트

from fractions import*
def f(n,d):
 i=1;r=[]
 while~-(i%d in r):r+=[i%d];i*=10
 r=10**r.index(i%d);u=i-r;v=i//r-1;t=u//d*n
 return Fraction(t-t%v+t%v*10//v+t%v*10%-~v,u)

온라인으로 사용해보십시오!


답변

Wolfram Language (Mathematica) , 70 67 바이트

-3 바이트에 대한 이 팁 덕분에 (삭제되었습니다)!

(x=10^Max@IntegerExponent[#,{2,5}];(Floor@#+Mod[10#,1])/x&[x#2/#])&

온라인으로 사용해보십시오!

젤리 답변 의 포트 . 기존 Mathematica보다 8 바이트 더 길다 …

이 기능은 다음 [denominator, numerator]과 같이 2 개의 입력 을 GCD[denominator, numerator] == 1받습니다.


답변

펄 6 , 102 바이트

{$/=.base-repeating;(+$0//$0~0)+([~]([$1.comb].rotate)/(9 x$1.chars)*.1**(($0~~/\.<(.*/).chars)if $1)}

시도 해봐

유리수를 가져 와서 유리수 또는 정수를 반환합니다 .

넓히는:

{  # bare block lambda with implicit Rational parameter 「$_」

  $/ = .base-repeating; # store in 「$/」 the two strings '0.9' '761904'

    # handle the non-repeating part
    (
      +$0        # turn into a number
      // $0 ~ 0  # if that fails append 0 (handle cases like '0.')
    )

  +

    # handle the repeating part
    (
          [~]( [$1.comb].rotate ) # rotate the repeating part
        /
          ( 9 x $1.chars )        # use a divisor that will result in a repeating number

        *

         # offset it an appropriate amount

         .1 ** (
           ( $0 ~~ / \. <( .* / ).chars # count the characters after '.'
         )

      if $1  # only do the repeating part if there was a repeating part
    )
}

uint64.Range.max더 큰 분모를 처리하기 위해 분모 를 다룰 FatRat(9 x$1.chars) 입니다. 사용해보십시오 .


답변