第n个分子


26

您可以创建所有有理数0 <r≤1的列表,方法是先按分母然后按分子顺序列出:

1  1  1  2  1  3  1  2  3  4  1  5  1  2  3  4  5
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
1  2  3  3  4  4  5  5  5  5  6  6  7  7  7  7  7

请注意,我们将跳过之前已经出现的任何有理数。例如2/5被跳过,因为我们已经列出了1/2。

在此挑战中,我们仅对分子感兴趣。查看上面的列表,编写一个函数或程序,该函数或程序采用正整数n,该整数从列表中返回第n个 分子


测试用例:

1 -> 1
2 -> 1
3 -> 1
4 -> 2
5 -> 1
6 -> 3
7 -> 1
8 -> 2
9 -> 3
50 -> 4
80 -> 15


2
实际上只是(0,1]
罗伯特·弗雷泽

@RobertFraser好点。
orlp

Answers:


7

MATL17 13字节

:tt!/XR6#uG))

在线尝试!验证所有测试用例

输入大小可能会受到浮点精度的限制。所有测试用例都给出正确的结果。

说明

这产生的所有级分k/mkm[1 2 ...n]作为n× n矩阵。行表示分子,列表示分母。实际上,矩阵项包含的是反分数m/k,而不是k/m,但这无关紧要,在其余的解释中可以忽略。

矩阵条目被隐式视为按列优先顺序排序。在这种情况下,这对应于所需的顺序:分母,然后是分子。

此矩阵中需要忽略三种类型的条目:

  1. k/mk>m即具有相同的值作为先前的条目(例如,2/4被忽略,因为它是一样的1/2
  2. 条目k/kk>1。分子超过分母的条目
  3. 条目k/mk<m(这些不是问题的一部分)。

忽略条目是通过一个unique函数完成的,该函数会稳定地删除重复的值并输出尚存条目的索引。这样,上面类型1的条目将被自动删除。为了处理类型2和3,将对角线和下方的矩阵条目设置为0。这样,除第一个(对应于有效分数1/1)外,所有零条目都将被删除。

以输入4为例。

:     % Input n implicitly. Push range [1 2 ...n]
      % STACK: [1 2 3 4]
t     % Duplicate
      % STACK: [1 2 3 4], [1 2 3 4]
t!    % Duplicate and transpose
      % STACK: [1 2 3 4], [1 2 3 4], [1; 2; 3; 4]
/     % Divide element-wise with broadcast: gives matrix with all pairs
      % STACK: [1 2 3 4], [1       2       3       4;
                           0.5000  1       1.5000  2;
                           0.3333  0.6667  1       1.3333;
                           0.2500  0.5000  0.7500  1     ]
XR    % Upper triangular part above the diagonal. This sets to 0 all entries
      % corresponding to fractions that equal or exceed 1. (Since the matrix
      % actually contains the inverse fractions, nonzero entries will contain
      % values greater than 1)
      % STACK: [1 2 3 4], [0       2       3       4;
                           0       0       1.5000  2;
                           0       0       0       1.3333;
                           0       0       0       0     ]
6#u   % Indices of first appearance of unique elements
      % STACK: [1 2 3 4], [1; 5; 9; 10; 13; 15]
G     % Push input n again
      % STACK: [1 2 3 4], [1; 5; 9; 10; 13; 15], 4
)     % Index: get the n-th entry from the array of indices of unique elements
      % STACK: [1 2 3 4], 10
)     % Index (modular): get the corresponding real part. Display implicitly
      % STACK: 2

4

果冻11 9 字节

gRỊTµ€Fị@

在线尝试!验证所有测试用例

怎么运行的

gRỊTµ€Fị@  Main link. Argument: n

    µ€     Map the monadic chain to the left over [1, ..., n]; for each k:
 R           Range; yield [1, ..., k].
g            Compute the GCD of k and each j in [1, ..., k].
  Ị          Insignificant; yield 1 for 1; 0 for 2, ..., k.
   T         Truth; yield all indices of 1's, i.e., all coprimes with k.
      F      Flatten the resulting 2D array.
       ị@    At-index swapped; return the n-th element.

4

Mathematica,53个字节

