반복되는 10 진수를 분수로 변환


23

이 질문 은 단지 소수를 종료하는 데 적용 할 필요는 없습니다. 반복 소수는 알고리즘을 통해 분수로 변환 할 수도 있습니다.

당신의 임무는 반복 된 십진수를 입력으로 사용하는 프로그램을 만들고, 그 십진 확장을 생성하는 해당 분자와 분모를 (최저의 용어로) 출력하는 것입니다. 1보다 큰 분수는와 같은 부적절한 분수로 표시해야합니다 9/5. 입력이 긍정적이라고 가정 할 수 있습니다.

반복되는 소수점은 다음 형식으로 제공됩니다.

5.3.87

다음과 같이 두 번째 점 이후의 모든 것이 반복됩니다.

5.3878787878787...

프로그램은 분자와 분모를 나타내는 두 개의 정수를 슬래시 (또는 일반 텍스트를 출력하지 않는 경우 해당 언어의 해당 형식)로 구분하여 출력합니다.

889/165

종료 소수점은 두 번째 점 다음에 아무 것도 없으며 반복되지 않는 소수 부분이없는 소수점은 두 점 사이에 아무 것도 없습니다.

테스트 사례

이 테스트 케이스는 필요한 모든 코너 케이스를 다룹니다.

0..3 = 1/3
0.0.3 = 1/30
0.00.3 = 1/300
0.6875. = 11/16
1.8. = 9/5
2.. = 2/1
5..09 = 56/11
0.1.6 = 1/6
2..142857 = 15/7
0.01041.6 = 1/96
0.2.283950617 = 37/162
0.000000.1 = 1/9000000
0..9 = 1/1
0.0.9 = 1/10
0.24.9 = 1/4

원하는 경우 정수 부분이없는 분수는 첫 번째 점의 왼쪽에 아무것도 없다고 가정 할 수도 있습니다. 다음과 같은 선택적 테스트 사례를 사용하여 테스트 할 수 있습니다.

.25. = 1/4
.1.6 = 1/6
..09 = 1/11
.. = 0/1

1
분수를 단순화해야합니까? 아니면 단순화되지 않은 형태로 두는 것이 합리적 9/99입니까 (예 :) ?
Justin

3
(in lowest terms)즉 분수를 단순화해야합니다.
Joe Z.

2
13대신에 출력이 허용 13/1됩니까?
mniip

4
이 입력 1.9999...및 출력 을 처리하십시오2/1
Thomas Eding

3
@ThomasEding는 1.9999.것입니다 19999/10000얻을, 2/1당신은 필요 1..9, 그렇지?
Qwertiy

답변:


8

Dyalog APL ( 75 73 69 68 자)

여기 또 다른 다섯 번째 시도 (대부분 나의 마지막 시도)가 있습니다. 나는 하루에 80 문자보다 짧은 코드를 작성하고 규칙과 완전히 일치하도록 노력했습니다. 이 도전은 나의 하루를 만들었다!

마침내 Dyalog APL과 함께 작동하는 75 문자로 구성된 APL 행을 얻었습니다 (그러나 실행 기능을 사용하기 때문에 온라인 인터프리터 페이지 에는 없음). 다음과 같습니다.

(N,D)÷D∨N←(⍎'0',1↓I/⍨2=+\P)+(⍎'0',I/⍨2>+\P)×D←D+0=D←⍎'0',⌽2↓⍕¯1+10⊥P←'.'=I← '1.2.3'

물론 나는 그것을 더 짧게 만들 수는 있지만 1, 2 또는 3 개의 필드가 누락 된 특별한 경우입니다. 내 코드는 ..입력 사례를 처리 할 수도 있습니다 .

나는 APL을 읽기가 어렵다는 것을 알고 있으며 사람들은 실제로 코드 조각이 어떻게 작동하는지 이해하기 때문에 여기에 몇 가지 설명이 있습니다. 기본적으로 변수 D의 최종 분모와 변수 N의 최종 분자를 계산합니다.

