Vereinfachen Sie einen Bruch

8

Gewinner: Ian D. Scotts Antwort um ein Byte (48 Bytes)! Hervorragend!

Ihr Programm muss Eingaben von einem Bruchteil akzeptieren, der vereinfacht werden kann, und ihn dann vereinfachen.

Regeln:

  • Wenn der Bruch bereits in seiner einfachsten Form vorliegt, müssen Sie den Benutzer informieren
  • Keine eingebauten Funktionen, um dies zu tun
  • Der Benutzer muss die Nummer irgendwann eingeben, die Methode, die das Programm liest, spielt jedoch keine Rolle. Dies kann mit stdin, console.readline usw. geschehen. Solange der Benutzer 9/18(zum Beispiel) irgendwann eingibt, ist es gültig
  • Die Ausgabe muss mit stdout, console.writeline usw. erfolgen.
  • Der Bruch wird als eingegeben x/yund muss als ausgegeben werdena/b
  • Der Bruch muss die einfachste Form ausgeben. Zum Beispiel ist 8/12 -> 6/9 nicht gültig , die einzig gültige Lösung ist 2/3.

  • Dieser Wettbewerb endet am 9. August 2014 (7 Tage nach Veröffentlichung)
  • Dies ist eine Frage, daher gewinnt der kürzeste Code
Jon
quelle
1
Wie sollen wir den Benutzer informieren?
Bebe
Stdout, console.writeline usw.
Jon
7
Das ist wirklich ein ziemlich triviales Problem. Alles, was Sie tun, ist durch die gcd zu teilen (eine Funktion, die oft eingebaut ist, aber nicht schwer zu schreiben wäre).
Calvins Hobbys
1
@ Calvin'sHobbies Ja, das Problem selbst ist trivial. Es ist nicht so einfach, es in kürzester Zeit zu tun.
Jon
3
Was meinen Sie mit "Wenn der Bruch bereits in seiner einfachsten Form vorliegt, müssen Sie den Benutzer informieren"? Sollte es eine bestimmte Nachricht geben, abgesehen von der Rückgabe der Eingabe? Wenn ja, erfüllt die akzeptierte Antwort dies nicht.
Martin Ender

Antworten:

1

Python - 69 48

Das erste, was Sie tun müssen, ist, es im nativen Python-Format zum Speichern von Brüchen darzustellen, nämlich in der Bruchklasse.

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

Jetzt vereinfachen wir ... aber schau! Es ist bereits vereinfacht.

Zählt dies als Verwendung einer eingebauten Funktion? Es ist nicht speziell zur Vereinfachung gedacht, und Bruch ist sowieso eine Klasse, keine Funktion.

Ich habe keine Vereinfachungsfunktion aufgerufen, daher ist es nicht meine Schuld, wenn Python beschließt, dies selbst zu tun.

Ian D. Scott
quelle
Aber der Konstruktor dieser Klasse ist eine Funktion?
Fehler
@flawr type(fractions.Fraction.__init__)gibt wrapper_descriptoreher zurück als function, also könnte man sagen, dass es keine Funktion ist. Das bedeutet eigentlich nur, dass es in c implementiert ist, aber alles, was nicht in der Klassenfunktion ist, ist keine Funktion, oder?
Ian D. Scott
2
-1: Dies ist eine eingebaute. Während es im Namen nicht "vereinfachen" heißt, vereinfacht es Brüche.
Cyoce
5

> <> (92)

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

Ich weiß, dass ich das niedriger machen kann, ich werde es morgen früh ein bisschen mehr spielen.

Grundlegende Erklärung: Die ersten beiden Zeilen und die zweite Hälfte der dritten Zeile dienen zum Lesen von Zahlen. Leider hat> <> keine Möglichkeit, dies zu tun, sodass das Parsen die Hälfte des Programms in Anspruch nimmt.

Die 4. Zeile ist eine einfache iterative GCD-Berechnung. Ich bin überrascht, wie gut> <> die Anzahl der Bytes für den tatsächlichen Algorithmus war. Wenn es nicht das schreckliche I / O gäbe, könnte es tatsächlich eine vernünftige Golfsprache sein.

Die letzten beiden Zeilen dienen nur zum Drucken des Ergebnisses und zum Teilen der ursprünglichen Zahlen durch die GCD.

