Racjonalna funkcja liczenia

11

Utwórz funkcję, która przyjmuje liczbę naturalną (zaczynając od 0 włącznie) i zwraca parę dodatnich liczb całkowitych, które są odpowiednio licznikiem i mianownikiem. Użyj ukośnego przejścia. Liczby wcześniej policzone muszą zostać pominięte. (możesz zapamiętać zestaw pominiętych wartości)

Diagram:

wprowadź opis zdjęcia tutaj

Czerwone są pomijanymi wartościami

Wartości:

  • f (0) = 1, 1
  • f (1) = 2, 1
  • f (2) = 1, 2
  • f (3) = 1, 3
  • f (4) = 3, 1 (zauważ pominięcie)
  • f (5) = 4, 1
  • f (6) = 3, 2
  • f (7) = 2, 3
  • f (8) = 1, 4
  • f (9) = 1, 5
  • f (10) = 5, 1 (zauważ pominięcie)

Możesz użyć struktury danych Rational i ich operacji, jeśli istnieją. Najkrótszy kod wygrywa.

Ming-Tang
źródło
1
Liczba zliczonych liczb wymiernych na każdej przekątnej jest funkcją sumaryczną wspólnej sumy tej przekątnej.
Leaky Nun
Wiem, że to wyzwanie jest stare, ale odpowiedź jest krótsza niż zaakceptowana, więc możesz chcieć ponownie zaakceptować.
Esolanging Fruit

Odpowiedzi:

4

J, 41 36 znaków

Pobiera liczby całkowite i zwraca wektor zawierający dwie liczby całkowite. Moje pierwsze rozwiązanie, które nie jest całkowicie milczące ani całkowicie jednoznaczne.

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

Oto rozwiązanie z wstawionymi spacjami w stosownych przypadkach:

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

Wyjaśnienie:

  1. x (, % +.) y– Wektor długości 2 reprezentujący ułamek z licznikiem xi mianownikiem yzredukowany do najmniejszego mianownika
  2. 1 + i. 1 + y– Wektor liczb całkowitych od 1doy + 1
  3. (, % +.)"0/~ 1 + i. 1 + y–Macierz wszystkich zredukowanych frakcji o nieredukowanym mianowniku i liczniku w zakresie od 1do y + 1.
  4. <`(<@|.)/. y–Macierz ukośnych przekątnych matrycy y, wzajemnie odwróconych względem siebie
  5. ~. ; y–Macierz przekątnych zwinął się w wektor elementów z usuniętymi duplikatami
  6. x { y–Pozycja na pozycji xwy
  7. (u v) y–Takie jak y u v y. W tym konkretnym przypadku użycia ujest {i vjest3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'
FUZxxl
źródło
1
30 bajtów
FrownyFrog
8

Haskell, 78 znaków

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

Przykładowy przebieg:

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

  • Edycja: (100 → 87) głupie mnie, wystarczy przetestować gcd!
  • Edycja: (87 → 85) sprytna sztuczka z cyclei funkcje do naprzemiennej kolejności wierszy
  • Edycja: (85 → 82) zastąp cycleręcznie stworzoną nieskończoną listąd
  • Edycja: (82 → 78) zastosował gcdtożsamość zgodnie z sugestią Matíasa
MtnViewMark
źródło
Z definicji gcd (r-b) b == gcd r bmożesz ogolić cztery kolejne postacie.
Matías Giovannini
3

Python, 144 znaki

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
źródło
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
źródło
2

OCaml + Baterie, 182 168 znaków

Oto, co byłoby naturalne w Haskell, ale jest prawie niemożliwe w 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))

Edycja: przekątna jest niepotrzebna

Matías Giovannini
źródło
0

Perl 6 , 75 bajtów

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

Sprawdź to

Generalnie generuje to całą sekwencję wartości wymiernych, zatrzymując się dopiero po wygenerowaniu wartości indeksowanej.

(Na podstawie mojego golfa do innego wyzwania.)

Rozszerzony:

{  # 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}…*)generuje nieskończoną sekwencję liczników ( |(…)służy do spłaszczania powyżej)

(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}…*) generuje nieskończoną sekwencję mianowników

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
źródło