Đơn giản hóa một phần


8

Người chiến thắng: Câu trả lời của Ian D. Scott , bằng một byte (48 byte)! Tuyệt vời!

Chương trình của bạn phải chấp nhận đầu vào từ một phân số có thể được đơn giản hóa, sau đó đơn giản hóa nó.

Quy tắc:

  • Nếu phân số đã ở dạng đơn giản nhất, bạn phải thông báo cho người dùng
  • Không có chức năng tích hợp để làm điều này
  • Người dùng phải nhập số tại một số điểm, tuy nhiên phương thức mà chương trình đọc nó không quan trọng. Nó có thể với stdin, console.readline, v.v ... Miễn là loại người dùng 9/18(ví dụ) tại một số điểm, nó hợp lệ
  • Đầu ra phải được thực hiện với thiết bị xuất chuẩn, console.writeline, v.v ...
  • Phân số sẽ được đặt dưới dạng x/yvà phải xuất ra dưới dạnga/b
  • Phân số phải xuất ra dạng đơn giản nhất. Ví dụ: 8/12 -> 6/9 không hợp lệ , giải pháp hợp lệ duy nhất là 2/3.

  • Cuộc thi này kết thúc vào ngày 9 tháng 8 năm 2014 (7 ngày kể từ ngày đăng)
  • Đây là một câu hỏi về , vì vậy đoạn mã ngắn nhất sẽ thắng

1
Làm thế nào chúng ta nên thông báo cho người dùng?
bebe

Stdout, console.writeline, v.v.
Jon

7
Đây thực sự là một vấn đề khá nhỏ. Tất cả những gì bạn làm là chia cho gcd (một chức năng thường được xây dựng nhưng sẽ không khó để viết).
Sở thích của Calvin

1
@ Calvin'sHob sở thích Vâng, vấn đề chính nó là tầm thường. Làm điều đó với số lượng mã ngắn nhất không phải là dễ dàng.
Jon

3
Ý bạn là gì khi "Nếu phân số đã ở dạng đơn giản nhất, bạn phải thông báo cho người dùng"? Có nên có một thông điệp cụ thể ngoài việc chỉ trả lại đầu vào? Nếu vậy, tôi không câu trả lời được chấp nhận thỏa mãn điều này.
Martin Ender

Câu trả lời:


1

Con trăn - 69 48

Điều đầu tiên cần làm là thể hiện nó ở định dạng gốc của python để lưu trữ phân số, cụ thể là lớp Phân số.

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

Bây giờ chúng tôi đơn giản hóa ... nhưng hãy nhìn! Nó đã được đơn giản hóa.

Điều này có được tính là sử dụng chức năng tích hợp không? Nó không nhằm mục đích đơn giản hóa và Fraction dù sao cũng là một lớp, không phải là một hàm.

Tôi đã không gọi bất kỳ chức năng đơn giản hóa nào, vì vậy đó không phải là lỗi của tôi nếu python quyết định tự thực hiện.


Nhưng hàm tạo của lớp đó là một hàm?
flawr

@flawr type(fractions.Fraction.__init__)trả về wrapper_descriptorchứ không phải function, vì vậy bạn có thể nói nó không phải là một hàm. Điều này thực sự chỉ có nghĩa là nó được thực hiện trong c, nhưng bất cứ điều gì không có trong hàm lớp không phải là một hàm, phải không?
Ian D. Scott

2
-1: đây là một tích hợp. Mặc dù nó không nói "đơn giản hóa" trong tên, nhưng nó đơn giản hóa các phân số.
Cyoce

5

> <> (92)

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

Tôi biết tôi có thể hạ thấp nó xuống, tôi sẽ đánh gôn thêm một chút vào buổi sáng.

Giải thích cơ bản: Hai dòng đầu tiên và nửa sau của dòng thứ ba, tất cả đều dành cho việc đọc số. Đáng buồn thay,> <> không có cách nào để làm điều đó, vì vậy việc phân tích cú pháp chiếm một nửa chương trình.

Dòng thứ 4 là một phép tính gcd lặp đơn giản. Tôi ngạc nhiên về mức độ> <> đã làm về số byte cho thuật toán thực tế. Nếu nó không phải là i / o khủng khiếp, nó thực sự có thể là một ngôn ngữ golf hợp lý.

