Le nième numérateur

26

Vous pouvez créer une liste de tous les rationnels 0 <r ≤ 1 en les répertoriant d'abord par dénominateur puis par numérateur:

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

Notez que nous ignorons tout nombre rationnel qui s'est déjà produit auparavant. Par exemple, 2/4 est ignoré car nous avons déjà répertorié 1/2.

Dans ce défi, nous nous intéressons uniquement aux numérateurs. En regardant la liste ci-dessus, écrivez une fonction ou un programme prenant un entier positif n qui renvoie le nième numérateur de la liste.


Testcases:

1 -> 1
2 -> 1
3 -> 1
4 -> 2
5 -> 1
6 -> 3
7 -> 1
8 -> 2
9 -> 3
50 -> 4
80 -> 15
orlp
la source
2
En fait, juste une liste des justifications de(0,1]
Robert Fraser
@RobertFraser Bon point.
orlp

Réponses:

7

MATL , 17 13 octets

:tt!/XR6#uG))

Essayez-le en ligne! Ou vérifiez tous les cas de test .

La taille d'entrée peut être limitée par la précision en virgule flottante. Tous les cas de test donnent le résultat correct.

Explication

Cela génère toutes les fractions k/mavec k, mdans [1 2 ...n], comme une matrice n× n. La ligne indique le numérateur et la colonne le dénominateur. En fait, l'entrée de la matrice contient la fraction inverse m/k, au lieu de k/m, mais cela n'est pas pertinent et peut être ignoré dans le reste de l'explication.

Les entrées de matrice sont implicitement considérées comme triées par ordre de colonne. Dans ce cas, cela correspond à l'ordre requis: dénominateur, puis numérateur.

Trois types d'entrées doivent être ignorés de cette matrice:

  1. Les inscriptions k/m, k>mqui ont la même valeur que d' une entrée précédente (par exemple, 2/4est ignoré parce qu'il est le même que 1/2)
  2. Entrées k/k, k>1. Entrées dont le numérateur dépasse le dénominateur
  3. Entrées k/m, k<m(elles ne font pas partie du problème).

Ignorer les entrées se fait avec une uniquefonction qui supprime de manière stable les valeurs en double et génère les indices des entrées survivantes. Avec cela, les entrées de type 1 ci-dessus sont automatiquement supprimées. Pour gérer les types 2 et 3, les entrées de matrice en diagonale et en dessous sont définies sur 0. De cette façon, toutes les entrées nulles seront supprimées sauf la première (correspondant à la fraction valide 1/1).

Considérez la saisie 4comme exemple.

:     % 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
Luis Mendo
la source
4

Gelée , 11 9 octets

gRỊTµ€Fị@

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

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.
Dennis
la source
4

Mathematica, 53 octets

(Join@@Select[Range@a,a~GCD~#==1&]~Table~{a,#})[[#]]&
JungHwan Min
la source
4

Haskell, 40 octets

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

Une fonction anonyme. Assez simple: utilise une compréhension de liste pour générer une liste infinie, en boucle sur tous les numérateurs net dénominateurs relativement premiers d. Pour convertir un index nul en un indexé, nous ajoutons a 0, qui prend des 4octets.

xnor
la source
n<-[0..d]ajoute le zéro de manière plus courte et enregistre les 4 octets
Angs
1

Pyth, 11 octets

@sm.mibdhdS

Essayez-le en ligne: Démonstration

Explication:

@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
Jakube
la source
1

En fait , 15 octets

Cette réponse est basée sur la réponse Jelly de Dennis . J'utilise HNà la fin pour éviter les problèmes avec l'indexation 0 et avoir besoin de décrémenter n et de permuter au début ou à la fin. Hobtient les premiers nmembres de la liste des numérateurs qui en résulte et Nobtient le dernier membre de cette sélection, c'est-à-dire le ne numérateur, le tout sans tripoter les opérations de pile. Suggestions de golf bienvenues. Essayez-le en ligne!

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

Ungolfing

          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.
Sherlock9
la source
1

Python, 111 110 octets

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 fraction est représentée par x/y. L'argument nest décrémenté quand une nouvelle fraction de raccord se trouve (le gcdde fractionschèques peut être réduite de la fraction). À chaque itération de la boucle, xest incrémenté, puis, si x>=y, une nouvelle série de fractions avec y+1est démarrée, en >raison du "cas spécial" (x,y)=(2,1), joué au golf x>y.

Je suis sûr que cela peut être joué davantage, mais je ne sais pas où je pourrais l'améliorer. Je l'ai trouvé.

Lien vers le code et les cas de test

AlexRacer
la source
0

JavaScript (ES6), 95 octets

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

Fonctionne en générant toutes les fractions avec des numérateurs et dénominateurs de 1pour net en filtrant ceux supérieure 1ou vu précédemment, en prenant alors le nth.

Neil
la source
0

Perl, 82 + 2 ( -plindicateur) = 84 octets

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

Non 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");
}
Denis Ibaev
la source
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")

Moins 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
}

Tester

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

edc65
la source
0

Clojure, 85 octets

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

Utilise la compréhension de liste pour générer la liste de toutes les justifications, puis la filtre pour n'en obtenir que des distinctes. Prend un nthélément de la liste et retourne son numérateur. Une condition distincte est également nécessaire pour le premier élément car Clojure n'est pas en mesure de prendre le numérateur d'un entier. (pour une raison quelconque, considérant qu'un entier n'est pas rationnel - https://goo.gl/XETLo2 )

Voir en ligne - https://ideone.com/8gNZEB

cliffroot
la source