APL은 오른쪽에서 왼쪽으로 구문 분석됩니다.

  • 먼저 문자열은 변수 I ( I←)에 저장됩니다 .
  • 그런 다음 점이있는 위치를 나타내는 부울 벡터로 매핑되며이 벡터를 P ( P←'.'=) 라고 합니다. 예를 들어 '1.2.3'은 0 1 0 1 0에 매핑됩니다.
  • 이 벡터는 밑이 10 인 자릿수입니다 ( 10⊥). 이제 '1.2.3'은 1010입니다.
  • 그런 다음 1 은이 숫자에서 뺍니다 (와 함께 1-⍨또는로 ¯1+, 여기서 두 번째를 선택했습니다). 이제 '1.2.3'은 1009입니다.
  • 그런 다음이 숫자는 문자열 ( ) 로 변환되고 두 개의 초기 숫자가 제거되고 ( 2↓) 초기 '1.2.3'예제에서 09를 만듭니다. 문자열이 반전됩니다 ( ).
  • 특별한 경우에, 나는 문자열 앞에 초기 0 문자를 추가합니다; 네 문자를 사용하면 슬프지만 '0',두 번째와 세 번째 필드가 모두 비어있을 때 오류를 피하기 위해 노력 했습니다. 문자열은 다시 숫자 ( ) 로 변환 되고 D에 저장됩니다. D는 0이므로 두 마지막 필드가 모두 비어있는 경우를 제외하고는 분모입니다.
  • D←D+0=1 코드 세트의 D 부분은 현재 널인 경우, 현재는 D (GCD 분할 전의 그러나) 분모를 포함한다.
  • 이 분모 ×에는 초기 문자열 I의 내용과 (⍎'0',I/⍨2>+\P)P에서 다시 시작 하는 두 번째 점까지 ( )를 곱하고 (이 예제에서는 0 1 0 0) 연속 숫자를 누적하여 더합니다 (0 1 1 2를 만듭니다) 내 예에서는 2), 2보다 작은 값을 확인하고 (부울 벡터 1 1 1 0 0 만들기) I에서 해당 문자를 가져옵니다. 다른 트랩을 방지하기 위해 문자열 앞에 다른 0이 추가되고 (두 초기 필드가 비어있는 경우) 전체가 숫자로 변환됩니다.
  • 입력 문자열의 마지막 부분은을 사용하여 이전 제품에 추가됩니다. (⍎'0',1↓I/⍨2=+\P)이는 P를 다시 받고, 다시 계산하여 추가하고, 어떤 값이 2인지 확인합니다 (이전 설명 참조), 문자를 가져오고 점인 첫 번째 문자를 제거합니다. , 방지 초기 0 문자를 추가하고 숫자로 변환합니다.
  • 이 곱 다음에 합계가 분자 인 N에 저장됩니다.
  • 마지막으로 GCD는 D∨N으로 계산되며 두 숫자는이 GCD로 나뉩니다.

편집 : 73 문자에 대한 수정 사항은 다음과 같습니다.

