분수를 줄이지 않는 방법


13

분수 를 잘못된 방법으로 줄이기

이 코드 골프 챌린지에서 잘못된 방법으로 줄일 수는 있지만 여전히 같은 숫자로 끝나는 분수를 찾아야합니다.

참고 : 분수 를 잘못 줄이면 정확한 정의가 있습니다. 자세한 내용을 참조하십시오.

예:

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

물론 두 6 모두를 칠 수는 없지만 여기서는 여전히 올바른 값으로 끝납니다. 이 과제에서 이와 같은 예를 찾아야합니다.

세부

하나의 양의 정수 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
"goofy"또는 "freaky"와 같은 "잘못된 방법"에 대한 용어를 정의하십시오. 독자들은 용어에 대한 정의가 있어야한다고 즉시 이해했기 때문에 게시물을 이해하기가 더 쉽다고 생각합니다.
Michael Easter

3
분수를 줄이는 여러 가지 방법이 있고 그중 일부만 잘못되면 어떻게 될까요? 1010/10 = 101/1 && 1010/10 /= 110/1
John Dvorak


1
두 번째 테스트 사례 ( n=147)가 잘못되었습니다 : 49/89 != 4/8.
Beta Decay

1
분수를 줄이는 방법이 두 가지 이상인 경우 결과 집합에 분수를 여러 번 포함시킬 수 있습니까?
John Dvorak

답변:


3

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

입력은에 저장되어야 n하고 출력은에 저장됩니다 l.

테스트 사례 :

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

하스켈, 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]

';'을 변경할 수 있습니까 개행 (골프 코드)? 그것은 바이트 수를 변경하지 않습니다 그리고 그것은 훨씬 더 읽을 수있는 코드합니다
자랑 haskeller

@proudhaskeller 고의입니다; 골프 코드에 줄이 적은 것을 좋아합니다. 또한이 방법으로 선 길이가보다 균형을 이룹니다. 내가 바꿔야한다고 생각합니까?
John Dvorak

당신이 원하는 무엇이든 할,하지만 난 더 나은 코드를 읽을 수있을 것입니다 수 있도록 라인이 (오히려 다음 ungolfed 코드에 의존) 밖으로 확산 될 싶습니다
자랑 haskeller

현재 버전에 문제가 없습니까? 불행히도 마지막 줄을 나눌 수 없습니다 (공간을 제외하고 가독성을 떨어
John Dvorak

내가 말했듯이, 당신이 느끼는대로하세요
자랑스런 헤 켈러

1

파이썬 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

파이썬 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

모든 켜고 if하나의 큰로들 ifand모든 조건을 연결의? 꽤 많은 문자를 절약한다고 생각합니다.
Soham Chowdhury

@Soham 예, 감사합니다!
Beta Decay

내가 추가 한 테스트 케이스도 포함시킬 수 있습니까? (그리고 내가 추가해야 할 흥미로운 테스트 사례가 있는지 알 수 있을까요?)
flawr

2
어디 10/70, 20/60그리고 30/50?
John Dvorak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.