MATL , 17 13 bytes
:tt!/XR6#uG))
Experimente online! Ou verifique todos os casos de teste .
O tamanho da entrada pode ser limitado pela precisão do ponto flutuante. Todos os casos de teste fornecem o resultado correto.
Explicação
Isso gera todas as frações k/m
com k
, m
em [1 2 ...n]
, como uma matriz n
× n
. A linha indica o numerador e a coluna indica o denominador. Na verdade, a entrada da matriz contém a fração inversa m/k
, em vez de k/m
, mas isso é irrelevante e pode ser ignorada no restante da explicação.
As entradas da matriz são consideradas implicitamente classificadas na ordem principal da coluna. Nesse caso, isso corresponde à ordem necessária: denominador e numerador.
Três tipos de entradas precisam ser desconsiderados nessa matriz:
- As entradas
k/m
, k>m
que têm o mesmo valor como uma entrada anterior (por exemplo, 2/4
não é considerado porque é a mesma que 1/2
)
- Entradas
k/k
, k>1
. Entradas que possuem um numerador que excede o denominador
- Entradas
k/m
, k<m
(estes não são parte do problema).
A desconsideração de entradas é feita com uma unique
função, que remove de forma estável os valores duplicados e gera os índices das entradas sobreviventes. Com isso, as entradas do tipo 1 acima são removidas automaticamente. Para lidar com os tipos 2 e 3, as entradas da matriz na diagonal e abaixo são definidas como 0
. Dessa forma, todas as zero entradas serão removidas, exceto a primeira (correspondente à fração válida 1/1
).
Considere a entrada 4
como um exemplo.
: % 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