Wie man keine Brüche reduziert

12

Brüche falsch reduzieren

In dieser Code-Golf-Herausforderung musst du Brüche finden, die auf die falsche Weise reduziert werden können, aber immer noch die gleiche Anzahl haben.

Hinweis: Das falsche Reduzieren von Brüchen hat hier eine genaue Definition, siehe Details.

Beispiel:

64/16 = 6 4/1 6 = 4/1 = 4

Natürlich können Sie nicht beide 6en anschlagen, aber hier haben Sie immer noch den richtigen Wert. In dieser Herausforderung muss man solche Beispiele finden.

Einzelheiten

Sie müssen eine Funktion / ein Programm schreiben, die / das eine positive Ganzzahl nals Eingabe akzeptiert und / oder eine Liste / ein Array der Brüche im Format ausgibt / zurückgibt
numerator1,denominator1,numerator2,denominator2,...

Das Programm muss für jede Fraktion herausfinden, a/bmit a+b=nund a,b>0ob es falsch reduziert werden kann . (Es spielt keine Rolle, ob es auf herkömmliche Weise reduziert werden kann oder ob es viele Möglichkeiten für Reduzierungen gibt, es muss nur möglich sein, es auf mindestens eine Weise falsch zu reduzieren .)

Definition des falschen Weges: Ein Bruch kann nur dann falsch reduziert werden , wenn in a und b dieselbe Folge aufeinanderfolgender Ziffern vorkommt und der Wert des Bruches gleich bleibt, wenn Sie die Teilzeichenfolge entfernen.

Beispiel: 1536/353 kann auf 16/3 'reduziert' werden, aber diese beiden Werte sind nicht gleich, sodass Sie diesen Bruch nicht auf die falsche Weise reduzieren können .

Beachten Sie, dass diese Definition des Reduzierens des falschen Wegs auch Brüche einschließen kann, die auf die richtige Weise reduziert werden: Sie 110/10 = 11/1liegt innerhalb der Definition des Reduzierens des falschen Wegs , obwohl es sich um einen gültigen Schritt handelt.

Wertung

Die geringste Anzahl von Bytes gewinnt. Sie können eine Funktion oder ein Programm schreiben, das eine Ganzzahl akzeptiert und ein Array oder ein Programm zurückgibt, das stdin / stdout verwendet, oder Sie können n als in einer Variablen gespeichert betrachten, und am Ende des Programms muss die Liste in einer anderen Variablen gespeichert werden.

Testfälle

Bitte fügen Sie folgende Testfälle bei (Sagen Sie mir, welche ich hinzufügen soll, ich habe keine Ahnung, wie viele dieser Brüche es gibt / wie viele Beispiele zu erwarten sind)

n=80 (64/16 should be in this list)
n=147 (98/49 should be in this list)
n=500 (294/196 should be in this list) WRONG since 294+196 != 500 Thanks Falko
Fehler
quelle
3
Überlegen Sie sich, einen Begriff für "den falschen Weg" zu definieren, beispielsweise "doof" oder "freaky". Ich denke, der Beitrag wäre einfacher zu verstehen, da die Leser sofort befürchten, dass es eine Definition für den Begriff geben muss.
Michael Easter
3
Was ist, wenn es mehrere Möglichkeiten gibt, einen Bruch zu reduzieren, und nur einige davon falsch sind? 1010/10 = 101/1 && 1010/10 /= 110/1
John Dvorak
1
Variante von projecteuler.net/problem=33 ?
user80551
1
Ihr zweiter Testfall ( n=147) ist falsch: 49/89 != 4/8.
Beta Decay
1
Wenn es mehr als eine Möglichkeit gibt, einen Bruch zu reduzieren, können wir ihn dann mehrmals in die Ergebnismenge aufnehmen?
John Dvorak

Antworten:

3

Python 2 - 183 180

r=range
s=lambda a:[(a[i:j],int(a[:i]+a[j:]))for i in r(len(a))for j in r(i+1,len(a)+(i>0))]
l=sum([[a,n-a]for a in r(n)for p,x in s(`a`)for q,y in s(`n-a`)if(n-a)*x==a*y<p==q],[])