Hai dòng cuối cùng chỉ để in kết quả và chia số gốc cho gcd.


bạn thực sự đã làm tốt hơn tất cả mọi người ngoại trừ bản golf. đẹp!
tự hào

không còn đúng nữa :-(
tự hào

3

GolfScript, 49 ký tự

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

Chạy hai testcase ở đây :

> 8/12
2/3

> 7/12
simplest

3

JavaScript 101

Lần đầu tiên, một giải pháp không sử dụng 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')

Nhưng với E6 có thể là 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 tôi hy vọng nó là toán học đúng ...
bebe

2

Con trăn 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'

Giải pháp rất đơn giản, mặc dù tôi biết nó sẽ ngắn hơn trong nhiều ngôn ngữ khác.

Tôi đã sử dụng một nhập khẩu gcdnhưng nếu nó được tính là một bộ giảm phân số tích hợp thì nó có thể được thực hiện trực tiếp.


2

Con trăn 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

Sau đó, in Boolean để cho biết bản gốc có ở dạng đơn giản nhất hay không. Chỉ cần làm thuật toán GCD thông thường. Hầu hết các ký tự được dành cho đầu vào / đầu ra.


Sẽ không ngắn hơn khi sử dụng Python 3 cho input()?
mbomb007

@ mbomb007 Đã được một thời gian, nhưng tôi nghĩ rằng 4 ký tự được lưu trên đó bị mất nhiều hơn bởi Python 3 cần parens xung quanh print, mapđược giải nén và có thể là số nguyên thay vì phân chia float.
xnor

Quên về sự phân chia. Điều đó một mình sẽ làm cho nó 'không có giá trị.' Bạn có ý nghĩa gì về mapviệc giải nén?
mbomb007

@ mbomb007 Lỗi của tôi, a,b=map(int,...)không yêu cầu thêm ký tự kể từ khi a,b=...tự động giải nén. Vấn đề đôi khi bạn gặp phải với Python 3 là mapkhông tạo được danh sách mà là một đối tượng bản đồ yêu cầu chuyển thành danh sách trước khi bạn có thể làm gì đó như cắt nó. Thay vào đó, một biểu thức như *l,=map(...)là cần thiết để gán lnhư một danh sách.
xnor


1

C, 94

Chỉ cần đoán và kiểm tra vũ lực, cho GCD bắt đầu từ a | b xuống còn 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);}
bebe

0

Rebmu (104 ký tự)

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

Không che giấu:

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;

Chạy:

php -r "$f=$argv[1];$p...[code here]...:$r;" 9/18;
1/2
  • in "giảm" nếu phân số đã ở dạng đơn giản nhất
  • hoạt động với các phân số âm
  • hoạt động với các phân số không chính xác (ví dụ 150/100 cho 3/2)
  • kinda hoạt động với số thập phân (ví dụ 1.2 / 3.6 cho 0,75 / 2,25)
  • 99/0 không chính xác cho 1/0 ?
  • sẽ không giảm xuống toàn bộ số (ví dụ 100/100 cho 1/1)

Đây là phiên bản chưa được chỉnh sửa với một số thử nghiệm (được sửa đổi thành dạng hàm):

<?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 (cảm ơn @Sieg vì tiền intboa)

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

Tôi biết nó không ngắn, nhưng tôi chỉ bị mê hoặc bởi những gì tôi đã làm.

Để sử dụng nó, biên dịch mã và chạy nó đi qua các đối số thông qua dòng lệnh.

  • Chỉ các số nguyên (Tôi không tham gia doublesvà nhiệm vụ không yêu cầu).
  • Nếu phân số đã được đơn giản hóa, trả về chính nó.
  • Không hoạt động với các phân số âm.
  • Chia cho số 0? Không có cookie cho bạn (Trả về một chuỗi trống).

Ungolfed (nếu có ai muốn xem mớ hỗn độn này):

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
Bạn thực sự nên sử dụng intthay vì Integer, ngay cả trong mã sản xuất. Int được phân bổ từ ngăn xếp, trong khi số nguyên là từ heap.
xem