Mike Precup
quelle
Sie haben es tatsächlich besser gemacht als alle anderen außer dem Golfskript. nett!
stolzer Haskeller
nicht mehr wahr :-(
stolzer Haskeller
3

GolfScript, 49 Zeichen

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

Führen Sie die beiden Testfälle hier aus :

> 8/12
2/3

> 7/12
simplest
Howard
quelle
3

JavaScript 101

Ausnahmsweise eine Lösung, die EcmaScript 6 nicht verwendet

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')

Aber mit E6 könnte 93 sein

[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
quelle
1
for([a,b]=[c,d]=prompt().split('/');b;[a,b]=[b,a%b]);alert(a-1?c/a+'/'+d/a:'Reduced'); 86 Ich hoffe, es ist mathematisch korrekt ...
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'

Sehr einfache Lösung, obwohl ich weiß, dass sie in vielen anderen Sprachen kürzer wäre.

Ich habe einen importierten verwendet, gcdaber wenn er als eingebauter Fraktionsreduzierer zählt, kann er direkt implementiert werden.

Calvins Hobbys
quelle
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

Druckt anschließend einen Booleschen Wert, um festzustellen, ob das Original in der einfachsten Form vorliegt. Tut einfach den üblichen GCD-Algorithmus. Die meisten Zeichen werden für die Eingabe / Ausgabe ausgegeben.

xnor
quelle
Wäre es nicht kürzer, Python 3 zu verwenden input()?
mbomb007
@ mbomb007 Es ist eine Weile her, aber ich denke, die 4 Zeichen, die darauf gespeichert sind, gehen mehr als verloren, da Python 3 Parens benötigt print, das mapentpackt wird und vielleicht eher eine Ganzzahl als eine Float-Division.
xnor
Ich habe die Teilung vergessen. Das allein würde es "nicht wert" machen. Was meinst du mapmit Auspacken?
mbomb007
@ mbomb007 Mein Fehler, a,b=map(int,...)erfordert keine zusätzlichen Zeichen, da a,b=...es automatisch entpackt wird. Das Problem, auf das Sie manchmal mit Python 3 stoßen, ist, dass mapkeine Liste erstellt wird, sondern ein Kartenobjekt, das in eine Liste umgewandelt werden muss, bevor Sie so etwas wie Slice It ausführen können. Ein Ausdruck wie *l,=map(...)wird benötigt, um lstattdessen als Liste zuzuweisen .
xnor
2

PHP> = 7,1, 76 Bytes (nicht konkurrierend)

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

Online Version

Jörg Hülsermann
quelle
1

C 94

Nur Brute Force erraten und prüfen, ob die GCD bei a | b bis 1 beginnt.

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
quelle
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 Zeichen)

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

Unmushed:

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

Lauf:

php -r "$f=$argv[1];$p...[code here]...:$r;" 9/18;
1/2
  • druckt "reduziert", wenn der Bruch bereits in seiner einfachsten Form vorliegt
  • arbeitet mit negativen Brüchen
  • arbeitet mit falschen Brüchen (zB 150/100 ergibt 3/2)
  • arbeitet irgendwie mit Dezimalstellen (zB 1,2 / 3,6 ergibt 0,75 / 2,25)
  • 99/0 gibt fälschlicherweise 1/0 ?
  • wird nicht auf eine ganze Zahl reduziert (zB 100/100 ergibt 1/1)

Hier ist eine ungolfed Version mit einigen Tests (modifiziert in Funktionsform):

<?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
)
*/
?>
Zamnüsse
quelle
0

Java, 361 349 329 (danke @Sieg für den intTipp)

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

Ich weiß, dass es nicht kurz ist, aber ich bin einfach fasziniert von dem, was ich getan habe.

Um es zu verwenden, kompilieren Sie den Code und führen Sie ihn aus, indem Sie die Argumente über die Befehlszeile übergeben.

  • Nur Ganzzahlen (ich bin nicht in doublesund die Aufgabe erfordert es nicht).
  • Wenn der Bruch bereits vereinfacht ist, gibt er sich selbst zurück.
  • Funktioniert nicht mit negativen Brüchen.
  • Durch Null teilen? Kein Cookie für Sie (Gibt eine leere Zeichenfolge zurück).

