分数を繰り返し小数に変換する


17

この挑戦はほぼ正反対であり、私はそれがわずかに簡単になると思う。

あなたの仕事は、2つの整数を形式a/b(有理数の形成)で取得し、その数値を10進数で正確に出力することです。

たとえば、入力1/3すると、出力されます。

0.33333333333333333

また、オプションの先頭に0を付けて、時間の終わりまで3を印刷し続けます(言語で同じ行への印刷が許可されていない場合にのみ、 1行に1文字を印刷することもできます)。

の動作はx/0未定義です。繰り返していないように見える数字(たとえば5/4)については、実際に繰り返します。次の2つの形式のいずれかが受け入れられ5/4ます。

1.25000000000000000
1.24999999999999999

(整数で1.9999999も同じ、または2.000000

画分は、最も単純な形態であってもなくてもよく、aまたはb負(注かもしれ-a/b = -(a/b)-a/-b = a/ba/-b = -a/b、および-.6249999無効であるが、-0.6249999許容されていますが、まだ使用することができます。


Unixを使用できますかbc、それとも不正行為ですか?
デビッドRトリブル

缶を:私は私の答えをゴルフ続ける前aおよび/またはb負になりますか?
デニス

@Dennisはい。ただし、いずれab(または両方)が負になる場合があります)

@DavidRTribbleそれは標準的な抜け穴だと思うので、いいえ。

最新の編集では、負の数ではなく、正の数で先行ゼロは問題ないと述べていますか?もしそうなら、その理由は何ですか?
ジオビット

回答:


2

CJam、38 37バイト

l'/%:i2*~*0<'-*o:Dmd\zo'.{oA*Dmd\z1}g

使い方

l     e# Read line from STDIN.            STACK '17/-13'
'/%   e# Split at '/'.                    STACK ['17' '-13']
:i    e# Cast each element to int.        STACK [17 -13]
2*~   e# Duplicate and dump the array.    STACK 17 -13 17 -13
*     e# Multiply.                        STACK 17 -13 -221
0<    e# Compare with zero.               STACK 17 -13 1
'-*o  e# Print '-' that many times.       STACK 17 -13
:D    e# Save the topmost integer in D.   STACK 17 -13
md    e# Perform modular division.        STACK -1 4
\z    e# Swap and take absolute value.    STACK 4 1
o'.   e# Print and push '.'.              STACK 4 '.'
{     e# do:
  o   e#   Print.                         STACK 4
  A*  e#   Multiply by 10.                STACK 40
  Dmd e#   Divide modulo D.               STACK -3 1
  \z  e#   Swap and take absolute value.  STACK 1 3
  o   e#   Print.                         STACK 1
1}g   e# while(1)

あなたは二重除算を使用しているので、これは大きな数に対して完全に壊れていませんか?
orlp

@orlp:まったく。現在修正されています。
デニス

6

C、108 79

編集負の数で動作するように変更されました。

stdinからの入力。古いK&Rスタイル。

main(a,b){char*s="-%d.";scanf("%d/%d",&a,&b);for(a*b<0?(a<0?a=-a:(b=-b)):++s;printf(s,a/b);s="%d")a=a%b*10;}

4

ルビー、83 69 102 91 89バイト

->s{a,b=s.scan(/\d+/).map &:to_i
eval(s+?r)<0&&$><<?-
$><<a/b<<?.
loop{a=a%b*10
$><<a/b}}

コンピューターの整数除算に基づく手動整数除算の簡単な実装。

ゴルフの手助けをしてくれた@blutorangeに感謝します。

編集:負の数を含めるようにソリューションを修正しました。


2
ルビーでいくつかのショートカットを使用することで、これを66バイトにまで減らすことができます->s{a,b=s.split(?/).map &:to_i;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}。ルビーについてはこれが大好きです。
ブルトレンジ

うわー、私は多くのことを学びました、ありがとう!?/文字を表すことを覚えていなかった$><<し、印刷することやloopキーワードについても知らなかった。どうもありがとう!!
ロルク

1
どういたしまして、誰かが指摘するまでこれらのトリックの多くについては知りませんでした。$>略で$stdout、かつ<<演算子です。次の行に変更することで、2行目にもう1バイト保存できますc*d<0&&$><<?-。3行目から4行目をに結合して数バイト、最後の行の$><<a/b<<?.スペースを削除してもう1つ<<。そして、これを91バイトに->s{a,b=s.scan(/\d+/).map &:to_i;1==s.count(?-)&&$><<?-;$><<a/b<<?.;loop{a=a%b*10;$><<a/b}}
減らす

の構文が$><<a/b正しく機能しなかったため、そこにスペースを入れました。残りは良いようです、どうもありがとう!
ロルク

1
それでも興味がある場合は、ルビー2.1以降(10分前に学んだ)から2行目を短縮するために使用できる合理的なリテラルRational(2,3) == 2/3r)もありますeval(s+?r)<0&&$><<?-
。– blutorange