(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←D+0=D←⍎'0',⌽2↓⍕¯1+10⊥P←'.'=I←

이 핵의 개념은 누적 덧셈이 2와 같은 값을 갖는 경우를 먼저 계산하여 나중에 저장하고 첫 번째 경우를 얻기 위해이 비트 마스크를 뒤집는 것입니다. 따라서 다음 경우를 계산하는 데 적은 문자가 필요합니다.

편집 : 다음은 69 자의 또 다른 수정 사항입니다.

(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←⍎'1⌈0',⌽2↓⍕¯1+10⊥P←'.'=I←

이 핵의 개념은 평가할 문자열에 문자열을 숫자로 변환하는 단계에서 가장 복잡한 특수 사례를 APL 코드로 포함시키는 것입니다.

편집 : 여기 68 문자에 대한 또 다른 수정 사항이 있습니다.

(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←⍎'1⌈0',⌽3↓⍕1-10⊥P←'.'=I←

이 해킹의 개념은 1을 빼기위한 에 1을 빼기위한 -1을 더한 값을 1 로 빼는 조작으로 시작한 다음 처음에 한 문자 이상 (빼기 부호)을 제거하는 것입니다.

편집 : 화장품 변경 :

(N,D)÷D∨N←(⍎'0',1↓P/I)+(⍎'0',I/⍨~P←2=+\P)×D←1⌈⍎'0',⌽3↓⍕1-10⊥P←'.'=I←

크기는 개선되지 않았지만 평가할 코드 에서 최대 기능 을 얻는 데 더 만족합니다 .


나는 이것을 tryapl.org로 실행하려고 시도했으며 불평 INVALID TOKEN합니다. 왜 그런지 아십니까?
피터 테일러

@ 피터 테일러 : 예, 그것은 심지어 내 메시지에 언급되어 있습니다; 이것은 Dyalog 서버에 안전하지 않고 온라인에서 비활성화 된 "execute"연산자를 사용하기 때문입니다 (안전 모드). 설치된 버전의 Dyalog APL에서 시도해야합니다.
Thomas Baruchel

아, 수치심 가끔 PCG 제출을 테스트하기 위해 60 유로를 쓰지 않을 것입니다. 다른 온라인 APL 테스터를 찾았지만 순위 오류 또는 길이 오류가 발생하기 때문에 코드에 Dyalog 고유의 것으로 보입니다.
피터 테일러

@ 피터 테일러; 아니오 ;-) GNU APL과 함께 자체 웹 사이트 (아직 실험적이지 않고 공식적인 웹 사이트)를 사용하십시오. 그러나 나는 호환되도록 두 문자를 추가해야했습니다 (1 주위의 괄호 I).이 permalink
Thomas Baruchel

15

펄 6 (93 101 100 80 68 66 바이트)

$/=split ".",get;say ($0+($1+$2/(9 x$2.comb||1))/10**$1.comb).nude

실패하지 않고 아무것도 처리 할 수 ​​있도록 크기가 늘어났습니다. Mouq는을 사용 $/하도록 제안 했으므로 현재 사용되고 있으며 코드는 20 바이트 더 짧습니다. Ayiko는로 대체 /할 것을 제안 했으므로 코드는 더 짧아집니다 (12 바이트). Mouq는 다음과 같이 대체 chars할 것을 제안 했습니다 comb(숫자 문맥에서는 숫자로 변환 한 후 문자 목록이 문자 수이므로 동일 함).

샘플 출력 :

$ perl6 script.p6
5.3.87
889 165
$ perl6 script.p6
2.0.0
2 1
$ perl6 script.p6
0..3
1 3
$ perl6 script.p6
0.0.3
1 30
$ perl6 script.p6
0.0.0
0 1
$ perl6 script.p6
0.1.6
1 6
$ perl6 script.p6
0.01041.6
1 96
$ perl6 script.p6
0.2.283950617
37 162
$ perl6 script.p6
123.456.789
41111111 333000

불행히도, 두 점 사이의 자리 표시 자로 0을 사용하는 것은 끝이 없습니다. 0..09을 반환 1/11하지만을 0.0.09반환합니다 1/110.
Joe Z.

@JoeZ. 오 그래. 아무것도 입력되지 않은 경우를 처리하기 위해 코드를 업데이트했습니다.
Konrad Borowski

Perl 6을 모르지만 'abc'가 주어지면 프로그램이 정확한 합리적 산술을 사용하여 c / 99 ... 9를 계산하지만 부동 소수점 만 사용하여 ab를 계산한다는 것이 맞습니까? 이 경우 b에 많은 숫자가 있으면 잘못된 대답을 제공합니다.
Omar

@ OmarAntolín-Camarena :별로. Perl 6에서는 합리적인 소수점 숫자가 아닌 합리적인 값이 기본값입니다. 예를 들어, 0.1 + 0.2 == 0.3Perl 6에서
Konrad Borowski

2
80 문자 골프 : $/=split ".",get;say join "/",($0+($1+$2/(9 x chars $2 or 1))/10**$1.chars).nude:)
Mouq

6

J ( 85 90 89 자)

두 번째보다 5 문자가 짧은 내 원래 함수에는 몇 가지 버그가 있습니다. 정수를 "n / 1"로 출력하지 않았으며 12 자리 이상의 숫자가있는 숫자에 잘못된 대답을주었습니다. 다음은 문자를 저장하기 위해 Eelvex의 제안을 통합하는 J의 수정 된 함수입니다.

f=:3 :0
'a t'=.|:(".@('0','x',~]),10x^#);._1'.',y
(,'/'&,)&":/(,%+.)&1+/a%*/\1,0 1-~}.t
)

문자열을 받아서 문자열을 반환합니다. 샘플 세션은 다음과 같습니다.

   f '..'
0/1
   f '0.0.0'
0/1
   f '3..'
3/1
   f '..052631578947368421'
1/19
   f '0.2.283950617'
37/162
   f '.0.103092783505154639175257731958762886597938144329896907216494845360824742268041237113402061855670'
1/97

처음 두 테스트 사례 를 출력 0/1하고 3/1inf로 함수를 수정해야합니다. 이 주석
mniip

@mniip 5 자의 비용으로 정수의 출력을 수정했습니다.
Omar

('0','x',~])바이트를 사용 하고 저장 하십시오 .
Eelvex

5

C, 171

꽤 길다. 더 줄일 수 있습니다. 아니 scanf점 사이의 번호가없는 경우 정말 그것을 처리 할 수있다. 없음 strtol. 번호 크 런칭 :