Ungolfed (wenn jemand dieses Durcheinander sehen will):

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
quelle
1
Sie sollten wirklich intstatt verwenden Integer, auch im Produktionscode. Int wird vom Stapel zugewiesen, während Integer vom Heap stammt.
siehe
@Sleg Nun, das wusste ich nicht, vielen Dank.
g.carvalho97
Dann etwas, das Sie nicht in der Produktion verwenden sollten. Nur ein Anruf new Integer(str)hat das gleiche Ergebnis wie Integer.parseInt(str). Warum nicht String f=""(immer) verwenden?
siehe
@Sieg Nochmals vielen Dank, aber warum ist das so? Ich weiß, dass new Integer(str)das Integeraus einem String entsteht, aber nicht Integer.parseInt(str)das Gleiche tut? Und die Sache mit String f="", ich weiß, dass ich es String f=new String()
überarbeiten
1
Integer.parseIntmacht zwar das gleiche, aber mit einigen zwischengespeicherten Werten für eine schnellere Suche.
siehe
0

Ruby - 112 Zeichen

gist ein Helfer-Lambda, das die GCD von zwei ganzen Zahlen berechnet. fNimmt beispielsweise einen Bruch als Zeichenfolge '42/14'und gibt den reduzierten Bruch aus oder simplestwenn Zähler und Nenner relativ prim sind.

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

Einige Testfälle:

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

Ausgabe:

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

Beachten Sie, dass Ruby RationalUnterstützung hat, obwohl dies gegen die Regeln verstößt, sodass wir dies tun können

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

JavaScript (91) (73)

Gibt '/' zurück, wenn der Bruch bereits in seiner einfachsten Form vorliegt. Die Funktion g berechnet die gcd. Übrigens: Gibt es einen kürzeren Weg für '1 == etwas', wo etwas eine nicht negative ganze Zahl ist?

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

Vielen Dank an @bebe für eine noch kürzere Version:

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;
fehlerhaft
quelle
benutze es6 konsequent. Rufen Sie Ihre Funktion auf s=f=>...und weisen Sie g zu, wenn Sie sie verwenden. (g=...)(n,m)Übergeben Sie sie dann an c und testen Sie, ob sie gleich 1 ist, c-1?not_equals:equalsund versuchen Sie, die Verwendung von return zu vermeiden. Ergebnis: 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 (gibt die einfachste Form (f) zurück, wenn sie nicht reduziert werden kann)
bebe
1
Wow! Das ist toll! Ich konnte mir keine Möglichkeit vorstellen, das ganze Ding in eine Aussage zu packen, deshalb habe ich functionund verwendet return. Und danke für die -1=)
Fehler
0

Lua - 130 115 Zeichen

10/10 habe ich wirklich versucht

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)
  • druckt "reduziert", wenn der Bruch in einfachster Form vorliegt
  • arbeitet mit Negativen
  • arbeitet mit falschen Brüchen
  • funktioniert vermutlich mit Dezimalstellen (1.2 / 3.6 ergibt 5.4043195528446e + 15 / 1.6212958658534e + 16)
  • Jede Zahl / 0 ergibt 1/0
  • reduziert sich nicht auf ganze Zahlen

Ich habe Luas Fähigkeit, eine Zeichenfolge automatisch in eine Zahl umzuwandeln, voll ausgenutzt, wenn ich arithmetische Operationen an einer Zeichenfolge ausgeführt habe. Ich musste "+0" anstelle von tonumber für einen Vergleichscode hinzufügen.

Entschuldigung, ich habe keine ungolfed Version, das obige ist eigentlich so, wie ich es geschrieben habe

Dwayne Slater
quelle
0

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

Die Eingabe wird aufgeteilt als a/b, dann prüfen wir für jeden cin b,b-1,...1, ob aund bdurch teilbar sind c, und teilen sie durch, cob sie teilbar sind. Dann kehren wir zurücka/b

Οurous
quelle
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
quelle
0

C 135

Akzeptiert Eingaben für 2 durch Leerzeichen getrennte Ganzzahlen. Teilt durch mindestens a & b bis 1, um GCD zu finden.

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
quelle
0

Java (200)

Die bisher beste Lösung in Java hatte noch> 300 Bytes, diese hat 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);}}

Dies verwendet das (schnellere) Modulo, um die gcd zu bestimmen, anstatt alle Zahlen zu iterieren.

Roy van Rijn
quelle
1
Sie können das Leerzeichen nachclass M
mbomb007