첫 번째주기 숫자 삭제


17

우리는 합리적인 숫자가 십진수로 쓰여질 때마다 결과가 종료되거나 (결과적으로) 주기적이라는 것을 알고 있습니다. 예를 들어 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

2017대신에 돌아갈 수 있을까요 2017/1?
JungHwan Min

예, 합리적인 숫자 일을하고 있다면. (정수 한 쌍을하고 있다면, 그 쌍을 제외하고는 다른 것이 무엇인지 확실하지 않습니다 (2017,1).)
Misha Lavrov

입력을 줄일 수 있습니까? 예를 들어, 2/4입력에서 발생할 수 있습니까?
user202729

1
입력이 120/11정답 111/11이거나 210/11?
kasperd

2
@kasperd Huh, 그것은 내가 생각하지 않은 경우입니다 ... 111/11순간에 가장 고도로 찬성 한 답변이 반환된다는 것을 제외하고 말하고 싶습니다 210/11. 기존 답변이 무효화되는 것을 피하도록 선택할 것입니다.
Misha Lavrov

답변:


13

Wolfram Language (Mathematica) , 59 바이트

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

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

설명

RealDigits@#

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

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

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

FromDigits@

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


참으로 영리하다!
DavidC

6

젤리 , 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


@EriktheOutgolfer 감사합니다!
user202729

5

파이썬 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))



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) 입니다. 사용해보십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.