# 在Stern-Brocot树中找到分数的位置

11

``````0.  0/1                                                             1/0
1.  0/1                             1/1                             1/0
2.  0/1             1/2             1/1             2/1             1/0
3.  0/1     1/3     1/2     2/3     1/1     3/2     2/1     3/1     1/0
4.  0/1 1/4 1/3 2/5 1/2 3/5 2/3 3/4 1/1 4/3 3/2 5/3 2/1 5/2 3/1 4/1 1/0
``````

``````2/3 -> 3/8   (4th number in iteration 3)
4/7 -> 9/32  (between 1/2 and 3/5 in the chart above)
1/1 -> 1/2   (middle number in the first iteration)
``````

``````0/1 -> 0/1   (0/1 is considered the left number)
1/0 -> 1/1   (1/0 is considered the rightmost number)
``````

Joe Z.

Joe Z.

2

1

1

## GolfScript（49 48 46个字符）

``````{0\@{}{@2*2\$2\$>!+@@{{\}3\$)*}:j~1\$-j}/\)\,?}:f;
``````

``````{0:x;\{}{.2\$<!2x*+:x){\}*1\$-{\}x)*}/x@)@,?}:g;
``````

``````while m != n do
if m < n then (output(L); n := n - m)
else (output(R); m := m - n)
``````

1

# Mathematica，130114111个字符

``````f=#~g~0&;0~g~q_=q;p_~g~q_:=g[#,(Sign[p-#]+q)/2]&@FromContinuedFraction[ContinuedFraction@p/.{x___,n_}:>{x,n-1}]
``````

### 例：

``````f[2/3]
``````

3/8

``````f[4/7]
``````

9/32

``````f[1]
``````

1/2

1

## 红宝石，132 125

@JoeZ摩擦并打高尔夫球的参考解决方案。

``````def t(n,d)u=k=0;v,j,f,g,b=[1,]*5;c=2
while(z=(f*d).<=>(g*n))!=0;z>0?(j,k=f,g):(u,v=f,g);b=b*2-z;f,g=u+j,v+k;c*=2;end
[b,c]end
``````

``````>> t(2,3)
=> [3, 8]
>> t(4,7)
=> [9, 32]
>> t(1,1)
=> [1, 2]
``````

1

## Ruby（69个字符） CoffeeScript（59个字符）

``````g=(a,b,x=0,y=1)->c=a>=b;a&&g(a-b*c,b-a*!c,2*x+c,2*y)||[x,y]
``````

``````f=(a,b,x=0,y=1,p=0)->a&&f(b%a,a,(x+p<<b/a)-p,y<<b/a,1-p)||[x+p,y]
``````

（65个字符；在线演示）。用这种方式编写它可以揭示与Euclid算法的关系。

@Howard，我不知道您使用的是哪个版本的Ruby，但是在IDEOne上，如果我尝试删除那些括号或使用该函数语法，则会收到语法错误。

0

# Python-531

Python中的非解决方案，可以用作最后的参考解决方案：

``````def sbtree(n, d):
ufrac = [0, 1]
lfrac = [1, 0]
frac = [1, 1]
bfrac = [1, 2]
while(frac[0] * d != frac[1] * n):
if(frac[0] * d > frac[1] * n):
# push it towards lfrac
lfrac[0] = frac[0]
lfrac[1] = frac[1]
bfrac[0] = bfrac[0] * 2 - 1
elif(frac[0] * d < frac[1] * n):
# push it towards ufrac
ufrac[0] = frac[0]
ufrac[1] = frac[1]
bfrac[0] = bfrac[0] * 2 + 1
frac[0] = ufrac[0] + lfrac[0]
frac[1] = ufrac[1] + lfrac[1]
bfrac[1] *= 2
return bfrac
``````

0

### GolfScript，54个字符

``````'/'/n*~][2,.-1%]{[{.~3\$~@+@@+[\]\}*].2\$?0<}do.@?'/'@,(
``````

``````> 4/7
9/32

> 9/7
35/64

> 5/1
31/32
``````

0

# Mathematica 138

``````q_~r~k_:=Nest[#+Sign@k/(2Denominator@# )&,q,Abs@k]
g@d_:=
Module[{l=ContinuedFraction@d,p=-1},
l[[-1]]-=1;
(p=-p;# p)&/@l]
h[q_]:=Fold[r,1/2,g@q]
``````

``````h[2/3]
h[4/7]
h[1]
``````

3/8
9/32
1/2

0

# JavaScript 186

``````f=(p1,q1,p2,q2)=>{if(p1*q2+1==p2*q1){return{p:p1+p2,q:q1+q2}}let p,q,pl=0,ql=1,ph=1,qh=0;for(;;){p=pl+ph;q=ql+qh;if(p*q1<=q*p1){pl=p;ql=q}else if(p2*q<=q2*p){ph=p;qh=q}else return{p,q}}}
``````

0

``````n((a,b):(c,d):r)=(a,b):(a+c,b+d):n((c,d):r)
n a=a
z=zip[0..]
t x=[(j,2^i)|(i,r)<-z\$iterate n[(0,1),(1,0)],(j,y)<-z r,x==y]!!0``````

`n`通过查看每对分数并将新的分数插入第一个和递归之间（它将第二个分数放在此处）来构造上一个分数的下一行。基本情况非​​常简单，因为它基本上只是身份功能。该`t`函数根据初始状态仅使用两个边界分数来无限期地迭代该函数。`t`然后索引每一行（`i`）和该行（`j`）中的每个项目，并寻找与我们要查找的内容相匹配的第一个分数。当找到它时，它`j`作为分子和`2^i`分母产生。