Sederhanakan fraksi

8

Pemenang: Jawaban Ian D. Scott , dengan satu byte (48 byte)! Hebat!

Program Anda harus menerima input dari fraksi yang dapat disederhanakan, lalu menyederhanakannya.

Aturan:

  • Jika fraksi sudah dalam bentuk yang paling disederhanakan, Anda harus memberi tahu pengguna
  • Tidak ada fungsi bawaan untuk melakukan ini
  • Pengguna harus mengetikkan angka di beberapa titik, namun metode yang dibaca program itu tidak masalah. Bisa dengan stdin, console.readline, dll. Selama tipe pengguna 9/18(misalnya) di beberapa titik, itu valid
  • Output harus dilakukan dengan stdout, console.writeline, dll ...
  • Fraksi akan dimasukkan sebagai x/y, dan harus ditampilkan sebagaia/b
  • Fraksi harus menampilkan bentuk yang paling sederhana. Misalnya, 8/12 -> 6/9 tidak valid , satu-satunya solusi yang valid adalah 2/3.

  • Kontes ini berakhir pada 9 Agustus 2014 (7 hari sejak posting)
  • Ini adalah pertanyaan , sehingga kode terpendek menang
Jon
sumber
1
Bagaimana cara kami memberi tahu pengguna?
bebe
Stdout, console.writeline, dll
Jon
7
Ini benar-benar masalah yang sangat sepele. Yang Anda lakukan adalah membagi dengan gcd (fungsi yang sering dibangun tetapi tidak akan sulit untuk menulis).
Calvin Hobbies
1
@ Calvin Hobbies Ya, masalahnya sendiri sepele. Melakukannya dalam jumlah kode terpendek tidaklah mudah.
Jon
3
Apa yang Anda maksud dengan "Jika fraksi sudah dalam bentuk yang paling sederhana, Anda harus memberi tahu pengguna"? Haruskah ada pesan khusus selain dari hanya mengembalikan input? Jika demikian, saya tidak menerima jawaban yang diterima memenuhi ini.
Martin Ender

Jawaban:

1

Python - 69 48

Hal pertama yang harus dilakukan adalah merepresentasikannya dalam format asli python untuk menyimpan fraksi, yaitu kelas Fraction.

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

Sekarang kami menyederhanakan ... tapi lihat! Ini sudah disederhanakan.

Apakah ini dianggap sebagai menggunakan fungsi bawaan? Itu tidak dimaksudkan khusus untuk menyederhanakan, dan Fraction adalah kelas, bukan fungsi.

Saya tidak memanggil fungsi penyederhanaan, jadi bukan salah saya jika python memutuskan untuk melakukannya sendiri.

Ian D. Scott
sumber
Tetapi konstruktor dari kelas itu adalah fungsi?
flawr
@ flawr type(fractions.Fraction.__init__)mengembalikan wrapper_descriptordaripada function, jadi Anda bisa mengatakan itu bukan fungsi. Ini sebenarnya hanya berarti diimplementasikan dalam c, tetapi apa pun yang tidak ada dalam fungsi kelas bukan fungsi, kan?
Ian D. Scott
2
-1: ini adalah built-in. Meskipun tidak mengatakan "sederhanakan" dalam nama, itu menyederhanakan fraksi.
Cyoce
5

> <> (92)

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

Saya tahu saya bisa mendapatkan ini lebih rendah, saya akan golf lebih banyak di pagi hari.

Penjelasan dasar: Dua baris pertama, dan paruh kedua dari ketiga, semuanya untuk membaca angka. Sedihnya,> <> tidak memiliki cara untuk melakukan itu, sehingga parsing mengambil setengah dari program.

Baris ke-4 adalah perhitungan gcd berulang sederhana. Saya terkejut melihat seberapa baik> <> lakukan pada hitungan byte untuk algoritma yang sebenarnya. Jika bukan karena i / o yang mengerikan, itu sebenarnya bisa menjadi bahasa golf yang masuk akal.

Dua baris terakhir hanya untuk mencetak hasilnya dan membagi angka aslinya dengan gcd.

