วิธีที่จะไม่ลดเศษส่วน


13

การลดเศษส่วนในทางที่ผิด

ในการแข่งขันกอล์ฟรหัสคุณต้องหาเศษส่วนที่สามารถลดความผิดได้ แต่ยังคงอยู่ในหมายเลขเดียวกัน

หมายเหตุ:การลดเศษส่วนในทางที่ผิดจะมีคำจำกัดความที่แน่นอนดูรายละเอียด

ตัวอย่าง:

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

แน่นอนว่าคุณไม่สามารถหยุดทั้ง 6es ได้ แต่ที่นี่คุณยังคงได้รับคุณค่าที่ถูกต้อง ในการท้าทายนี้คุณจะต้องค้นหาตัวอย่างเช่นนี้

รายละเอียด

คุณต้องเขียนฟังก์ชัน / โปรแกรมที่รับจำนวนเต็มบวกหนึ่งตัวnเป็นอินพุตและเอาต์พุต / ส่งคืนรายการ / อาร์เรย์ของเศษส่วนในรูปแบบ
numerator1,denominator1,numerator2,denominator2,...

โปรแกรมที่มีเพื่อหาสำหรับแต่ละส่วนa/bด้วยa+b=nและa,b>0ไม่ว่าจะสามารถลดลงได้ทางที่ผิด (ไม่สำคัญว่าจะลดลงในแบบปกติหรือมีความเป็นไปได้หลายอย่างในการลดมันก็ต้องมีความเป็นไปได้ที่จะลดลงในลักษณะที่ผิดอย่างน้อยหนึ่งวิธี)

คำจำกัดความของ วิธีที่ไม่ถูกต้อง:เศษส่วนสามารถลดลงได้ในทางที่ผิดถ้าหากต่อเนื่องกันของตัวเลขที่ต่อเนื่องกันปรากฏใน a และ b และถ้าค่าของเศษส่วนยังคงเหมือนเดิมหากคุณลบสตริงย่อย

ตัวอย่าง: 1536/353 สามารถ 'ลด' เพื่อ 16/3 แต่ทั้งสองค่าไม่เท่ากันดังนั้นคุณจึงไม่สามารถลดส่วนนี้ทางที่ผิด

โปรดทราบว่าคำจำกัดความของการลดวิธีที่ผิดนี้อาจรวมถึงเศษส่วนที่ลดลงในวิธีที่ถูกต้อง: 110/10 = 11/1อยู่ในคำนิยามของการลดวิธีที่ไม่ถูกต้องแม้ว่าจะเป็นขั้นตอนที่ถูกต้องก็ตาม

เกณฑ์การให้คะแนน

จำนวนไบต์น้อยที่สุดชนะ คุณสามารถเขียนฟังก์ชั่นหรือโปรแกรมที่รับจำนวนเต็มและส่งกลับอาร์เรย์หรือโปรแกรมที่ใช้ stdin / stdout หรือคุณสามารถพิจารณา n บันทึกไว้ในตัวแปรและในตอนท้ายของโปรแกรมรายการจะต้องบันทึกไว้ในตัวแปรอื่น

กรณีทดสอบ

โปรดรวมการทดสอบต่อไปนี้ (บอกฉันทีว่าควรเพิ่มอะไรฉันไม่ทราบว่าเศษส่วนเหล่านั้นมีเท่าไร / มีกี่ตัวอย่างที่คาดหวัง)

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
พิจารณาการกำหนดคำศัพท์สำหรับ "ทางที่ผิด" เช่น "โง่" หรือ "ประหลาด" ฉันคิดว่าการโพสต์นั้นจะง่ายต่อการเข้าใจเพราะผู้อ่านรีบหาว่าต้องมีคำจำกัดความสำหรับคำนั้น
Michael Easter

3
ถ้ามีหลายวิธีในการลดเศษส่วนและมีเพียงบางส่วนเท่านั้นที่ผิด 1010/10 = 101/1 && 1010/10 /= 110/1
John Dvorak

