Làm thế nào để giảm phân số


12

Giảm phân số sai cách

Trong thử thách chơi gôn mã này, bạn phải tìm các phân số có thể được giảm sai cách nhưng vẫn kết thúc với cùng một số.

Lưu ý: giảm phân số sai cách ở đây có định nghĩa chính xác, xem chi tiết.

Thí dụ:

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

Tất nhiên bạn không thể tấn công cả 6es nhưng ở đây bạn vẫn kết thúc với giá trị chính xác. Trong thử thách này, bạn phải tìm những ví dụ như thế này.

Chi tiết

Bạn phải viết một hàm / chương trình chấp nhận một số nguyên dương nlàm đầu vào và đầu ra / trả về một danh sách / mảng các phân số có định dạng
numerator1,denominator1,numerator2,denominator2,...

Chương trình phải tìm ra từng phân số a/bvới a+b=na,b>0liệu nó có thể được giảm sai cách hay không . (Không quan trọng là liệu nó có thể được giảm theo cách thông thường hay có nhiều khả năng giảm hay không, chỉ cần có thể giảm theo cách sai theo ít nhất một cách.)

Định nghĩa sai cách: Một phân số có thể được giảm theo cách sai khi và chỉ khi cùng một chuỗi các chữ số liên tiếp xuất hiện trong a và b nếu giá trị của phân số giữ nguyên nếu bạn loại bỏ chuỗi con.

Ví dụ: 1536/353 có thể được 'giảm' xuống 16/3 nhưng hai giá trị đó không bằng nhau nên bạn không thể giảm phân số này sai cách .

Lưu ý rằng định nghĩa giảm sai cách này cũng có thể bao gồm các phân số được giảm theo đúng cách: 110/10 = 11/1nằm trong định nghĩa giảm sai cách mặc dù đó là một bước hợp lệ.

Chấm điểm

Số byte ít nhất sẽ thắng. Bạn có thể viết một hàm hoặc chương trình chấp nhận một số nguyên và trả về một mảng hoặc một chương trình sử dụng stdin / stdout hoặc bạn có thể xem xét n được lưu trong một biến và vào cuối chương trình, danh sách phải được lưu trong một biến khác.

Các trường hợp thử nghiệm

Vui lòng bao gồm các mẫu thử sau (Hãy cho tôi biết những cái nào tôi nên thêm, tôi không biết có bao nhiêu phân số có / bao nhiêu ví dụ để mong đợi)

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
Xem xét việc xác định một thuật ngữ cho "cách sai", chẳng hạn như "ngớ ngẩn" hoặc "kỳ dị". Tôi nghĩ rằng bài viết sẽ dễ hiểu hơn, bởi vì độc giả ngay lập tức mò mẫm rằng phải có một định nghĩa cho thuật ngữ này.
Michael Easter

3
Điều gì xảy ra nếu có nhiều cách để giảm một phần và chỉ một số trong số đó là sai? 1010/10 = 101/1 && 1010/10 /= 110/1
John Dvorak


1
Trường hợp thử nghiệm thứ hai của bạn ( n=147) không chính xác : 49/89 != 4/8.
Beta Decay

1
Nếu có nhiều hơn một cách để giảm một phần, chúng ta có thể đưa nó nhiều lần vào tập kết quả không?
John Dvorak

Câu trả lời:


3

Con trăn 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],[])

đầu vào phải được lưu trữ trong n, đầu ra sẽ được lưu trữ trong l.

Các trường hợp thử nghiệm:

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]

Nếu các bản sao trong đầu ra bị cấm, nó sẽ dài hơn 10 ký tự:

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?) Ký tự

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]

Nếu không được phép trả lại cùng một tỷ lệ nhiều lần (400/400 = 40/40 = 4/4), hãy sử dụng f n=nub[...để lọc chúng ra.

Trả về một danh sách các cặp. Một danh sách các cặp hai yếu tố có giá như nhau. Một danh sách các phân số thực tế sẽ yêu cầu nhập Data.Ratiohoặc đủ điều kiện Data.Ratio.%(cũng xung đột với %chức năng được xác định ở đây)

trường hợp thử nghiệm (với 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)]

vô lương tâm và bình luận :

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]

Bạn có thể thay đổi ';' đến dòng mới (trong mã golf)? nó không thay đổi số byte và nó làm cho mã dễ đọc hơn nhiều
tự hào

@proudhaskeller Điều đó có chủ ý; Tôi thích có ít dòng trong mã golf. Ngoài ra, độ dài dòng được cân bằng hơn theo cách này. Bạn có nghĩ rằng tôi nên thay đổi?
John Dvorak

làm bất cứ điều gì bạn muốn, nhưng tôi muốn các dòng được trải ra để tôi có thể đọc mã tốt hơn (thay vào đó sử dụng mã không được mã hóa)
tự hào

Bạn có ổn với phiên bản hiện tại không? Thật không may, tôi không thể phân chia dòng cuối cùng, ngoại trừ (tại các khoảng trắng, sẽ giết chết khả năng đọc)
John Dvorak

như tôi đã nói, hãy làm bất cứ điều gì bạn cảm thấy
tự hào

1

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

Con trăn 3 - 302

Lưu ý: Do khó khăn trong việc phân tích cú pháp, không có phân số nào có số 0 trong (vì vậy không có phân số nào được tính bằng phương pháp đúng).

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

Với n = 80:

[[64, 16]]

Với n = 147

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

Với 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]]

Đối với n=80bản in này [[64, 16], [65, 26]], nhưng rõ ràng 65 + 26 = 91 > 80.
Ingo Bürk

Biến tất cả các ifs thành một lớn duy nhất ifvới ands kết nối tất cả các điều kiện? Tiết kiệm khá nhiều ký tự, tôi nghĩ vậy.
Soham Chowdhury

@Soham Vâng, đúng vậy, cảm ơn!
Beta Decay

Bạn cũng có thể bao gồm các testcase tôi đã thêm? (Và có lẽ bạn có thể thấy nếu bạn tìm thấy một số trường hợp thử nghiệm thú vị mà tôi cũng nên thêm vào không?)
flawr

2
Ở đâu 10/70, 20/6030/50?
John Dvorak
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.