합리적인 계산 기능


11

자연수 (0부터 시작)를 취하는 함수를 만들고 각각 분자와 분모 인 양의 정수 쌍을 반환합니다. 대각선 횡단을 사용하십시오. 이전에 계산 된 숫자는 건너 뛰어야합니다. (건너 뛴 값 집합을 기억할 수 있음)

도표:

여기에 이미지 설명을 입력하십시오

빨간색은 건너 뛴 값

값 :

  • f (0) = 1, 1
  • f (1) = 2, 1
  • f (2) = 1, 2
  • f (3) = 1, 3
  • f (4) = 3, 1 (스킵 통지)
  • f (5) = 4, 1
  • f (6) = 3, 2
  • f (7) = 2, 3
  • f (8) = 1, 4
  • f (9) = 1, 5
  • f (10) = 5, 1 (스킵 통지)

Rational 데이터 구조 및 해당 조작이있는 경우이를 사용할 수 있습니다. 가장 짧은 코드가 승리합니다.


1
각 대각선에서 계산 된 합리적 숫자의 수는 해당 대각선의 공통 합계의 유효 기능입니다.
— Leaky Nun

나는이 도전이 오래되었다는 것을 알고 있지만 받아 들여진 것보다 짧은 대답이 있으므로 다시 받아들이고 싶을 수도 있습니다.
— Esolanging 과일

답변:


4

J, 41 36 자

정수를 취하고 두 정수로 구성된 벡터를 반환합니다. 완전히 암묵적이거나 명시 적이 지 않은 나의 첫 번째 해결책.

{3 :'~.;<`(<@|.)/.(,%+.)"0/~1+i.1+y'

적절한 곳에 공백이 삽입 된 솔루션은 다음과 같습니다.

{ 3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'

설명:

  1. x (, % +.) y분자 x와 분모 y가 가장 작은 분모로 축소 된 분수를 나타내는 길이 2의 벡터
  2. 1 + i. 1 + y–에서 1~ 까지의 정수 벡터y + 1
  3. (, % +.)"0/~ 1 + i. 1 + y– 범위에서 감소되지 않은 분모와 분자를 가진 모든 감소 된 분수의 행렬 1 로 y + 1.
  4. <`(<@|.)/. y– 행렬의 비스듬한 대각선 배열 y , 서로
  5. ~. ; y– 대각선 배열이 복제물이 제거 된 요소 벡터로 축소되었습니다.
  6. x { y–의 위치에 x있는 품목y
  7. (u v) y–와 동일합니다 y u v y. 이 특정 사용 사례에서 uis {and vis3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'


8

하스켈, 78 자

q(r,f)=[(r-b,b)|b<-f[1..r-1],r`gcd`b==1]
d=reverse:id:d
f=((zip[2..]d>>=q)!!)

샘플 실행 :

> map f [0..10]
[(1,1),(2,1),(1,2),(1,3),(3,1),(4,1),(3,2),(2,3),(1,4),(1,5),(5,1)]
> f 100
(17,1)
> f 1000
(3,55)

  • 편집 : (100 → 87) 바보 나, 그냥 gcd를 테스트하면 충분합니다!
  • 편집 : (87 → 85) 영리한 트릭과 cycle행 순서를 대체하는 기능
  • 편집 : (85 → 82) cycle수제 무한 목록으로 대체d
  • 편집 : (82 → 78) gcdMatías가 제안한대로 적용되는 정체성

정의에 따라 gcd (r-b) b == gcd r b4 개 문자를 더 면도 할 수 있습니다.
— Matías Giovannini

3

파이썬, 144 자

def F(i):
 r,d,z=[1],1,[]
 while z[:i]==z:z+=[(x,y)for x,y in zip(r[::d],r[::-d])if all(x%j+y%j for j in r[1:])];d=-d;r+=[r[-1]+1]
 return z[i]

2

루비 1.9 109 106

F=->n{x=y=d=1
e=0
n.times{(x+=d).gcd(y+=e)>1&&redo
x<2?d<0?d=0:(d,e=1,-1):y<2?e<0?e=0:(d,e=-1,1):0}
[x,y]}

2

OCaml + 배터리, 182168 자

이것은 Haskell에서 자연 스럽지만 OCaml에서는 거의 불가능합니다.

open LazyList
let rec r(i,j)=lazy(let a,b=if(i+j)mod 2=0then i,j else j,i in
Cons((a,b),filter(fun(c,d)->a*d<>c*b)(r(if j=1 then 1,i+1else i+1,j-1))))
let f=nth(r(1,1))

편집 : 대각선이 필요하지 않습니다


0

펄 6 , 75 바이트

{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique[$_]}

그것을 테스트

이것은 기본적으로 합리적 값의 전체 시퀀스를 생성하며 인덱스 값이 생성 된 후에 만 ​​중지됩니다.

( 나의 골프 를 바탕으로 다른 도전 에 기초를 두었다.)

넓히는:

{  # bare block lambda with implicit parameter $_

  (
      ( # sequence of numerators

        {
          |( # slip into outer sequence (flatten)

            1      # start at one
            …
            (
              $    # state variable
              += 2 # increment it by two each time this block is called
            )
            …
            1      # finish at one
          )

        }
        … * # never stop generating values
      )


    Z/   # zip using &infix:« /  » (generates Rats)


      ( # sequence of denominators

        1,  # start with an extra one

        {
          |( # slip into outer sequence (flatten)

            1
            …
            (
              ( $ ||= 1 ) # state variable that starts with 1 (rather than 0)
              += 2        # increment it by two each time this is called
            )
            …
            1
          )
        }
        … * # never stop generating values
      )


  ).unique                # get only the unique values
  .[ $_ ]                 # index into the sequence
}

({1…($+=2)…1}…*)무한한 분자 시퀀스를 생성합니다 ( |(…)위에서 사용하여 평탄화).

(1 2 1)
(1 2 3 4 3 2 1)
(1 2 3 4 5 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1)
…

(1,{1…(($||=1)+=2)…1}…*) 무한 분모의 분모를 생성

1
(1 2 3 2 1)
(1 2 3 4 5 4 3 2 1)
(1 2 3 4 5 6 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3 2 1)
…
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.