@Sleg Vâng, tôi không biết điều đó, cảm ơn bạn rất nhiều.
g.carvalho97

Sau đó, một cái gì đó bạn không nên sử dụng trong sản xuất. Chỉ cần gọi new Integer(str)sẽ có kết quả tương tự Integer.parseInt(str). Ngoài ra, tại sao không sử dụng String f=""(luôn luôn)?
xem

@Sieg Cảm ơn một lần nữa, nhưng tại sao vậy? Tôi biết điều đó new Integer(str)tạo Integerra một chuỗi, nhưng không Integer.parseInt(str)làm điều tương tự? Và điều này String f="", tôi biết rằng tôi nên sử dụng nó String f=new String(), nhưng tôi không biết tại sao tôi không, có lẽ đó là một thói quen xấu: P
g.carvalho97

1
Integer.parseIntthực sự làm điều tương tự, nhưng với một số giá trị được lưu trong bộ nhớ cache để tra cứu nhanh hơn.
xem

0

Ruby - 112 ký tự

glà một lambda trợ giúp tính toán GCD của hai số nguyên. flấy một phân số dưới dạng một chuỗi, ví dụ '42/14', và đưa ra phân số giảm hoặc simplestnếu tử số và mẫu số tương đối nguyên tố.

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

Một số trường hợp thử nghiệm:

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

Đầu ra:

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

Lưu ý, mặc dù trái với quy tắc, Ruby có Rationalhỗ trợ nướng, vì vậy chúng tôi có thể làm

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

0

JavaScript (91) (73)

Trả về '/' khi phân số đã ở dạng đơn giản nhất. Hàm g tính toán gcd. BTW: Có cách nào ngắn hơn cho '1 == một cái gì đó' trong đó một cái gì đó là một số nguyên không âm?

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

Cảm ơn @bebe cho phiên bản thậm chí ngắn hơn:

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;

sử dụng es6 một cách nhất quán. gọi hàm của bạn s=f=>...sau đó gán g khi sử dụng nó (g=...)(n,m)sau đó chuyển nó cho c và kiểm tra xem nó có bằng 1 không c-1?not_equals:equalsvà cố gắng tránh sử dụng return. kết quả: 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 (thu nhập dưới hình thức đơn giản nhất (f) nếu nó không thể được giảm)
bebe

1
Ồ điều đó thật tuyệt! Tôi không thể nghĩ ra cách đóng gói thứ shole vào một tuyên bố đó là lý do tại sao tôi sử dụng functionreturn. Và cảm ơn vì -1=)
flawr

0

Lua - 130 115 ký tự

10/10 tôi thực sự đã cố gắng

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)
  • in "giảm" nếu phân số ở dạng đơn giản nhất
  • làm việc với tiêu cực
  • làm việc với các phân số không đúng
  • có lẽ hoạt động với số thập phân (1.2 / 3.6 cho 5.4043195528446e + 15 / 1.6212958658534e + 16)
  • bất kỳ số nào / 0 cho 1/0
  • không giảm xuống toàn bộ số

Tôi hoàn toàn tận dụng khả năng của Lua để tự động chuyển đổi một chuỗi thành một số khi thực hiện các phép toán số học trên một chuỗi. Tôi đã phải thêm "+0" thay cho tonumber cho một số mã so sánh.

Xin lỗi, tôi không có phiên bản chưa được chỉnh sửa, trên đây thực sự là cách tôi viết nó


0

Mẻ - 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%

Đầu vào được phân chia thành a/b, sau đó cho mỗi ctrong b,b-1,...1chúng ta kiểm tra xem abchia hết cho cvà chia chúng cho cnếu có. Sau đó chúng tôi trở lạia/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

Chấp nhận đầu vào cho 2 số nguyên cách nhau. Tiếp tục chia cho tối thiểu a & b xuống 1 để tìm 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);
}

0

Java (200)

Giải pháp tốt nhất trước đây trong Java vẫn có> 300 byte, giải pháp này có 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);}}

Điều này sử dụng modulo (nhanh hơn) để xác định gcd thay vì lặp tất cả các số.


1
Bạn có thể xóa khoảng class M
trắng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.