Función de conteo racional

11

Cree una función que tome un número natural (a partir de 0 inclusive) y devuelva un par de enteros positivos, que son el numerador y el denominador, respectivamente. Usa el recorrido diagonal. Los números contados previamente se deben omitir. (puede memorizar el conjunto de valores omitidos)

Diagrama:

ingrese la descripción de la imagen aquí

El rojo son valores omitidos

Valores:

  • f (0) = 1, 1
  • f (1) = 2, 1
  • f (2) = 1, 2
  • f (3) = 1, 3
  • f (4) = 3, 1 (observe el salto)
  • f (5) = 4, 1
  • f (6) = 3, 2
  • f (7) = 2, 3
  • f (8) = 1, 4
  • f (9) = 1, 5
  • f (10) = 5, 1 (observe el salto)

Puede utilizar la estructura de datos de Rational y sus operaciones si existen. El código más corto gana.

Ming-Tang
fuente
1
El número de números racionales contados en cada diagonal es la función totient de la suma común de esa diagonal.
Leaky Nun
Sé que este desafío es antiguo, pero existe una respuesta más corta que la aceptada, por lo que es posible que desee volver a aceptar.
Esolanging Fruit

Respuestas:

4

J, 41 36 caracteres

Toma enteros y devuelve un vector que comprende dos enteros. Mi primera solución que no es ni tácita ni explícita.

{3 :'~.;<`(<@|.)/.(,%+.)"0/~1+i.1+y'

Aquí está la solución con espacios insertados donde sea apropiado:

{ 3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'

Una explicación:

  1. x (, % +.) y–Un vector de longitud 2 que representa la fracción con numerador xy denominador yreducido al mínimo denominador
  2. 1 + i. 1 + y–Un vector de enteros de 1ay + 1
  3. (, % +.)"0/~ 1 + i. 1 + y–Una matriz de todas las fracciones reducidas con denominador y numerador no reducidos en el rango de 1a y + 1.
  4. <`(<@|.)/. y–Una matriz de diagonales oblicuas de matriz y, cada una diagonal invertida
  5. ~. ; y–Una matriz de diagonales colapsadas en un vector de elementos con duplicados eliminados
  6. x { y–El artículo en la posición xeny
  7. (u v) y–Lo mismo que y u v y. En este caso de uso particular, ues {y ves3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'
FUZxxl
fuente
1
30 bytes
FrownyFrog
8

Haskell, 78 personajes

q(r,f)=[(r-b,b)|b<-f[1..r-1],r`gcd`b==1]
d=reverse:id:d
f=((zip[2..]d>>=q)!!)

Ejecución de muestra:

> map f [0..10]
[(1,1),(2,1),(1,2),(1,3),(3,1),(4,1),(3,2),(2,3),(1,4),(1,5),(5,1)]
> f 100
(17,1)
> f 1000
(3,55)

  • Editar: (100 → 87) tonto, ¡solo probar el mcd es suficiente!
  • Editar: (87 → 85) truco inteligente con cycle y funciones para alternar el orden de las filas
  • Editar: (85 → 82) reemplazar cyclecon la lista infinita hecha a manod
  • Editar: (82 → 78) gcdidentidad aplicada como lo sugiere Matías
MtnViewMark
fuente
Por definición, gcd (r-b) b == gcd r by puedes eliminar cuatro personajes más.
Matías Giovannini
3

Python, 144 caracteres

def F(i):
 r,d,z=[1],1,[]
 while z[:i]==z:z+=[(x,y)for x,y in zip(r[::d],r[::-d])if all(x%j+y%j for j in r[1:])];d=-d;r+=[r[-1]+1]
 return z[i]
Keith Randall
fuente
2

Ruby 1.9, 109 106

F=->n{x=y=d=1
e=0
n.times{(x+=d).gcd(y+=e)>1&&redo
x<2?d<0?d=0:(d,e=1,-1):y<2?e<0?e=0:(d,e=-1,1):0}
[x,y]}
Lowjacker
fuente
2

OCaml + baterías, 182 168 caracteres

Esto es lo que sería natural en Haskell, pero apenas es posible en OCaml:

open LazyList
let rec r(i,j)=lazy(let a,b=if(i+j)mod 2=0then i,j else j,i in
Cons((a,b),filter(fun(c,d)->a*d<>c*b)(r(if j=1 then 1,i+1else i+1,j-1))))
let f=nth(r(1,1))

Editar: la diagonal es innecesaria

Matías Giovannini
fuente
0

Perl 6 , 75 bytes

{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique[$_]}

Pruébalo

Básicamente, esto genera toda la secuencia de valores racionales, solo se detiene una vez que se genera el valor indexado.

(Basado en mi golf para otro desafío).

Expandido:

{  # bare block lambda with implicit parameter $_

  (
      ( # sequence of numerators

        {
          |( # slip into outer sequence (flatten)

            1      # start at one
            
            (
              $    # state variable
              += 2 # increment it by two each time this block is called
            )
            
            1      # finish at one
          )

        }
         * # never stop generating values
      )


    Z/   # zip using &infix:« /  » (generates Rats)


      ( # sequence of denominators

        1,  # start with an extra one

        {
          |( # slip into outer sequence (flatten)

            1
            
            (
              ( $ ||= 1 ) # state variable that starts with 1 (rather than 0)
              += 2        # increment it by two each time this is called
            )
            
            1
          )
        }
         * # never stop generating values
      )


  ).unique                # get only the unique values
  .[ $_ ]                 # index into the sequence
}

({1…($+=2)…1}…*)genera la secuencia infinita de numeradores ( |(…)se usa arriba para aplanar)

(1 2 1)
(1 2 3 4 3 2 1)
(1 2 3 4 5 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1)

(1,{1…(($||=1)+=2)…1}…*) genera la secuencia infinita de denominadores

1
(1 2 3 2 1)
(1 2 3 4 5 4 3 2 1)
(1 2 3 4 5 6 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1)
(1 2 3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3 2 1)
Brad Gilbert b2gills
fuente