a,b,c,d,q;main(){while((q=getchar()-48)>-3)q<0?(d=b>0,b+=!b):d?(c=c*10+q,d*=10):(a=a*10+q,b*=10);for(a=a*--d+c,q=b*=d;q>1;a%q+b%q?--q:(a/=q,b/=q));printf("%d/%d\n",a,b);}

테스트:

rfc <<< "2..142857"
15/7

5

DC (일반적이지 않고 76 자로 단축 됨)

완전히 일반적인 것은 아니지만 제발, 내가 세상에서 가장 오래된 것들 중 하나와 함께 한 것을 고려하십시오.

5.3.87 dsaX10r^d1-rla*sasbdscX10r^dlc*rlb*rlb*la+snsdlnld[dSarLa%d0<a]dsax+dldr/rlnr/f

편집 : 솔루션을 편집합니다. 더 일반적이지 않지만 조금 더 짧습니다.

sadsbX10r^sclaX10r^dd1-dsdlblc**rla*+dsnrld*dsd[dSarLa%d0<a]dsax+dldr/rlnr/f

다음과 같이 사용하십시오.

5.3.87 sadsbX10r^sclaX10r^dd1-dsdlblc**rla*+dsnrld*dsd[dSarLa%d0<a]dsax+dldr/rlnr/f
  • 첫 번째 필드는 필요하지 않습니다 :

    .1.3 sadsbX10r^sclaX10r^dd1-dsdlblc**rla*+dsnrld*dsd[dSarLa%d0<a]dsax+dldr/rlnr/f
    

    괜찮습니다.

  • 두 번째 및 갈증 필드에는 하나 이상의 숫자가 필요합니다


5

자바 스크립트, 203

너무 길지만 여전히 재미 있습니다. 세미콜론을 읽을 수 없으므로 줄 바꿈.

s=prompt(b=1).split(".")
P=Math.pow
a=s[0]
c=s[1]
d=P(10,l=c.length)
f=(P(10,s[2].length)-1)*P(10,l)||1
e=s[2]=+s[2]
a=d*a+b*c;b*=d
a=f*a+b*e;b*=f
function g(a,b){return b?g(b,a%b):a}g=g(a,b);a/g+"/"+b/g

내가 889/NaN달릴 때 나는 점점 5.3.87... 내가 뭔가 잘못하고 있습니까?
rafaelcastrocouto

모르겠다 ... Safari 콘솔에이 코드를 붙여 넣기 만하면 (Firefox 또는 Chrome도 수행해야 함) Enter 키를 누르고 "5.3.87"을 입력 "889/165"하면 콘솔에 들어갑니다. 어떻게 운영하고 있습니까? @rafaelcastrocouto
tomsmeding

nevermind ... 나는 그것이 지금 일하고 있기 때문에 내가 잘못한 것 같아요 ...
rafaelcastrocouto

1
b=1부품을 안으로 이동하여 1 개의 문자를 저장할 수 있습니다 prompt().
user2428118

1
f=(P(10,s[2].length)-1)*P(10,l),f=f?f:1=>f=(P(10,s[2].length)-1)*P(10,l)||1
f.ardelian

3

J (다른 방법)

