繰り返し小数を小数に変換します


23

この質問は、小数の終端だけに適用する必要はありません-小数の繰り返しは、アルゴリズムを介して分数に変換することもできます。

あなたの仕事は、入力として繰り返される小数をとるプログラムを作成し、その小数展開を生成する対応する分子と分母(最低条件で)を出力することです。1より大きい分数は、などの不適切な分数として表す必要があります9/5。入力が正であると仮定できます。

繰り返される小数はこの形式で与えられます:

5.3.87

次のように、2番目のドットの後のすべてが繰り返されます。

5.3878787878787...

プログラムは、分子(分母)を表す2つの整数をスラッシュ(またはプレーンテキストを出力しない場合は言語の同等の形式)で区切って出力します。

889/165

小数点の終了には、2番目のドットの後には何もありません。また、繰り返しのない小数部分のない小数点には、2つのドットの間に何もありません。

テストケース

これらのテストケースは、必要なすべてのコーナーケースをカバーしています。

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ですか(例:)?
ジャスティン14年

3
(in lowest terms)すなわち、分数を単純化する必要があります。
ジョーZ. 14年

2
13代わりに出力でき13/1ますか?
mniip

4
必ずこの入力1.9999...と出力を処理してください2/1
Thomas Eding

3
@ThomasEding 1.9999.19999/100002/1あなたが必要1..9とするために、そうではありませんか?
Qwertiy 14

回答:


8

Dyalog APL(75 73 69 68文字)

次に、もう1つ5番目の試み(おそらく最後の試み)を示します。80文字より短く、ルールに完全に一致するコードを記述しようと1日を費やしました。この挑戦は私の一日を作りました!

最終的に、Dyalog APLで動作する75文字で構成されるAPLの行を取得しました(ただし、 execute関数を使用しているため、オンラインインタープリターページではそうではありません)。

(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を減算します(with 1-⍨またはwithのいずれか¯1+、ここでは2番目を選択しました)。「1.2.3」は1009です。
  • 次に、この番号が文字列に変換され()、2つの最初の数字が削除され(2↓)、最初の「1.2.3」の例から09になります。文字列が反転されます()。
  • ここでは、特別な場合として、文字列の前に最初の0文字を追加します。4文字を使用するのは悲しくなり'0',ますが、2番目と3番目のフィールドが両方とも空の場合にエラーを回避するためにしました。文字列は数値()に変換され、Dに格納されます。Dは0に等しいため、両方の最後のフィールドが空の場合を除いて分母です。
  • D←D+0=コードの一部は、Dが現在nullである場合にDを1に設定し、Dには分母が含まれます(ただし、GCD除算の前)。
  • この分母は×、最初の文字列Iの内容で、(⍎'0',I/⍨2>+\P)Pから始まる2番目のドット(この例では0 1 0 1 0 )まで乗算され(0 1 1 2私の例では2)、どの値が2より小さいかを確認し(ブールベクトルを1 1 1 0 0にします)、Iで対応する文字を取得します。別のトラップを防ぐために文字列の前に別の0が追加され(2つの初期フィールドが空の場合)、全体が数値に変換されます。
  • 入力文字列の最後の部分は、を使用して前の製品に追加され、(⍎'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ます。なぜなのかご存知ですか?
ピーターテイラー14年

@ピーターテイラー:はい、それは私のメッセージでも言われています。これは、Dyalogのサーバーにとって安全ではない「実行」演算子を使用しており、オンラインで無効になっているためです(セーフモード)。Dyalog APLのインストール済みバージョンで試してみる必要があります。
トーマスバルチェル14年

ああ、恥。時折のPCG提出をテストするために60ユーロを費やすつもりはありません。別のオンラインAPLテスターを見つけましたが、ランクエラーまたは長さエラーを与えるため、コードにDyalog固有の何かがあるようです。
ピーターテイラー14年

@ピーターテイラー; いいえ;-) GNU APLで(まだ実験的で公式ではない)私自身のWebサイトを使用してください。しかし、互換性を持たせるために2つの文字を追加する必要がありました(1つを囲む括弧I):このパーマリンクを
トーマスバルチェル14年

15

Perl 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はcharscomb(数値コンテキストでは、数値への変換後の文字のリストは文字数であるため、同一である)に置き換えることを提案しました。

サンプル出力:

$ 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

残念ながら、2つのドット間のプレースホルダーとしてゼロを使用することはできません。0..09を返しますが1/11、を0.0.09返します1/110
ジョーZ. 14年

@JoeZ。ああ、わかった。何も入力されていない場合を処理するようにコードを更新しました。
コンラッドボロスキー14年

Perl 6を知りませんが、 'abc'が与えられた場合、プログラムはc / 99 ... 9を計算するために正確な有理数計算を使用しますが、abを計算するために浮動小数点のみを使用すると推測しますか?その場合、bの桁数が多いと、誤った答えが返されます。
オマー

@OmarAntolín-Camarena:まったく違います。Perl 6では、浮動小数点数ではなく有理数がデフォルトです。たとえば、0.1 + 0.2 == 0.3Perlの6中
コンラッド・ボロウスキ

2
80文字までゴルフ:$/=split ".",get;say join "/",($0+($1+$2/(9 x chars $2 or 1))/10**$1.chars).nude:)
Mouq 14年

6

J(85 90 89文字)

私の元の関数は、2番目の文字より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/1参照してください、infの最初の2つのテストケースこのコメント
mniip

@mniipという5文字のコストで整数の出力を修正しました。
オマー

('0','x',~])バイトを使用して保存します。
エルベックス14年

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文字に短縮)

完全に一般的ではありませんが、世界で最も古いものの1つでそれをやったことを考慮してください:

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
    

    OK

  • 2番目と1番目のフィールドには少なくとも1桁が必要です


