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.


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'


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

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]

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

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


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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.