El enésimo numerador


26

Puede crear una lista de todos los racionales 0 <r ≤ 1 enumerándolos ordenados primero por denominador y luego por numerador:

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

Tenga en cuenta que omitimos cualquier número racional que ya haya ocurrido antes. Por ejemplo, se omite 2/4 porque ya enumeramos 1/2.

En este desafío solo nos interesan los numeradores. Mirando la lista anterior, escriba una función o programa tomando un entero positivo n que devuelva el enésimo numerador de la lista.


Casos de prueba:

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


2
En realidad, solo una lista de los fundamentos en(0,1]
Robert Fraser

@RobertFraser Buen punto.
orlp

Respuestas:


7

MATL , 17 13 bytes

:tt!/XR6#uG))

Pruébalo en línea! O verificar todos los casos de prueba .

El tamaño de entrada puede estar limitado por la precisión del punto flotante. Todos los casos de prueba dan el resultado correcto.

Explicación

Esto genera todas las fracciones k/mcon k, men [1 2 ...n], como una matriz n× n. La fila indica el numerador y la columna indica el denominador. En realidad, la entrada de la matriz contiene la fracción inversa m/k, en lugar de k/m, pero esto es irrelevante y puede ignorarse en el resto de la explicación.

Las entradas de matriz se consideran implícitamente ordenadas en orden de columna mayor. En este caso esto corresponde al orden requerido: denominador, luego numerador.

Se deben descartar tres tipos de entradas de esta matriz:

  1. Entradas k/m, k>m, que tienen el mismo valor como una entrada anterior (por ejemplo, 2/4no es considerada ya que es el mismo que 1/2)
  2. Entradas k/k, k>1. Entradas que tienen un numerador que excede el denominador
  3. Entradas k/m, k<m(estos no son parte del problema).

Hacer caso omiso de las entradas se realiza con una uniquefunción, que elimina de manera estable los valores duplicados y genera los índices de las entradas supervivientes. Con esto, las entradas de tipo 1 anteriores se eliminan automáticamente. Para tratar con los tipos 2 y 3, las entradas de matriz en la diagonal y debajo se establecen en 0. De esta forma, se eliminarán todas las entradas cero, excepto la primera (correspondiente a la fracción válida 1/1).

Considere la entrada 4como un ejemplo.

:     % 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

Jalea , 11 9 bytes

gRỊTµ€Fị@

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo funciona

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 bytes

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

4

Haskell, 40 bytes

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

Una función anónima. Bastante sencillo: utiliza una comprensión de lista para generar una lista infinita, recorriendo todos los numeradores ny denominadores relativamente primos d. Para convertir el índice cero a uno indexado, anteponemos a 0, que toma 4bytes.


n<-[0..d]agrega el cero de una manera más corta y guarda los 4 bytes
Angs


1

Pyth, 11 bytes

@sm.mibdhdS

Pruébelo en línea: demostración

Explicación:

@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

En realidad , 15 bytes

Esta respuesta se basa en la respuesta de Dennis 'Jelly . Lo uso HNal final para evitar problemas con la indexación 0 y la necesidad de disminuir n e intercambiar al principio o al final. Hobtiene los primeros nmiembros de la lista de numeradores que resultan y Nobtiene el último miembro de esa selección, es decir, el nnumerador th, todo sin jugar con las operaciones de pila. Sugerencias de golf bienvenidas. Pruébalo en línea!

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

No golfista

          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, 111 110 bytes

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

La fracción se representa con x/y. El argumento ndisminuye cuando se encuentra una nueva fracción de ajuste (las comprobaciones gcddesde fractionspueden reducir la fracción). En cada iteración del bucle, xse incrementa, luego, si x>=y, y+1se inicia una nueva serie de fracciones con , >debido al "caso especial" (x,y)=(2,1), golfed a x>y.

Estoy seguro de que esto se puede jugar más, pero me falta dónde podría mejorarlo. Lo encontré.

Enlace al código y casos de prueba


0

JavaScript (ES6), 95 bytes

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

Funciona generando todas las fracciones con numeradores y denominadores desde 1hasta ny filtrando las mayores que 1las vistas anteriormente, y luego tomando el nth.


0

Perl, 82 + 2 ( -plbandera) = 84 bytes

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

Sin golf:

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")

Menos golf

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
}

Prueba

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 bytes

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

Utiliza la comprensión de la lista para generar una lista de todos los racionales, luego la filtra para obtener solo los distintos. Toma el nthelemento de la lista y devuelve su numerador. También se necesita una condición separada para el primer elemento porque Clojure no puede tomar el numerador de un entero. (por cualquier razón, considerando que un entero no es racional - https://goo.gl/XETLo2 )

Véalo en línea: https://ideone.com/8gNZEB

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.