(Join@@Select[Range@a,a~GCD~#==1&]~Table~{a,#})[[#]]&

4

Haskell,40个字节

((0:[n|d<-[1..],n<-[1..d],gcd n d<2])!!)

匿名函数。非常简单:使用列表推导生成无限列表,循环遍历所有分子n和相对质数的分母d。零指数转换成一个指数的,我们前置一个0,这需要4个字节。


n<-[0..d]以较短的方式添加零并保存4个字节
Angs


1

Pyth,11个字节

@sm.mibdhdS

在线尝试:演示

说明:

@sm.mibdhdSQQ   implicit Qs at the end (Q = input number)
  m       SQ    map each denominator d from [1, 2, ..., Q] to:
   .m   hd        select the numerators b from [0, 1, ..., d]
     ibd             for which gcd(b, d) == 1 (which is the smallest possible gcd)
                  this gives [0, 1] for d=1, [1] for d=2, [1,2] for d=3, ...
 s              combine all lists to a big one
@           Q   print the Qth element

1

实际上,15个字节

该答案基于Dennis的Jelly答案HN最后,我使用它来避免0索引的问题,并且需要减少n并在开始或结束时进行交换。H获取生成n的分子列表的第一个成员,并N获取该选择的最后一个成员,即nth分子,所有这些都无需摆弄堆栈操作。欢迎打高尔夫球。在线尝试!

;R`;r;)♀┤░`MΣHN

开球

          Implicit input n.
;         Duplicate n. Leave one n on the stack for getting the nth numerator at the end.
R`...`M   Map the following function over the range [1..n]. Variable m.
  ;         Duplicate m. Leave one m on the stack for checking coprimality later.
  r         Push the range [0...m].
  ;)        Move a duplicate of range [0...m] to BOS.
  ♀┤        Push a list of 0's and 1's where a 1 denotes a number coprime to m (a numerator),
             and 0 denotes a fraction we have counted before.
  ░         Filter the second list (range [0...m]) 
             by the truthy values in the first list (our coprime check).
Σ         Sum all of the lists in the result into one list.
H         Push result[:n] using the duplicate of n from the beginning of the program.
N         Push result[:n][:-1], which is the same as result[n-1], our nth numerator.
          Implicit return.

1

Python,111110字节

from fractions import*
def g(n):
 x,y=1,1
 while n>1:
  x+=1
  if x>y:x,y=1,y+1
  if gcd(x,y)<2:n-=1
 return x

分数用表示x/yn当找到一个新的拟合分数时,该参数会减小(可以gcd通过fractions检查减少分数)。在循环的每次迭代中,x递增,然后,如果出现“特殊情况” ,则开始x>=y一系列新的分数,以表示。y+1>(x,y)=(2,1)x>y

我敢肯定,这可以打更多,但我缺少可以改进的地方。找到了。

链接到代码和测试用例


0

JavaScript(ES6),95个字节

n=>[...Array(n*n).keys()].filter(i=>i%n<=i/n&g(i%n+1,i/n+1|0)<2,g=(a,b)=>b?g(b,a%b):a)[n-1]%n+1

通过使用从1到的分子和分母生成所有分数n并滤除大于1或以前看到的那些分数,然后取nth来工作。


0

Perl,82 + 2(-pl标志)= 84字节

perl -ple '{{$d>$n?($n++,(grep!($n%$_||$d%$_),2..$d)&&redo):($n=1,$d++)}++$i!=$_&&redo;$_=$n}'

取消高尔夫:

while (<>) {  # -p flag
    chomp();  # -l flag

    my $i = 0;
    my $n = 0;
    my $d = 0;

    for (;;) {
        for (;;) {
            if ($d <= $n) {
                $n = 1;
                $d++;
                last;
            }
            else {
                $n++;
                last unless grep { !($n % $_) && !($d % $_) } 2 .. $d;
            }
        }
        if (++$i == $_) {
            $_ = $n;
            last;
        }
    }
}
continue {
    print($_, "\n");
}

0

JavaScript(ES6),76

x=>eval("for(g=(a,b)=>b?g(b,a%b):a,d=n=0;x;g(n,d)-1||--x)n=++n>d?(++d,1):n")

少打高尔夫球

x=>{
  g=(a,b) => b ? g(b,a%b) : a; // gcd
  for (d=n=0; x; )
  {
     ++n;
     if (n > d)
     {
        ++d;
        n=1;
     }
     if (g(n,d) == 1) // if the fraction is irreducible 
        --x;
  }
  return n
}

测试

f=
x=>eval("for(g=(a,b)=>b?g(b,a%b):a,d=n=0;x;g(n,d)-1||--x)n=++n>d?(d++,1):n")

;`1 -> 1
2 -> 1
3 -> 1
4 -> 2
5 -> 1
6 -> 3
7 -> 1
8 -> 2
9 -> 3
50 -> 4
80 -> 15`.split`\n`.forEach(
  r=>{
    var [a,k]=r.match(/\d+/g),r=f(a)
    console.log(r==k?'OK':'KO',a,r)
  }
)  


0

Clojure,85个字节

#(if(= 1 %)1(numerator(nth(distinct(for[i(range)j(range 1(inc i))](/ j i)))(dec %))))

使用列表推导生成所有有理数的列表,然后对其进行过滤以仅获取不同的有理数。获取nth列表中的项目并返回其分子。另外,第一个元素需要单独的条件,因为Clojure无法使用整数的分子。(出于任何原因,认为整数不是Rational的原因– https://goo.gl/XETLo2

在线查看-https: //ideone.com/8gNZEB

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.