Die Eingabe muss in gespeichert werden n, die Ausgabe wird in gespeichert l.

Testfälle:

n = 80:

[10, 70, 16, 64, 20, 60, 30, 50, 40, 40, 40, 40, 50, 30, 60, 20, 64, 16, 70, 10]

n = 147:

[49, 98, 98, 49]

n = 490:

[10, 480, 20, 470, 30, 460, 40, 450, 50, 440, 60, 430, 70, 420, 80, 410, 90, 400, 90, 400, 98, 392, 100, 390, 100, 390, 110, 380, 120, 370, 130, 360, 140, 350, 150, 340, 160, 330, 170, 320, 180, 310, 190, 300, 190, 300, 196, 294, 200, 290, 200, 290, 210, 280, 220, 270, 230, 260, 240, 250, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 250, 240, 260, 230, 270, 220, 280, 210, 290, 200, 290, 200, 294, 196, 300, 190, 300, 190, 310, 180, 320, 170, 330, 160, 340, 150, 350, 140, 360, 130, 370, 120, 380, 110, 390, 100, 390, 100, 392, 98, 400, 90, 400, 90, 410, 80, 420, 70, 430, 60, 440, 50, 450, 40, 460, 30, 470, 20, 480, 10]

Sollten Duplikate in der Ausgabe verboten sein, werden 10 Zeichen länger:

r=range
s=lambda a:[(a[i:j],int(a[:i]+a[j:]))for i in r(len(a))for j in r(i+1,len(a)+(i>0))]
l=sum(map(list,{(a,n-a)for a in r(n)for p,x in s(`a`)for q,y in s(`n-a`)if(n-a)*x==a*y<p==q}),[])
Wrzlprmft
quelle
3

Haskell, 207 206 (209?) Zeichen

import Data.List
x![]=[x];(w:x)!(y:z)|w==y=x!z;_!_=[]
a@(w:x)%b=a!b++[w:e|e<-x%b];a%b=a!b
h=show
f n=[(c,n-c)|c<-[1..n-1],i<-inits$h c,s<-init$tails i,s/=h c,a<-h c%s,b<-h(n-c)%s,read a*(n-c)==read('0':b)*c]

