分数を単純化する


8

勝者:イアンD.スコットの回答、1バイト(48バイト)ずつ!見事!

プログラムは、簡略化できる部分からの入力を受け入れ、それを単純化する必要があります。

ルール:

  • 分数が既に最も単純な形式である場合は、ユーザーに通知する必要があります
  • これを行う組み込み関数はありません
  • ユーザーはある時点で数値を入力する必要がありますが、プログラムがそれを読み取る方法は重要ではありません。stdin、console.readlineなどを使用できます。ある時点で9/18(たとえば)ユーザーが入力する限り、有効です。
  • 出力はstdout、console.writelineなどで行う必要があります。
  • 分数はとしてx/y入力され、次のように出力する必要がありますa/b
  • 分数は最も単純な形式を出力する必要があります。たとえば、8/12-> 6/9は無効であり、有効なソリューションは2/3のみです。

  • このコンテストは2014年8月9日に終了します(投稿から7日間)
  • これは質問なので、最短のコードが勝ちます

1
どのようにユーザーに通知すべきですか?
2014

Stdout、console.writelineなど
Jon

7
これは本当に非常に小さな問題です。あなたがしていることは、gcd(しばしば組み込まれているが、書くのは難しくない関数)で除算することだけです。
カルバンの趣味

1
@ Calvin'sHobbiesええ、問題自体は簡単です。最短のコードでそれを行うのは簡単ではありません。
Jon

3
「分数がすでに最も単純な形である場合、ユーザーに通知する必要がある」とはどういう意味ですか?入力を返すだけでなく、特定のメッセージが必要ですか?もしそうなら、私は受け入れられた答えがこれを満たしていません。
マーティンエンダー、2015

回答:


1

パイソン-69 48

最初にすることは、分数を格納するためのpythonのネイティブ形式、つまりFractionクラスでそれを表現することです。

print(__import__("fractions").Fraction(input()))

今、私たちは単純化しています...しかし見てください!すでに簡略化されています。

これは組み込み関数の使用としてカウントされますか?特に単純化を目的としたものではなく、Fractionは関数ではなくクラスです。

私は単純化関数を呼び出さなかったので、pythonがそれ自体を行うことに決めたのは私のせいではありません。


しかし、そのクラスのコンストラクタは関数ですか?
flawr

@flawr type(fractions.Fraction.__init__)wrapper_descriptorではなくを返すfunctionので、関数ではないと言えます。これは実際にはcで実装されていることを意味しますが、クラス関数にないものは関数ではありませんよね?
イアンD.スコット

2
-1:これは組み込みです。名前に「単純化」とは書かれていませんが、分数を単純化しています。
Cyoce

5

> <>(92)

