Come NON ridurre le frazioni


13

Ridurre le frazioni nel modo sbagliato

In questa sfida di code-golf devi trovare frazioni che possono essere ridotte nel modo sbagliato ma che finiscono comunque con lo stesso numero.

Nota: ridurre le frazioni nel modo sbagliato qui ha una definizione esatta, vedere i dettagli.

Esempio:

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

Ovviamente non puoi semplicemente colpire entrambi i 6 ma qui finisci comunque con il valore corretto. In questa sfida devi trovare esempi come questo.

Dettagli

Devi scrivere una funzione / programma che accetta un intero positivo ncome input e output / restituisce un elenco / array delle frazioni in formato
numerator1,denominator1,numerator2,denominator2,...

Il programma deve scoprire per ogni frazione a/bcon a+b=ne a,b>0se può essere ridotto nel modo sbagliato . (Non importa se può essere ridotto nel modo convenzionale o se ci sono molte possibilità di riduzioni, deve solo essere possibile ridurlo nel modo sbagliato in almeno un modo.)

Definizione del modo sbagliato: una frazione può essere ridotta nel modo sbagliato se e solo se la stessa sequenza di cifre successive appare in a e b e se il valore della frazione rimane lo stesso se si rimuove la sottostringa.

Esempio: 1536/353 può essere 'ridotto' a 16/3 ma quei due valori non sono uguali, quindi non è possibile ridurre questa frazione nel modo sbagliato .

Nota che questa definizione di riduzione del modo sbagliato può anche includere frazioni che sono ridotte nel modo giusto: 110/10 = 11/1rientra nella definizione di riduzione del modo sbagliato anche se è un passo valido.

punteggio

Vince il numero minimo di byte. È possibile scrivere una funzione o un programma che accetta un numero intero e restituisce un array o un programma che utilizza stdin / stdout oppure si può considerare n salvato in una variabile e alla fine del programma l'elenco deve essere salvato in un'altra variabile.

Casi test

Ti preghiamo di includere i seguenti test (dimmi quali dovrei aggiungere, non ho idea di quante di queste frazioni ci siano / quanti esempi aspettarsi)

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

3
Prendi in considerazione la definizione di un termine per "la strada sbagliata", come "sciocco" o "strano". Penso che il post sarebbe più facile da capire, perché i lettori si rendono subito conto che ci deve essere una definizione per il termine.
Michael Easter,

3
E se ci fossero diversi modi per ridurre una frazione e solo alcuni di loro sono sbagliati? 1010/10 = 101/1 && 1010/10 /= 110/1
John Dvorak,


1
Il tuo banco di prova secondo ( n=147) non è corretto: 49/89 != 4/8.
Decadimento beta

1
Se esiste più di un modo per ridurre una frazione, possiamo includerla più volte nel set di risultati?
John Dvorak,

Risposte:


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'ingresso deve essere archiviato n, l'uscita verrà archiviata l.

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

Se i duplicati nell'output sono vietati, vengono visualizzati 10 caratteri in più:

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

3

Haskell, 207 206 (209?) Caratteri

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]

Se non è consentito restituire lo stesso rapporto più di una volta (400/400 = 40/40 = 4/4), utilizzare f n=nub[...per filtrarli.

Restituisce un elenco di coppie. Un elenco di coppie a due elementi costa lo stesso. Un elenco di frazioni effettive richiederebbe l'importazione Data.Ratioo la qualificazione completa Data.Ratio.%(che si scontra anche con la %funzione definita qui)

casi di test (con 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 golfato e commentato :

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]

Puoi cambiare ';' a newline (nel codice golfed)? non cambia il conteggio dei byte e rende il codice molto più leggibile
orgoglioso haskeller il

@proudhaskeller Questo è deliberato; Mi piace avere meno righe nel codice golf. Inoltre, le lunghezze delle linee sono più bilanciate in questo modo. Pensi che dovrei cambiare?
John Dvorak,

fai quello che vuoi, ma vorrei che le linee fossero sparse in modo da poter leggere meglio il codice (piuttosto che ricorrere al codice non golfizzato)
orgoglioso haskeller

Stai bene con la versione attuale? Purtroppo non riesco a dividere l'ultima riga (tranne che negli spazi, il che ucciderebbe la leggibilità)
John Dvorak,

come ho detto, fai quello che vuoi
orgoglioso haskeller il

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

1

Python 3 - 302

Nota: a causa di difficoltà di analisi, non vi sono frazioni con il numero 0 in (quindi non vengono calcolate frazioni con il metodo corretto).

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

Con n = 80:

[[64, 16]]

Con n = 147

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

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

Per n=80questo stampe [[64, 16], [65, 26]], ma ovviamente 65 + 26 = 91 > 80.
Ingo Bürk,

Trasforma tutte le ifs in un unico grande ifcon ands che collega tutte le condizioni? Salva parecchi caratteri, credo.
Soham Chowdhury,

@Soham Sì, grazie!
Decadimento beta

Potresti includere anche le prove che ho aggiunto? (E potresti forse vedere se trovi alcuni casi di test interessanti che dovrei aggiungere anche io?)
flawr

2
Dove sono 10/70, 20/60e 30/50?
John Dvorak,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.