Wenn es nicht möglich ist, dasselbe Verhältnis mehr als einmal zurückzugeben (400/400 = 40/40 = 4/4), f n=nub[...filtern Sie sie heraus.

Gibt eine Liste von Paaren zurück. Eine Liste von Zwei-Element-Paaren kostet dasselbe. Eine Liste der tatsächlichen Brüche müsste importiert Data.Ratiooder vollständig qualifiziert werden Data.Ratio.%(was auch mit der %hier definierten Funktion kollidiert ).

Testfälle (mit nub):

Prelude Data.List> f 80
[(10,70),(16,64),(20,60),(30,50),(40,40),(50,30),(60,20),(64,16),(70,10)]
Prelude Data.List> f 147
[(49,98),(98,49)]
Prelude Data.List> f 500
[(10,490),(20,480),(30,470),(40,460),(50,450),(60,440),(70,430),(80,420),(90,410
),(100,400),(110,390),(120,380),(130,370),(140,360),(150,350),(160,340),(170,330
),(180,320),(190,310),(200,300),(210,290),(220,280),(230,270),(240,260),(250,250
),(260,240),(270,230),(280,220),(290,210),(300,200),(310,190),(320,180),(330,170
),(340,160),(350,150),(360,140),(370,130),(380,120),(390,110),(400,100),(410,90)
,(420,80),(430,70),(440,60),(450,50),(460,40),(470,30),(480,20),(490,10)]

ungolfed und kommentiert :

import Data.List

-- haystack ! needle - the haystack with the needle removed, wrapped in a single-element list
--                       or an empty array if the haystack does not start with the needle

x ! [] = [x]                        -- case: empty needle = match with the full haystack left
(h:hs) ! (n:ns) | h == n = hs ! ns  -- case: needle and haystack match
_ ! _ = []                          -- case: no match

-- haystack % needle - the haystack with the needle removed 
--                       for all positions of the needle in the haystack

a@(h:hs) % b = a ! b ++ map (h:) (hs%b) -- either remove the needle here, or elsewhere
a % b = a                               -- empty haystack cannot be popped

-- f - the function we are interested in

f total = [ (num, total - num) 
          | num   <- [1 .. total-1],            -- for each numerator in range
            i     <- inits $ show num,          -- for each postfix of the numerator
            sub   <- init $ tails i,            -- for each prefix of the postfix except the last (empty) one
            sub /= show num,                    -- that isn't equal to the numerator
            reNum <- show num % sub,            -- remove the substring from the numerator
            reDiv <- show (total - num) % sub,  -- as well as from the denominator.

                                                -- the resulting ratios must be equal by value:
            (read reNum) ^ (total - num) == (read '0':reDiv) * num]
John Dvorak
quelle
kannst du dich verändern ';' zu Newlines (im Golf Code)? es ändert nichts an der Anzahl der Bytes und macht den Code viel lesbarer
stolzer Haskeller
@ proudhaskeller Das ist absichtlich; Ich mag es weniger Zeilen im Code zu haben. Auch die Leitungslängen sind auf diese Weise ausgeglichener. Denkst du, ich sollte mich ändern?
John Dvorak
mach was immer du willst, aber ich möchte, dass die Zeilen ausgebreitet werden, damit ich den Code besser lesen kann (anstatt auf den ungolfed Code zurückzugreifen)
stolzer haskeller
Geht es dir gut mit der aktuellen version Ich kann die letzte Zeile leider nicht teilen (außer bei Leerzeichen, die die Lesbarkeit
John Dvorak
wie gesagt, tu was auch immer du willst
stolzer haskeller
1

Python 2 - 236

n=input()
r=range
f=float
l=len
for a in r(n):
 A=`a`;B=`n-a`
 for i in r(l(A)):
  for j in r(i+1,l(A)+1):
   for u in r(l(B)):
    C=A[:i]+A[j:];D=B[:u]+B[u+j-i:]
    if A[i:j]==B[u:u+j-i]and l(C)*l(D)and f(C)==f(A)/f(B)*f(D):print A,B
Falko
quelle
1

Python 3 - 302

Hinweis: Aufgrund von Analyseproblemen gibt es keine Brüche mit der Nummer 0 in (daher werden keine Brüche mit der richtigen Methode berechnet).

n=int(input());s=str;r=range
print([[a,b]for a in r(1,n)for b in r(1,a)for i in r(1,n)if i!=a and i!=b and s(i)in s(a)and s(i)in s(b)and s(a).count(s(i))<len(s(a))and s(b).count(s(i))<len(s(b))and not'0'in s(a)and not'0'in s(b)and eval(s(a).replace(s(i),'')+'/'+s(b).replace(s(i),''))==a/b and a+b<=n])

Mit n = 80:

[[64, 16]]

Mit n = 147

[[64, 16], [65, 26], [95, 19], [98, 49]]

Mit n = 500

[[64, 16], [65, 26], [95, 19], [98, 49], [136, 34], [192, 96], [194, 97], [195, 39], [196, 49], [196, 98], [231, 132], [238, 34], [238, 136], [242, 143], [253, 154], [264, 165], [268, 67], [275, 176], [286, 187], [291, 97], [291, 194], [294, 49], [294, 98], [294, 196], [295, 59], [297, 198], [298, 149], [325, 13], [341, 143], [345, 138], [392, 49], [392, 98], [395, 79]]
Beta-Zerfall
quelle
Dafür n=80druckt das [[64, 16], [65, 26]]aber offensichtlich 65 + 26 = 91 > 80.
Ingo Bürk
Alle ifs in ein einziges großes verwandeln, ifwobei ands alle Bedingungen miteinander verbindet? Spart ziemlich viele Zeichen, denke ich.
Soham Chowdhury
@Soham Ja, danke!
Beta Decay
Könnten Sie auch die Testfälle einschließen, die ich hinzugefügt habe? (Und könnten Sie vielleicht sehen, ob Sie einige interessante Testfälle finden, die ich auch hinzufügen sollte?)
Fehler
2
Wo sind 10/70, 20/60und 30/50?
John Dvorak