매우 다른 방법에 기반한 다른 솔루션. 이번에는 완전히 일반적입니다. 정수가 제출 될 때 1- 분모 만 누락됩니다.

   ".((({.~(i.&1)),'+'"_,((":@(10&^)@#,'%~',])@}.@#~~:/\),'+%',((,~(##'9'"_),'%x:0'"_)@}.@#~2:=+/\@]))(=&'.')) '.1.3'
2r15
   ".((({.~(i.&1)),'+'"_,((":@(10&^)@#,'%~',])@}.@#~~:/\),'+%',((,~(##'9'"_),'%x:0'"_)@}.@#~2:=+/\@]))(=&'.')) '.1.'
1r10
   ".((({.~(i.&1)),'+'"_,((":@(10&^)@#,'%~',])@}.@#~~:/\),'+%',((,~(##'9'"_),'%x:0'"_)@}.@#~2:=+/\@]))(=&'.')) '1..'
1
   ".((({.~(i.&1)),'+'"_,((":@(10&^)@#,'%~',])@}.@#~~:/\),'+%',((,~(##'9'"_),'%x:0'"_)@}.@#~2:=+/\@]))(=&'.')) '1..3'
4r3

3

GolfScript (67 자)

`{'.'/1$=.10\,?@-).!+0@+~}+3,/1$4$*]-1%~;*+*+].~{.@\%.}do;{/}+/'/'@

NB 빈 정수 부분을 지원합니다.

문자열이 양식 인 'n.p.q'경우 값은 when을 제외한n + p/E + q/(DE) = ((nD + p)E + q)/DE where D = 10^(len p)및이며 E = 10^(len q) - 1, 이 경우 0으로 나누지 않습니다.len q = 0E = 1

해부:

           # Stack: 'n.p.q'
`{         # Combined with the }+ below this pulls the value into the block
           # Stack: idx 'n.p.q'
    '.'/   # Stack: idx ['n' 'p' 'q']
    1$=    # Stack: idx str   (where str is the indexed element of ['n' 'p' 'q'])
    .10\,? # Stack: idx str 10^(len str)
    @-)    # Stack: str 10^(len str)-idx+1
           #   If idx = 0 we don't care about the top value on the stack
           #   If idx = 1 we compute D = 10^(len 'p')
           #   If idx = 2 we compute E' = 10^(len 'q') - 1
    .!+    # Handle the special case E'=0; note that D is never 0
    0@+~   # Stack: 10^(len str)-idx+1 eval('0'+str) (GolfScript doesn't treat 011 as octal)
}+         # See above
3,/        # Run the block for idx = 0, 1, 2
           # Stack: _ n D p E q
1$4$*      # Stack: _ n D p E q D*E
]-1%~;     # Stack: D*E q E p D n
*+*+       # Stack: D*E q+E*(p+D*n)
].~        # Stack: [denom' num'] denom' num'
{.@\%.}do; # Stack: [denom' num'] gcd
{/}+/      # Stack: denom num
'/'@       # Stack: num '/' denom

한 번에 하나씩 각 테스트 입력으로 프로그램 실행을 시뮬레이트하는 온라인 데모 .


나는 그것을 시도했지만 모든 규칙을 따르지 않는 것 같다 : "소수점 종료는 두 번째 점 다음에 아무 것도 없으며 반복되지 않는 소수 부분이없는 소수는 두 점 사이에 아무 것도 없다." 입력으로 코드를 작동시킬 수 없었습니다0.1.
Thomas Baruchel

-1. +300 포인트를 얻은 것을 발견 한 후 다시 시도했습니다. 다른 해결책들이 당신이 분명히하지 않은 모든 규칙을 따르기 위해 최선을 다했기 때문에 공평하지 않습니다.
Thomas Baruchel

@ ברוכאל, 나는 규칙을 따르려고 시도하지 않았다는 당신의 주장에 반대합니다. 선택적 테스트 사례의 위치는 최종 블록이 필요한 모든 사례를 다루었다는 생각으로 혼란 스러웠습니다. 내가 틀렸다는 것이 밝혀졌으며 다른 사람들이 같은 실수를하지 않도록 질문을 곧 편집 할 것입니다. 이전에 처리되지 않은 코너 사례를 처리하기 위해 코드를 업데이트하고 테스트를위한 링크를 업데이트했습니다.
피터 테일러

괜찮아. 당신은 아마 300 점을받을 자격이 있습니다. CodeGolf를 처음 접했을 때이 300 점은 도전적인 목표였으며 마감 시간에 코드가 규칙에 완벽하게 부합하는 최단 시간이라고 생각하는 동안 이러한 점을 얻지 못한 것에 대해 여전히 실망했습니다. 어쨌든, 나는 포인트를 얻기 위해 평생을 가지고 있습니다. 문안 인사.
Thomas Baruchel

@ ברוכאל : 나는 500 포인트를 시작하고 싶었습니다 (예, 관대하고, 줄 수는 없습니다) 바운티를 제공하지만 이미 바운티가 시작된 것 같습니다. 뭐든간에 이 현상금이 언제 끝나고 누가 그 포인트를 얻을지 궁금합니다.
Konrad Borowski

2

파이썬

라이브러리 없음-156 자

_=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),
(10**len(c)-bool(c))*10**len(b);f=_(d,e);print'%i/%i'%(d/f,e/f)

사용 fractions-127 자

from fractions import*;a,b,c=raw_input().split('.');print Fraction(int(a+b+c)-bool(c)*int(a+b
),(10**len(c)-bool(c))*10**len(b))

fractions버전을 인쇄 같은 것들 "분수 (7, 5)"대신 "7/5"는, 그렇지 않습니다?
Omar

그렇지 않습니다. 그건 그렇고, 나는 최고의 사람을 얻지 못하고 있습니다. _=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b), ValueError: need more than 1 value to unpack
tomsmeding

