Comment NE PAS réduire les fractions

13

Réduire les fractions dans le mauvais sens

Dans ce défi de code-golf, vous devez trouver des fractions qui peuvent être réduites dans le mauvais sens mais qui se retrouvent toujours dans le même nombre.

Remarque: la réduction des fractions dans le mauvais sens a ici une définition exacte, voir les détails.

Exemple:

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

Bien sûr, vous ne pouvez pas simplement frapper les deux 6 mais ici vous vous retrouvez toujours avec la bonne valeur. Dans ce défi, vous devez trouver des exemples comme celui-ci.

Détails

Vous devez écrire une fonction / programme qui accepte un entier positif nen entrée et génère / renvoie une liste / tableau des fractions au format
numerator1,denominator1,numerator2,denominator2,...

Le programme doit trouver pour chaque fraction a/bavec a+b=net a,b>0si elle peut être réduite dans le mauvais sens . (Peu importe si elle peut être réduite de manière conventionnelle ou s'il existe de nombreuses possibilités de réduction, il doit simplement être possible de la réduire de la mauvaise manière d'au moins une manière.)

Définition de la mauvaise façon: Une fraction peut être réduite de la mauvaise façon si et seulement si la même séquence de chiffres successifs apparaît dans a et b et si la valeur de la fraction reste la même si vous supprimez la sous-chaîne.

Exemple: 1536/353 peut être «réduit» à 16/3 mais ces deux valeurs ne sont pas égales, vous ne pouvez donc pas réduire cette fraction dans le mauvais sens .

Notez que cette définition de la réduction de la mauvaise façon peut également inclure des fractions qui sont réduites de la bonne façon: 110/10 = 11/1est dans la définition de la réduction de la mauvaise façon même si c'est une étape valide.

Notation

Le moins d'octets gagne. Vous pouvez écrire une fonction ou un programme qui accepte un entier et renvoie un tableau ou un programme qui utilise stdin / stdout ou vous pouvez considérer n enregistré dans une variable et à la fin du programme, la liste doit être enregistrée dans une autre variable.

Cas de test

Veuillez inclure les tests suivants (dites-moi lesquels je dois ajouter, je n'ai aucune idée du nombre de ces fractions / du nombre d'exemples à prévoir)

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
flawr
la source
3
Pensez à définir un terme pour "la mauvaise façon", comme "maladroit" ou "bizarre". Je pense que le message serait plus facile à comprendre, car les lecteurs se demandent immédiatement qu'il doit y avoir une définition du terme.
Michael Easter
3
Que se passe-t-il s'il existe plusieurs façons de réduire une fraction et que seules certaines d'entre elles ont tort? 1010/10 = 101/1 && 1010/10 /= 110/1
John Dvorak
1
Variante de projecteuler.net/problem=33 ?
user80551
1
Votre deuxième cas de test ( n=147) est incorrect: 49/89 != 4/8.
Beta Decay
1
S'il existe plusieurs façons de réduire une fraction, pouvons-nous l'inclure plusieurs fois dans l'ensemble de résultats?
John Dvorak

Réponses:

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],[])

l'entrée doit être stockée dans n, la sortie sera stockée dans l.

Cas de test:

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]

Si les doublons dans la sortie sont interdits, il obtient 10 caractères de plus:

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
la source
3

Haskell, 207 206 (209?) Caractères

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]

S'il n'est pas permis de renvoyer le même rapport plusieurs fois (400/400 = 40/40 = 4/4), utilisez f n=nub[...pour les filtrer.

Renvoie une liste de paires. Une liste de paires à deux éléments coûte la même chose. Une liste de fractions réelles nécessiterait une importation Data.Ratioou une qualification complète Data.Ratio.%(qui entre également en collision avec la %fonction définie ici)

cas de test (avec 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)]

non golfé et commenté :

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
la source
peux tu changer ';' vers les nouvelles lignes (dans le code golfé)? cela ne change pas le nombre d'octets et rend le code beaucoup plus lisible
fier haskeller
@proudhaskeller C'est délibéré; J'aime avoir moins de lignes dans le code golfé. De plus, les longueurs de ligne sont plus équilibrées de cette façon. Pensez-vous que je devrais changer?
John Dvorak
faites ce que vous voulez, mais j'aimerais que les lignes soient réparties afin que je puisse mieux lire le code (plutôt que de recourir au code non golfé)
fier haskeller
Êtes-vous d'accord avec la version actuelle? Je ne peux pas diviser la dernière ligne, malheureusement (sauf dans les espaces, ce qui tuerait la lisibilité)
John Dvorak
comme je l'ai dit, faites ce que vous voulez
fier 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
la source
1

Python 3 - 302

Remarque: En raison de difficultés d'analyse, il n'y a pas de fractions avec le nombre 0 (donc aucune fraction n'est calculée en utilisant la bonne méthode).

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

Avec n = 80:

[[64, 16]]

Avec n = 147

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

Avec 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 Decay
la source
Pour n=80cela imprime [[64, 16], [65, 26]], mais évidemment 65 + 26 = 91 > 80.
Ingo Bürk
Transformer tous les ifs en un seul grand ifavec ands reliant toutes les conditions? Enregistre pas mal de caractères, je pense.
Soham Chowdhury du
@Soham Oui, c'est vrai, merci!
Beta Decay
Pourriez-vous également inclure les cas de test que j'ai ajoutés? (Et pourriez-vous peut-être voir si vous trouvez des cas de test intéressants que je devrais ajouter aussi?)
flawr
2
Où sont 10/70-ils 20/60et 30/50?
John Dvorak