우리는 합리적인 숫자가 십진수로 쓰여질 때마다 결과가 종료되거나 (결과적으로) 주기적이라는 것을 알고 있습니다. 예를 들어 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...
유효하지 않은 입력 : (첫 번째주기 숫자는0
in 으로 간주 될 수 있음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)
것 입니다. 사용해보십시오 .