@ OmarAntolín-Camarena AFAIK는 print사용 str가능한 경우가 아니라 사용 repr합니다. 이것은 내 끝의 출력입니다 : puu.sh/7w64w.png
Oberon

@tomsmeding 둘 다 한 줄에 있습니다. 줄 바꿈은 답변에 맞게 추가되었습니다. _=lambda a,b:b and _(b,a%b)or a;a,b,c=raw_input().split('.');d,e=int(a+b+c)-bool(c)*int(a+b),(10**len(c)-bool(c))*10**len(b);f=_(d,e);print'%i/%i'%(d/f,e/f)한 줄로 가야합니다.
Oberon

아, @Oberon, 내가 컴퓨터에 없었고 코드를 실행할 수 없었을 것입니다.
Omar

2

매스 매 티카, 143

평소와 같이 Mathematica는 작업을 수행하는 많은 고급 기능을 제공하지만 자세한 이름을 제공합니다.

x=StringTake;c=ToExpression;p=s~StringPosition~".";{o,t}=First/@p;u=StringLength@s-t;d=t-o-1;Rationalize@(c@x[s,t-1]+c@x[s,-u]/((10^u)-1)/10^d)

시간이 있으면 나중에 추가 할 샘플 출력입니다.


마치 정수가 n / 1이 아닌 n으로 출력되는 것처럼 보입니다. 맞습니까? (내 솔루션에는 같은 버그가 있습니다 ... :()
Omar

아, 이제는 .... 코멘트에 명시되어 있습니다. 다른 모든 부분이 감소하면 어떻게 이상한 요구 ... 왜 허용하지 n/1에 감소 n? 나중에 정수를 변환하기 위해 여분의 ~ 50 바이트를 추가하겠습니다.
Jonathan Van Matre

당신의 접근은 괜찮습니다. 내 것이 사용 FromDigits하기 때문에 게시하기로 결정했습니다.
DavidC

2

루비-112

x,y,z=gets.chop.split".";y||='0';z||='0';puts((y.to_i+Rational(z.to_i,10**z.length-1))/10**y.length+x.to_i).to_s

이것은 루비에 대한 첫 번째 실험이므로 개선을 제안하십시오.

$ ruby20 % <<< '5.3.87'
889/165
$ ruby20 % <<< '0..3'
1/3
$ ruby20 % <<< '0.0.3'
1/30
$ ruby20 % <<< '0.00.3'
1/300
$ ruby20 % <<< '0.6875.0'
11/16
$ ruby20 % <<< '1.8.0'
9/5
$ ruby20 % <<< '2..'
2/1
$ ruby20 % <<< '..'
0/1

지원 ".."및 ".1.2"를 제거하면 사양을 따르지 않는 것입니다. 그렇지 않습니까?
Omar

@ OmarAntolín-Camarena이 시점에서 스펙은 다음과 같이 말합니다 If you wish. 나는 원하지 않기 때문에 첫 번째 또는 세 번째 숫자 그룹이없는 분수는 지원하지 않습니다. 그러나 나는 두 번째 자릿수 그룹이없는 분수를 지원하고 있으며 이는 스펙과 일치합니다.
mniip

@minip, 당신은 스펙을 잘못 읽었습니다. "만약 당신이 ..와 .1.2를 지원할 수 있다면"이라고 말하지 않고, 당신이 원한다면, 당신은 항상 0 ..과 0.1.2가 .. 및 .1.2 ".
Omar

@ OmarAntolín-Camarena Point 촬영. 편집했습니다.
mniip

2

C, 164

이것은 처음부터 수행했지만 오리온의 C 솔루션과 유사합니다. 그러나 나는 그의 많은 최적화를 훔쳤다고 고백합니다. 훨씬 짧지는 않지만 .25를 처리합니다. = 1/4 및 0.000000.1 = 1/9000000.

long a,b,c,d,e;main(){while((c=getchar()-48)>-3)c+2?a=a*10+c,b*=10:b?e=a,d=b:(b=1);
b>d?a-=e,b-=d:0;for(d=2;d<=a;)a%d+b%d?d++:(a/=d,b/=d);printf("%ld/%ld\n",a,b);}

2

라이브러리가없는 두 개의 파이썬 답변. 첫 번째 앞에 숫자없이 선택적 입력을 처리합니다. 그리고 162 자입니다

_=lambda a,b:b and _(b,a%b)or a;i,t,r=raw_input().split(".");b=r!="";d=(10**len(r)-b)*10**len(t);n=int((i+t+r)or 0)-b*int((i+t)or 0);f=_(d,n);print "%i/%i"%(n,d)

두 번째는 첫 번째 숫자 앞에 아무것도 처리하지 않지만 필요한 모든 입력을 올바르게 처리하고 150 자입니다.

_=lambda a,b:b and _(b,a%b)or a;i,t,r=raw_input().split(".");b=r!="";d=(10**len(r)-b)*10**len(t);n=int(i+t+r)-b*int(i+t);f=_(d,n);print "%i/%i"%(n,d)

2

하스켈

import Data.Ratio
f n=case s '.' n of
    [x,y,z]->(r x)%1+(r y)%(10^(length y))+(r z)%((10^t-1)*(10^(length y)))
        where
            r ""=0
            r n=read n
            t = if length z==0 then 9 else length z
s _ []=[[]]
s n (x:xs) | x==n = []:(s n xs)
           | otherwise = let (l:ls)=s n xs in (x:l):ls

이봐, 이것은 코드 골프입니다, 당신은 시도조차하지 않습니다!
mniip

@ mniip 저는 코드 골프를 잘 못합니다. Atleast 저는 단일 문자 변수 이름을 사용했습니다.
PyRulez

1
언어 또는 사용 된 총 문자 / 바이트 수를 지정하지 않았습니다.
Justin Fay

2
{;}를 사용하여 들여 쓰기 공간을 절약하고을 span구현하고 함수의 짧은 별명을 추가하고 가능한 경우 공간을 제거하십시오. import Data.Ratio v=span(/='.');w=tail;l=length;f n=(r x)%1+(r y)%p+(r z)%((10^t-1)*p)where{(x,b)=v n;(y,d)=v(w b);z=w d;p=10^(l y);r""=0;r n=read n;t=if null z then 9 else l z}- 178 개 문자, 아래로 321에서 NB는 True동의어가되어 otherwise, null zlength z==0
bazzargh

2

자바 스크립트 (ECMA 스크립트 6) 180 175

G=(a,d)=>d?G(d,a%d):a;P=a=>+("1e"+a);L=a=>a.length;f=prompt().split(".");B=P(L(b=f[1]));D=P(L(b)+L(c=f[2]))-P(L(b))||1;alert((m=(f[0]+b||0)*D+B*(c||0))/(g=G(m,n=B*D))+"/"+n/g)

300 현상금의 확실한 승자는 아니지만 ... 이것은 내가 얻을 수있는 가장 짧은 것입니다.

  • 이전 버전의 변경 사항 : 논리가 약간 변경되고 몇 가지 문자를 저장하는 대신 P변경 하여 전원 기능이 변경되었습니다 .+("1e"+a)Math.pow(10,a)

1

매스 매 티카 175

f@i_:=
If[IntegerQ[g=FromDigits[Map[IntegerDigits@ToExpression@#&,StringSplit[i,"."]/.""-> {}]
/.{a_,b_,c_}:> {{Sequence@@Join[a,b],c},Length@a}]],HoldForm[Evaluate@g]/HoldForm@1,g]

대부분의 루틴은 입력을 마사지합니다. 약 50 개의 문자가 정수 처리에 사용되었습니다.


f["7801.098.765"]

frac1

더 많은 예 :

TableForm[
 Partition[{#, f[#]} & /@ {"19..87", "19.3.87", "5.3.87", "0.0.3", "0..3", "0.2.283950617", 
"123.456.789", "6666.7777.8888", "2.0.0","0.0.0"}, 5], TableSpacing -> {5, 5}]

frac2


Mathematica에서 일반적으로 달성되는 방법

FromDigits입력이 특정 형식 인 경우 반복 반복 십진수에서 직접 분수를 얻을 수 있습니다. 정수는 정수로 표시됩니다.

z={{{1, 9, {8, 7}}, 2}, {{1, 9, 3, {8, 7}}, 2}, {{5, 3, {8, 7}}, 1}, {{{3}}, -1}, {{{3}}, 0}, 
{{2, {2, 8, 3, 9, 5, 0, 6, 1, 7}}, 0}, {{1, 2, 3, 4, 5, 6, {7, 8, 9}}, 3}, 
{{6, 6, 6, 6, 7, 7, 7, 7, {8}}, 4}, {{2}, 1}, {{0}, 1}}

FromDigits/@z

z


출력 형식이 잘못되었습니다. 너무 예쁩니다.
Omar

이상하게도, 이것은 Mathematica에서 분수를 표현하기위한 기본 형식입니다. 이 형식을 더 간단한 형식으로 변경하려면 몇 개의 문자가 더 필요합니다.
DavidC

1

J (96 자)

슬래시 기호를 구분 기호로 사용하지 않습니다 (그러나 Mathematica의 솔루션은 그래도 더 나은 그래픽 표현을 사용하기 때문에 사용하지 않습니다). J 언어에서 분수는 다음과 r같이 표시됩니다 /.

   (((-.@]#[)((".@[%#@[(10x&^)@-{.@])+({.@](10x&^)@-#@[)*<:@{:@](".%<:@(10x&^)@#)@}.[)I.@])(=&'.')) '1..3'
4r3
   (((-.@]#[)((".@[%#@[(10x&^)@-{.@])+({.@](10x&^)@-#@[)*<:@{:@](".%<:@(10x&^)@#)@}.[)I.@])(=&'.')) '123.456.789'
41111111r333000

1

APL (완전히 일반적인 것은 아님)

완전하지는 않습니다 (DC 솔루션과 같습니다). Dyalog APL과 함께 작동합니다 (그러나 Dyalog APL의 온라인 버전에는 해당되지 않습니다).

(R,F)÷(F←D×N)∨R←(⍎C)+D×(⍎I/⍨2>+\P)×N←10*¯1++/≠\P⊣D←¯1+10*⍴C←1↓I/⍨2=+\P←'.'=I← '123.456.789'

첫 번째 필드는 선택 사항이지만 다른 두 필드에는 하나 이상의 숫자가 필요합니다.


1

자바 스크립트 (189)

i=prompt().split(".");a=i[0];b=i[1];c=i[2];B=b.length;p=Math.pow;n=a+b+c-(a+b);d=p(10,B+c.length)-p(10,B);f=1;while(f){f=0;for(i=2;i<=n;i++)if(n%i==0&&d%i==0){n/=i;d/=i;f=1}};alert(n+"/"+d)

예:

입력:

5.3.87

산출:

889/165

1

C (작성한대로 420 자, 불필요한 공백을 제거한 후 줄임)

이것은 64 비트 long(예 : 64 비트 Linux)를 가정합니다 . 0.2.28395061732 비트를 사용하는 시스템 에서는 테스트 케이스가 실패합니다 long. 유형을 long long변경하고 printf그에 따라 형식 문자열 을 변경하면 일부 문자를 희생하여 해결할 수 있습니다 .

#include <stdio.h>

long d[3], n[3], i;

int main(int c, char** v)
{
  while (c = *v[1]++)
    switch(c)
    {
    case '.':
      n[++i] = 1;
      break;
    default:
      d[i] = 10 * d[i] + c - '0';
      n[i] *= 10;
    }

  n[2] -= n[2] != 1;

  while (i--)
    d[2] += d[i] * n[i+1], n[i]*=n[i+1];

  i = d[2];
  *n = n[1];

  while (i)
    *d = i, i = *n%i, *n = *d;
  printf("%ld/%ld\n", d[2]/ *n, n[1]/ *n);
}

좋은. 로 변경 '0'하여 1 개의 문자를 면도 할 수 있습니다 48.
Todd Lehman

switch문을 다음과 같이 다시 작성하면 약간 더 절약 할 수 있습니다 if(c==46) n[++i]=1; else d[i]=10*d[i]+c-48,n[i]*=10;.
Todd Lehman

-3

GTB , 81

`_:s;_,1,l?_)-S;_,"."
s;A;,1,S;_,".")-1
s;_,1+S;_,"."),l?_)-S;_,"."))→_
x?A;+_)►Frac

?3.25.
            13/4

4
컴파일러가이 언어를 자유롭게 사용할 수있게 될 때까지, 나는 그것을 사용하는 모든 답을 공감할 것이다.
Gareth

1
위에 링크 된 페이지에 컴파일러가있는 것 같습니다.
skibrianski


2
@Gareth, 당신은 downvote에 대한 몇 가지 Mathematica 답변이 있습니다. : P
Omar

2
@ OmarAntolín-Camarena Mathematica를위한 컴파일러 / 통역사가 있습니다. GTB는 없습니다. GTB당신이 나를 믿지 않으면 위 의 링크를 따르십시오 . 독점적 인 프로그램에 대한 압축 된 내용을 얻은 다음 해당 프로그램을 검색하여 다운로드를 제공한다고 주장하는 사이트에서 사용할 수 없다고 말합니다. 그래서 어떻게 컴파일합니까?
Gareth
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.