Mike Precup
sumber
Anda benar-benar melakukan yang lebih baik daripada semua orang kecuali yang ada di skrip golf. bagus!
haskeller bangga
tidak lagi benar :-(
bangga haskeller
3

GolfScript, 49 karakter

'/'/{~}%.~{.@\%.}do;:G({{G/}%'/'*}{;'simplest'}if

Jalankan kedua testcas di sini :

> 8/12
2/3

> 7/12
simplest
Howard
sumber
3

JavaScript 101

Untuk sekali ini, solusi tidak menggunakan 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')

Namun dengan E6 bisa jadi 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')
edc65
sumber
1
for([a,b]=[c,d]=prompt().split('/');b;[a,b]=[b,a%b]);alert(a-1?c/a+'/'+d/a:'Reduced'); 86 saya harap ini benar secara matematis ...
bebe
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'

Solusi yang sangat sederhana, meskipun saya tahu ini akan lebih pendek dalam banyak bahasa lain.

Saya menggunakan yang diimpor gcdtetapi jika dianggap sebagai peredam fraksi bawaan, ia dapat diterapkan secara langsung.

Hobi Calvin
sumber
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

Mencetak Boolean sesudahnya untuk mengatakan apakah aslinya dalam bentuk yang paling sederhana. Hanya melakukan algoritma GCD biasa. Sebagian besar karakter dihabiskan untuk input / output.

Tidak
sumber
Bukankah lebih pendek untuk menggunakan Python 3 input()?
mbomb007
@ mbomb007 Sudah lama, tapi saya pikir 4 chars disimpan pada yang lebih dari hilang oleh Python 3 membutuhkan parens sekitar print, mapsedang dibongkar, dan mungkin bilangan bulat daripada divisi float.
xnor
Lupa tentang pembagian. Itu saja akan membuatnya 'tidak layak.' Apa maksudmu tentang mapdibongkar?
mbomb007
@ mbomb007 Kesalahan saya, a,b=map(int,...)tidak memerlukan karakter tambahan karena a,b=...membongkar secara otomatis. Masalah yang kadang-kadang Anda temui adalah Python 3 yang maptidak menghasilkan daftar tetapi objek peta yang perlu diubah menjadi daftar sebelum Anda bisa melakukan sesuatu seperti mengirisnya. Ekspresi suka *l,=map(...)diperlukan untuk menetapkan lsebagai daftar.
xnor
2

PHP> = 7.1, 76 Bytes (Tidak Bersaing)

for([$x,$y]=explode("/",$argn),$t=1+$x;$y%--$t||$x%$t;);echo$x/$t."/".$y/$t;

Versi Online

Jörg Hülsermann
sumber
1

C, 94

Hanya tebakan kasar dan periksa, untuk GCD mulai dari | b hingga 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);}
technosaurus
sumber
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);}
bebe
0

Rebmu (104 karakter)

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

Tanpa suara:

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
es1024
sumber
0

PHP 156

meh.

$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;

Lari:

php -r "$f=$argv[1];$p...[code here]...:$r;" 9/18;
1/2
  • mencetak "diperkecil" jika fraksi sudah dalam bentuk yang paling sederhana
  • bekerja dengan pecahan negatif
  • bekerja dengan fraksi yang tidak tepat (mis. 150/100 memberi 3/2)
  • agak bekerja dengan desimal (mis. 1.2 / 3.6 memberi 0.75 / 2.25)
  • 99/0 salah memberikan 1/0 ?
  • tidak akan berkurang menjadi bilangan bulat (mis. 100/100 memberi 1/1)

Berikut adalah versi yang tidak dikenali dengan beberapa pengujian (dimodifikasi ke dalam bentuk fungsi):

<?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
)
*/
?>
kacang zam
sumber
0

Java, 361 349 329 (terima kasih @Sieg untuk inttipnya)

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);}}

Saya tahu ini tidak pendek, tapi saya hanya terpesona dengan apa yang saya lakukan.

Untuk menggunakannya, kompilasi kode dan jalankan lewat argumen melalui baris perintah.

  • Hanya bilangan bulat (saya tidak suka doubles dan tugas tidak memerlukannya).
  • Jika fraksi sudah disederhanakan, mengembalikan dirinya sendiri.
  • Tidak bekerja dengan pecahan negatif.
  • Membagi dengan nol? Tidak ada cookie untuk Anda (Mengembalikan string kosong).