2

Java、177 176 170

s->{try{int x=new Integer(s.split("/")[0]),y=new Integer(s.split("/")[1]),z=1;for(;;x=x%y*10,Thread.sleep(999))System.out.print(x/y+(z-->0?".":""));}catch(Exception e){}}

アルゴリズムは簡単です。難しい部分は、印刷を機能させることでした。最後に、各ステップの間にコンピューターを1秒間スリープさせて、印刷できるようにしました。

拡張された実行可能なバージョン

public class RepeatedDecimal {
    public static void main(String[] args) {
        java.util.function.Consumer<String> f = s -> {
                try {
                    int x = new Integer(s.split("/")[0]),
                        y = new Integer(s.split("/")[1]),
                        z = 1;
                    for (;; x = x % y * 10, Thread.sleep(999)) {
                        System.out.print(x / y + (z-- > 0 ? "." : ""));
                    }
                } catch (Exception e) { }
                };

        f.accept("5/7");
    }
}

出力にはフラッシュの問題がありますが、2バイトを削る9ミリ秒間スリープすることで出力を表示することができました。

@SnowmanおそらくハードウェアまたはOSに依存します。私のコンピューターは250ms未満では動作しません。
Ypnypn

2

R、103 137 109 103

これで少し幸せになりました。区切り文字付きのスキャンを使用すると、多くのバイトを節約できます。まだ改善の余地があるかもしれません。に置き換えられまし<-=。常にこれで最高の運があったわけではありませんが、今回はうまくいきました。

cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)

テスト実行

> cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)
1: -1/3
3: 
Read 2 items
-0.33333333333333333333...
> cat(if(prod(i=scan(sep='/'))<0)'-',(n=(i=abs(i))[1])%/%(d=i[2]),'.',sep='');repeat cat((n=n%%d*10)%/%d)
1: -5/-4
3: 
Read 2 items
1.250000000000000000000...

1

Pythonの3、107の 115バイト

a,b=map(int,input().split("/"))
print(("%.1f"%(a/b))[:-1],end="")
b=abs(b)
while 1:a=abs(a)%b*10;print(a//b,end="")

とても簡単です:

  • 分子と分母を入力してください
  • 小数点以下1桁の商を出力し、最後の桁を外します(例-1/3-> -0.
  • 絶対値を取る*
  • ループ:
    • 分子は分母を分割した後の剰余です
    • 分子に10を掛ける
    • 次の桁として整数の商を出力します

*(ただし、計算aはループ内に移動して数バイトを節約しました。)

編集:負の分数> -1のバグを修正しました。


0

Python 2.7、209バイト

from sys import*;m,o=1,lambda x:stdout.write(str(x));a,b=[int(x)for x in argv[1].split('/')]
o(str(a*b)[0]);a,b=abs(a),abs(b);o('0'*(b>a))
while 1:
 while not((m*a)/b):o('0.'[m==1]);m*=10
 o((m*a)/b);a=(m*a)%b

編集:

尋ねられたように、同じ行にすべての文字を出力するようになりました。

edit2:

要求されたように、コマンドライン引数から分数を読み取ります:)


1
いくつかのヒント:1)mapリスト内包表記の代わりに使用すると、かなり節約できます。2)の周りに括弧を必要としないm*aように、その場所のいずれかで*%/すべて同じ優先順位と左結合されています。3)3行目の0またはドットロジックはに簡略化でき"0."[m==1]ます。とにかく印刷するだけなので、4)おそらく、必要に応じて数値引数をバックティック付きの文字列に設定o=stdout.writeおよび変換するだけで、文字を保存します。
DLosc

1
また、コードはネガで動作するように表示されません1/-3提供します-1.666666666代わりに-0.333333333
DLosc
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.