0v
+>>>>>>a*ic4*-:0(?v
v@:{:~^?=2l0  ,a~ <
>:?!v:@%
=1:~<;no-1*4c,n,@:/?
|oooo;!'simplest' /

私はこれを低くすることができることを知っています、私は午前中にもう少しゴルフをします。

基本的な説明:最初の2行と3行目の後半は、すべて数字を読むためのものです。悲しいことに、> <>にはそれを行う方法がないため、解析はプログラムの半分を占めます。

4行目は、単純な反復gcd計算です。実際のアルゴリズムのバイトカウントで> <>がどれだけうまく機能したかに驚いています。ひどいI / Oがなければ、それは実際には妥当なゴルフ言語である可能性があります。

最後の2行は、結果を出力し、元の数値をgcdで除算するためのものです。


実際には、golfscriptを除くすべての人よりも優れています。いいね!
誇り高いハスケラー、2014

もはや本当ではない:-(
誇り高いhaskeller 14


3

JavaScript 101

一応、EcmaScript 6を使用しないソリューション

v=prompt().split('/');for(a=v[0]|0,b=v[1]|0;a-b;)a>b?a-=b:b-=a;
alert(a>1?v[0]/a+'/'+v[1]/a:'Reduced')

しかしE6では93

[n,d]=prompt().split('/');for(a=n|0,b=d|0;a-b;)a>b?a-=b:b-=a;
alert(a>1?n/a+'/'+d/a:'Reduced')

1
for([a,b]=[c,d]=prompt().split('/');b;[a,b]=[b,a%b]);alert(a-1?c/a+'/'+d/a:'Reduced'); 86私はそれが...数学的に正しい願っています
ベベ

2

Python 2.7、124

from fractions import gcd;x,y=map(int,raw_input().split('/'));g=gcd(x,y);print'%d/%d'%(x/g,y/g)if g!=1 else'Already reduced'

非常に単純な解決策ですが、他の多くの言語では短くなることはわかっています。

私はインポートされgcdたものを使用しましたが、組み込みのフラクションリデューサーとしてカウントされる場合は、直接実装できます。


2

Python 2(82)

A,B=a,b=map(int,raw_input().split("/"))
while b:a,b=b,a%b
print`A/a`+"/"+`B/a`,a<2

その後、ブール値を出力して、オリジナルが最も単純な形式であったかどうかを示します。通常のGCDアルゴリズムを実行するだけです。ほとんどの文字は入出力に費やされます。


Python 3を使用する方が短いとinput()思いませんか?
mbomb007 2015

@ mbomb007久しぶりですが、そこに保存された4文字は、Python 3で括弧を必要としprintmapアンパックされ、浮動小数点除算ではなく整数で失われるだけではありません。
XNOR

分割を忘れました。それだけでは「価値がない」ことになります。map開梱についてどういう意味ですか?
mbomb007 2015

@ mbomb007私の間違いは、自動的に解凍されるa,b=map(int,...)ため、余分な文字を必要としませんa,b=...。Python 3で時々遭遇する問題はmap、リストを生成しないが、スライスのようなことを行う前にリストに変換する必要があるマップオブジェクトである。代わりにリストとして*l,=map(...)割り当てるにlは、次のような式が必要です。
xnor


1

C、94

力ずくで推測して確認してください。GCDがa | bから1に始まっていることを確認します。

main(a,b,c){scanf("%d/%d",&a,&b);for(c=a|b;--c;)if(a%c+b%c<1)a/=c,b/=c;printf("%d/%d\n",a,b);}

83: c;d;f(a,b){b?f(b,a%b):printf("%d/%d",c/a,d/a);}main(){scanf("%d/%d",&c,&d);f(c,d);}
2014

0

レブム(104文字)

P"/"rSst[a b]paSp AtiA BtiB Ca DbFOiMNcD 1 -1[izADmdCiMDdI[CdvCi DdvDi]]QapAPtsCpTSdIa^e?aCe?bD[Q"Err"]Q

アンマッシュ:

P"/"
rS
; extract numerator to a, denominator to b
st [a b] pa s p
; convert a,b to integers
AtiA
BtiB
; set c=a, d=b
Ca Db
; loop from min(c,d) to 1
fo i mn c d 1 -1[
    ; check if (c mod i) + (d mod i) is 0
    iz ad md c i md d i [
        ; divide c, d by i
        Cdv c i
        Ddv d i
    ]
]
; set Q to c/d
Qap ap ts c p ts d
; check if a==c and b==d
i a^ e? a c e? b d[
    ; set q to "err"
    Q"err"
]
; print q
Q

0

PHP 156

ええ。

$f=$argv[1];$p=explode('/',$f);$m=max(array_map('abs',$p));for(;$m;$m--)if(!($p[0]%$m||$p[1]%$m)){$r=$p[0]/$m.'/'.$p[1]/$m;break;}echo $r===$f?'reduced':$r;

実行:

php -r "$f=$argv[1];$p...[code here]...:$r;" 9/18;
1/2
  • 分数が既に最も単純な形式の場合、「縮小」を出力します
  • 負の分数で動作します
  • 不適切な分数で動作します(例:150/100は3/2を与えます)
  • ちょっと小数で動作します(たとえば、1.2 / 3.6は0.75 / 2.25を与えます)
  • 99/0が誤って1/0を与える
  • 整数にはなりません(例:100/100は1/1になります)

これは、いくつかのテストを行った(関数形式に変更された)ゴルフ前のバージョンです。

<?php
$a = array(
    '9/18','8/12','50/100','82/100','100/100','150/100','99/100',
    '-5/10','-5/18','0.5/2.5','1.2/3.6','1/0','0/1','99/0'
);
print_r(array_map('r',array_combine(array_values($a),$a)));

function r($f) {
    $p = explode('/',$f);
    $m = max(array_map('abs',$p));
    for ( ; $m; $m-- )
        if ( !($p[0] % $m || $p[1] % $m) ) {
            $r = $p[0]/$m.'/'.$p[1]/$m;
            break;
        }
    return $r === $f ? 'reduced' : $r;
}
/*
Array(
    [9/18] => 1/2
    [8/12] => 2/3
    [50/100] => 1/2
    [82/100] => 41/50
    [100/100] => 1/1
    [150/100] => 3/2
    [99/100] => reduced
    [-5/10] => -1/2
    [-5/18] => reduced
    [0.5/2.5] => 0.2/1
    [1.2/3.6] => 0.75/2.25
    [1/0] => reduced
    [0/1] => reduced
    [99/0] => 1/0
)
*/
?>

0

Java、361 349 329(ヒントを提供してくれた@Siegに感謝int

class P{public static void main(String[]a){String[]e=a[0].split("/");String f="";int g=new Integer(e[0]),h=new Integer(e[1]);if(g>h){for(int i=h;i>=1;i--){if(g%i==0&&h%i==0){f=g/i+"/"+h/i;break;}}}else if(g<h){for(int i=g;i>=1;i--){if(g%i==0&&h%i==0){f=g/i+"/"+h/i;break;}}}else if(g.equals(h)){f="1/1";}System.out.println(f);}}

私はそれが短くないことを知っていますが、私は自分のしたことに夢中になっています。

これを使用するには、コードをコンパイルし、コマンドラインから引数を渡して実行します。

  • 整数のみ(私は好きではなくdoubles、タスクはそれを必要としません)。
  • 分数が既に簡略化されている場合は、それ自体を返します。
  • 負の分数では機能しません。
  • ゼロ除算?Cookieはありません(空の文字列を返します)。

Ungolfed(誰もがこの混乱を見たい場合):

class P{
    public static void main(String[]a){
        String[]e=a[0].split("/");
        String f="";
        int g=new Integer(e[0]),h=new Integer(e[1]);
        if(g>h){
            for(int i=h;i>=1;i--){
                if(g%i==0&&h%i==0){
                    f=g/i+"/"+h/i;
                    break;
                }
            }
        }else if(g<h){
            for(int i=g;i>=1;i--){
                if(g%i==0&&h%i==0){
                    f=g/i+"/"+h/i;
                    break;
                }
            }
        }else if(g.equals(h)){
            f="1/1"; //no processing if the number is THAT obvious.
        }
        System.out.println(f);
    }
}

1
本番のコードでも、のint代わりに実際に使用する必要がありIntegerます。Intはスタックから割り当てられ、integerはヒープから割り当てられます。
Seequ

@Slegまあ、私はそれを知らなかった、どうもありがとう。
g.carvalho97 2014

次に、本番環境では使用しないでください。呼び出すだけでとnew Integer(str)同じ結果になりInteger.parseInt(str)ます。また、なぜString f=""(常に)使用しないのですか?
Seequ

@ジークありがとうございます。なぜですか?文字列からout をnew Integer(str)作成するIntegerことは知っていInteger.parseInt(str)ますが、同じことをしませんか?とのことString f=""、私はそれを使うべきだと知ってString f=new String()いますが、なぜ私がそれをしないのか分かりません、おそらくそれは悪い習慣です:P
g.carvalho97

1
Integer.parseInt確かに同じことを行いますが、より高速な検索のためにいくつかのキャッシュされた値があります。
Seequ

0

ルビ— 112文字

g2つの整数のGCDを計算するヘルパーラムダです。fは、分数を文字列として受け取り、たとえば'42/14'、分数を削減したりsimplest、分子と分母が比較的素数である場合に出力します。

g=->a,b{(t=b;b=a%b;a=t)until b==0;a}
f=->z{a,b=z.split(?/).map &:to_i;y=g[a,b];puts y==1?:simplest:[a/y,b/y]*?/}

いくつかのテストケース:

test_cases = ['9/18', '8/12', '50/100', '82/100', '100/100',
              '150/100', '99/100', '-5/10', '-5/18', '0/1']

test_cases.map { |frac| f[frac] }

出力:

1/2
2/3
1/2
41/50
1/1
3/2
simplest
-1/2
simplest
simplest

ルールに反しますが、RubyにはRationalサポートが組み込まれていることに注意してください。

a=gets.chomp;b=a.to_r;puts b.to_s==a ?:simplest:b

0

JavaScript (91)(73)

分数が既に最も単純な形式の場合、「/」を返します。関数gはgcdを計算します。ところで:何かが非負の整数である「1 ==何か」の短い方法はありますか?

function s(f){[n,m]=f.split(b='/');g=(u,v)=>v?g(v,u%v):u;return 1==(c=g(n,m))?b:n/c+b+m/c;}

さらに短いバージョンの@bebeに感謝します。

s=f=>([n,m]=f.split(b='/'),c=(g=(u,v)=>v?g(v,u%v):u)(n,m))-1?n/c+b+m/c:f;

es6を一貫して使用します。関数を呼び出し、使用時s=f=>...gを割り当て(g=...)(n,m)、それをcに渡し、それが1に等しいかどうかをテストし、c-1?not_equals:equalsreturnの使用を避けます。結果:s=f=>([n,m]=f.split(b='/'),c=(g=(u,v)=>v?g(v,u%v):u)(n,m))-1?n/c+b+m/c:f;73(戻り最も単純な形態、それを低減することができない場合(F))
BEBE

1
うわーすごい!全体を1つのステートメントにまとめる方法が考えられなかったので、私はとを使用functionしましたreturn-1=)への感謝
2014

0

Lua- 130 115文字

10/10本当に試しました

a,b=io.read():match"(.+)/(.+)"u,v=a,b while v+0>0 do t=u u=v v=t%v end print(a+0==a/u and"reduced"or a/u.."/"..b/u)
  • 分数が最も単純な形式の場合、「縮小」を出力します
  • ネガを扱う
  • 不適切な分数で動作します
  • おそらく小数で動作します(1.2 / 3.6は5.4043195528446e + 15 / 1.6212958658534e + 16を示します)
  • 任意の数/ 0は1/0を与える
  • 整数にはなりません

文字列で算術演算を行うときに文字列を数値に自動変換するLuaの機能を十分に活用しました。比較コードのtonumberの代わりに「+0」を追加する必要がありました。

申し訳ありませんが、私は非ゴルフバージョンを持っていません、上記は実際に私がそれを書いた方法です


0

バッチ-198

for /f "tokens=1,2delims=/" %%a in ("%1")do set a=%%a&set b=%%b&set/ac=%%b
:1
set/ax=%a%%%%c%&set/ay=%b%%%%c%
if %x%%y%==00 set/aa/=%c%&set/ab/=%c%
if %c% GTR 0 set/ac=%c%-1&goto 1
echo %a%/%b%

入力はとして分割されますa/b。次に、ごとcb,b-1,...1abで割り切れるかどうかをチェックしc、割り切れる場合は割りますc。次に戻りますa/b


0

Befunge 93(192)

&04p~$&14p2       > :24p  v       >34g#v_0"tselpmiS">:#,_@
>134p 24g>        ^+1g42$<>04g`   |    >04g."/",14g.@
^p41/g42p40/g42<         |%g42:g41<
         #     |!%g42:g40<
   0     ^+1g42<

0

C 135

スペースで区切られた2つの整数の入力を受け入れます。GCDを見つけるために、最小のaとbで除算して1に下げます。

int a,b,m;
void main()
{
scanf("%d %d", &a, &b);
m=a<b?a:b;
for (;m>0;m--){if (a%m==0&&b%m==0)break;}
printf("%d/%d",a/m,b/m);
}

0

ジャワ(200)

Javaでの以前の最適なソリューションはまだ300バイトを超えていましたが、これは200バイトです。

class M {public static void main(String[]args){String[]s=args[0].split("/");int a=Integer.parseInt(s[0]),b=Integer.parseInt(s[1]),c=a,d=b;while(d>0){int g=c;c=d;d=g%d;}System.out.print(a/c+"/"+b/c);}}

これは、すべての数値を繰り返す代わりに、(より速い)モジュロを使用してgcdを決定します。


1
スペースは後から削除できますclass M
mbomb007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.