Tidak disatukan (jika ada yang ingin melihat kekacauan ini):

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);
    }
}
g.carvalho97
sumber
1
Anda benar-benar harus menggunakannya intsebagai ganti Integer, bahkan dalam kode produksi. Int dialokasikan dari stack, sedangkan integer dari heap.
seequ
@Leg Yah, saya tidak tahu itu, terima kasih banyak.
g.carvalho97
Maka sesuatu yang sebaiknya tidak Anda gunakan dalam produksi. Hanya menelepon new Integer(str)akan memiliki hasil yang sama dengan Integer.parseInt(str). Juga, mengapa tidak menggunakan String f=""(selalu)?
seequ
@ Sieg Terima kasih lagi, tapi mengapa begitu? Saya tahu itu new Integer(str)menciptakan Integerstring, tetapi tidak Integer.parseInt(str)melakukan hal yang sama? Dan masalahnya String f="", saya tahu bahwa saya harus menggunakannya String f=new String(), tetapi saya tidak tahu mengapa saya tidak menggunakannya, mungkin itu kebiasaan buruk: P
g.carvalho97
1
Integer.parseIntmemang melakukan hal yang sama, tetapi dengan beberapa nilai cache untuk pencarian lebih cepat.
seequ
0

Ruby - 112 karakter

gadalah lambda pembantu yang menghitung GCD dari dua bilangan bulat. fmengambil fraksi sebagai string, misalnya '42/14', dan mengeluarkan fraksi yang berkurang atau simplestjika pembilang dan penyebutnya relatif prima.

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]*?/}

Beberapa test case:

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] }

Keluaran:

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

Catatan, meskipun bertentangan dengan aturan, Ruby memiliki Rationaldukungan, jadi kami bisa melakukannya

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

JavaScript (91) (73)

Mengembalikan '/' ketika fraksi sudah dalam bentuk yang paling sederhana. Fungsi g menghitung gcd. BTW: Apakah ada cara yang lebih pendek untuk '1 == sesuatu' di mana ada sesuatu yang bukan bilangan bulat negatif?

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;}

Terima kasih kepada @bebe untuk versi yang lebih singkat:

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;
cacat
sumber
gunakan es6 secara konsisten. panggil fungsi Anda s=f=>...lalu tetapkan g saat menggunakannya (g=...)(n,m)lalu berikan ke c dan uji apakah itu sama dengan 1 oleh c-1?not_equals:equalsdan cobalah untuk menghindari menggunakan kembali. hasil: 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 (mengembalikan bentuk paling sederhana (f) jika tidak dapat dikurangi)
bebe
1
Wow, bagus! Saya tidak bisa memikirkan cara untuk mengemas shole itu menjadi satu pernyataan, itulah sebabnya saya menggunakan functiondan return. Dan terima kasih atas -1=)
flawr
0

Lua - 130 115 karakter

10/10 saya benar-benar mencoba

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)
  • mencetak "diperkecil" jika pecahan dalam bentuk paling sederhana
  • bekerja dengan negatif
  • bekerja dengan pecahan yang tidak tepat
  • mungkin bekerja dengan desimal (1.2 / 3.6 memberi 5.4043195528446e + 15 / 1.6212958658534e + 16)
  • angka / 0 memberi 1/0
  • tidak mengurangi ke bilangan bulat

Saya sepenuhnya mengambil keuntungan dari kemampuan Lua untuk secara otomatis mengkonversi string ke angka ketika melakukan operasi aritmatika pada string. Saya harus menambahkan "+0" sebagai pengganti tonumber untuk beberapa kode perbandingan.

Maaf, saya tidak memiliki versi yang tidak disunat, di atas sebenarnya adalah bagaimana saya menulisnya

Dwayne Slater
sumber
0

Gelombang - 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%

Masukan dibagi sebagai a/b, maka untuk setiap cdi b,b-1,...1kita memeriksa apakah adan bdibagi oleh c, dan membagi mereka dengan cjika mereka. Lalu kita kembalia/b

Suram
sumber
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<
sig_seg_v
sumber
0

C 135

Menerima input untuk 2 bilangan bulat yang dipisahkan ruang. Terus membagi dengan minimum a & b hingga 1 untuk menemukan GCD.

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);
}
bacchusbeale
sumber
0

Jawa (200)

Solusi terbaik sebelumnya di Jawa masih memiliki> 300 byte, yang ini memiliki 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);}}

Ini menggunakan modulo (lebih cepat) untuk menentukan gcd daripada mengulangi semua angka.

Roy van Rijn
sumber
1
Anda dapat menghapus spasi setelahclass M
mbomb007