5

Javascript、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

用事...私は...それは今働いているので、私は何かを間違っをしたと思います
rafaelcastrocouto

1
b=1内部のパーツを動かすことで1キャラクターを保存できますprompt()
user2428118 14

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'場合、値はn + p/E + q/(DE) = ((nD + p)E + q)/DEwhere D = 10^(len p)およびですE = 10^(len q) - 1ただし when を除きlen q = 0、その場合E = 1(0による除算を避けるため)。

解剖:

           # 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

各テスト入力でプログラムを1つずつ実行することをシミュレートするオンラインデモ


私はそれを試してみましたが、すべてのルールに従っていないようです:「小数点の終了には2番目のドットの後に何もありません。また、繰り返しのない小数部分のない10進数には2つのドットの間に何もないことに注意してください」入力があるとあなたのコードを動作させることができませんでした0.1.
トーマスバルチェル

-1。あなたが+300ポイントを獲得したことに気付いた後、私はもう一度それを再試行しました。他のソリューションがすべてのルールに従うために最善を尽くしたので、それは公平ではありません。
トーマスバルチェル14年

@ברוכאל、私は規則に従おうとしなかったというあなたの主張に反対します。オプションのテストケースの位置は、最終ブロックが必要なすべてのケースをカバーしていると考えるように私を混乱させました。私が間違っていたことがわかりました。他の人が同じ間違いをするのを避けるために、間もなく質問を編集します。これまで未処理のコーナーケースを処理するためにコードを更新し、それを実証するためのテストへのリンクを更新しました。
ピーターテイラー14年

それで大丈夫です。おそらく300ポイントに値するでしょう。CodeGolfが初めてなので、これらの300ポイントは私にとってやりがいのある目標であり、期限にコードがルールに完全に適合するには最短であると考えながら、それらを獲得できなかったことに失望しています。とにかく、私はポイントを獲得するために私の人生をすべて持っています。よろしく。
トーマスバルチェル14年

@ברוכאל:私は500ポイントを獲得したかった(そう、私はそのように寛大だ、私はそれを減らすことができないわけではない)バウンティ、そしてそれらのポイントをあなたに与えたが、すでにバウンティが始まったと思う。まあ、何でも。この賞金がいつ終了するのか、誰がそれらのポイントを獲得するのか、私は疑問に思っています。
コンラッドボロスキー14年

2

Python

ライブラリなし-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」ではなく「Fraction(7、5)」などを出力します。
オマー

そうではありません。ちなみに、私は一番上のものが機能していません。_=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-CamarenaAFAIK、print利用str可能な場合に使用しますrepr。これは私の終わりの出力です:puu.sh/7w64w.png
Oberon

@tomsmeding両方が1行にあります。答えに合うように改行が追加されました。_=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)すべてを1行で入力する必要があります。
オベロン14年

ああ、@ Oberon、おそらく私がコンピューターにいなかったので、コードを実行できなかったと推測できます。
オマー14年

2

Mathematica、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として出力するように見えます。そうですか?(私のソリューションには同じバグがあります... :()
オマー

ああ、今、私は参照してください...コメントで指定されています。どのような奇妙な要件...他のすべての割合が削減される場合、なぜn/1削減することを許可しないのnですか?後で整数を変換するために、余分な〜50バイトを追加します。
ジョナサンヴァンマトレ

あなたのアプローチは問題ありません。私も利用している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ます。私は望んでいないので、第1または第3桁の数字がない分数はサポートしていません。ただし、仕様に一致する2番目の桁のグループを持たない分数をサポートしています。
mniip

@minip、仕様を読み間違えました:「..および.1.2をサポートしたい場合」とは言わず、「望むなら、0 ..および0.1.2が常に..および.1.2 "。
オマー

@OmarAntolín-Camarenaポイントを取った。編集済み。
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

ライブラリを使用しない2つのPythonの回答。Firstは、最初の前に数字なしでオプションの入力を処理します。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)

2番目は最初の数字の前に何も処理しませんが、必要なすべての入力を正しく処理し、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 14年

@mniip私はコードゴルフが苦手です。少なくとも1文字の変数名を使用しました。
PyRulez 14年

1
言語または使用された文字/バイトの合計量を指定したことはありません。
ジャスティンフェイ14年

2
{;}を使用して、インデントのスペースを節約し、spansを実装し、関数の短いエイリアスを追加し、可能であればスペースを削除します。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}- NBは321から178文字、ダウンTrueと同義であるがotherwisenull zあるlength z==0
bazzargh

2

JavaScript(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

Mathematica 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


あなたの出力は間違ったフォーマットであり、あまりにもきれいです。
オマー

奇妙なことに、これは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桁が必要です。


1

JavaScript(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ます。
トッドリーマン

また、switchステートメントをに書き換えることで、さらにいくつかを節約できると思いますif(c==46) n[++i]=1; else d[i]=10*d[i]+c-48,n[i]*=10;
トッドリーマン

-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
コンパイラがこの言語で自由に利用できるようになるまで、私はそれを使用するすべての答えに投票します。
ガレス

1
上記のリンクページにコンパイラがあるようですか?
skibrianski

参照してください@skibrianski メタにこのポストを
mniip

2
@Gareth、あなたがダウン票をするためのMathematicaの回答もいくつかあります。:P
オマー

2
@OmarAntolín-CamarenaMathematica用のコンパイラ/インタプリタがあります。GTBにはありません。GTBあなたが私を信じていない場合は、上記のリンクに従ってください。プロプライエタリなプログラム用に圧縮されたものを入手し、そのプログラムを検索すると、ダウンロードを提供していると主張しているサイトには利用できないと表示されます。それでは、どのようにコンパイルしますか?
ガレス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.