有理数関数


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 Fruit

回答:


4

J、41 36文字

整数を受け取り、2つの整数で構成されるベクトルを返します。完全に暗黙的でも完全でもない私の最初の解決策。

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

以下は、適切な場所にスペースを挿入したソリューションです。

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

説明:

  1. x (, % +.) y–分子xと分母yが最小の分母に縮小された分数を表す長さ2のベクトル
  2. 1 + i. 1 + y以下からの整数の-aベクトル1y + 1
  3. (, % +.)"0/~ 1 + i. 1 + y範囲の非還元分母と分子を持つすべての縮小画分の-aマトリックス1y + 1
  4. <`(<@|.)/. y–マトリックスの斜めの対角線の配列y。互いに対角線を反転
  5. ~. ; y–対角線の配列が要素のベクトルに折りたたまれ、重複が削除されます
  6. x { y–の位置xにあるアイテムy
  7. (u v) y–と同じy u v y。この特定のユースケースでuは、is {vis3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'


8

Haskell、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によって提案されたIDを適用

定義により、gcd (r-b) b == gcd r bさらに4つのキャラクターを削ることができます。
マティアスGiovannini

3

Python、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

Perl 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.