1
แตกต่างจากprojecteuler.net/problem=33 ?
user80551

1
กรณีทดสอบที่สองของคุณ ( n=147) ไม่ถูกต้อง: 49/89 != 4/8.
สลายตัวเบต้า

1
หากมีวิธีการลดเศษส่วนมากกว่าหนึ่งวิธีเราอาจรวมหลายครั้งในชุดผลลัพธ์หรือไม่
John Dvorak

คำตอบ:


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

การป้อนข้อมูลที่ต้องเก็บไว้ในการส่งออกจะถูกเก็บไว้ในnl

กรณีทดสอบ:

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]

ควรห้ามทำซ้ำในผลลัพธ์มันจะยาว 10 ตัวอักษร:

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

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]

หากไม่อนุญาตให้ส่งคืนอัตราส่วนเดิมมากกว่าหนึ่งครั้ง (400/400 = 40/40 = 4/4) ให้ใช้f n=nub[...เพื่อกรองออก

ส่งคืนรายการคู่ รายการคู่สององค์ประกอบมีค่าเท่ากัน รายการของเศษส่วนที่เกิดขึ้นจริงจะต้องนำเข้าData.Ratioหรือมีคุณสมบัติครบถ้วนData.Ratio.%(ซึ่งยังชนกับ%ฟังก์ชั่นที่กำหนดไว้ที่นี่)

กรณีทดสอบ (พร้อม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 และแสดงความคิดเห็น :

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]

คุณสามารถเปลี่ยน ';' ถึงบรรทัดใหม่ (ในรหัส golfed)? มันไม่เปลี่ยนจำนวนไบต์และทำให้โค้ดอ่านได้ง่ายขึ้น
ภูมิใจ haskeller

@proudhaskeller นั่นคือเจตนา; ฉันชอบมีบรรทัดน้อยลงในรหัส golfed นอกจากนี้ความยาวของเส้นจะสมดุลกันมากขึ้น คุณคิดว่าฉันควรเปลี่ยนหรือไม่
John Dvorak

ทำทุกอย่างที่คุณต้องการ แต่ฉันต้องการให้เส้นถูกกระจายออกไปดังนั้นฉันจะสามารถอ่านโค้ดได้ดีขึ้น (แทนที่จะหันไปใช้รหัสที่ไม่ถูกตรึง)
ภูมิใจ haskeller

คุณสบายดีกับเวอร์ชันปัจจุบันหรือไม่? ฉันไม่สามารถแยกบรรทัดสุดท้ายโชคไม่ดี (ยกเว้นในพื้นที่ซึ่งจะฆ่าการอ่าน)
จอห์น Dvorak

อย่างที่ฉันพูดทำในสิ่งที่คุณรู้สึก
ภูมิใจในใจ

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

หมายเหตุ:เนื่องจากปัญหาการแยกวิเคราะห์จึงไม่มีเศษส่วนที่มีตัวเลข 0 ใน (ดังนั้นจึงไม่มีการคำนวณเศษส่วนโดยใช้วิธีการที่ถูกต้อง)

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

ด้วย n = 80:

[[64, 16]]

ด้วย n = 147

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

ด้วย 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]]

สำหรับn=80พิมพ์นี้แต่อย่างเห็นได้ชัด[[64, 16], [65, 26]] 65 + 26 = 91 > 80
Ingo Bürk

เปิดทุกifs เป็นใหญ่เดียวifกับands เชื่อมต่อเงื่อนไขทั้งหมดหรือไม่ ฉันคิดว่าจะบันทึกไม่กี่ตัวอักษร
Soham Chowdhury

@ โซโหใช่แล้วขอบคุณ!
สลายตัวเบต้า

คุณสามารถใส่ชุดทดสอบที่ฉันเพิ่มเข้าไปได้หรือไม่ (และอาจจะคุณอาจจะดูว่าคุณพบบางกรณีทดสอบที่น่าสนใจฉันควรเพิ่มมากเกินไป?)
flawr

2
อยู่ที่ไหน10/70, 20/60และ30/50?
John Dvorak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.