Функція раціонального підрахунку


11

Створіть функцію, яка приймає натуральне число (починаючи з 0 включно) і повертає пару натуральних чисел, що є чисельником і знаменником відповідно. Використовуйте діагональний обхід. Попередні відлічені номери потрібно пропустити. (Ви можете запам'ятати набір пропущених значень)

Діаграма:

введіть тут опис зображення

Червоні - пропущені значення

Значення:

  • f (0) = 1, 1
  • f (1) = 2, 1
  • f (2) = 1, 2
  • f (3) = 1, 3
  • f (4) = 3, 1 (зауважте пропуск)
  • f (5) = 4, 1
  • f (6) = 3, 2
  • f (7) = 2, 3
  • f (8) = 1, 4
  • f (9) = 1, 5
  • f (10) = 5, 1 (зауважте пропуск)

Ви можете використовувати структуру раціональних даних та їх операції, якщо вони існують. Найкоротший код виграє.


1
Кількість підрахованих раціональних чисел у кожній діагоналі є тотаційною функцією загальної суми діагоналі.
Leaky Nun

Я знаю, що цей виклик старий, але відповідь є коротшою, ніж прийнята, тому ви, можливо, захочете повторно прийняти.
Esolanging Fruit

Відповіді:


4

J, 41 36 символів

Бере цілі числа і повертає вектор, що складається з двох цілих чисел. Моє перше рішення, яке не є ні цілком мовчазним, ні повністю явним.

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

Ось рішення з пробілами, вставленими, де це доречно:

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

Пояснення:

  1. x (, % +.) y–Вектор довжиною 2, що представляє дріб з чисельником xі знаменником, yзменшеним до найменшого знаменника
  2. 1 + i. 1 + y– Вектор цілих чисел від 1доy + 1
  3. (, % +.)"0/~ 1 + i. 1 + y–Матриця всіх зменшених дробів з неприведеним знаменником та чисельником у діапазоні від 1до y + 1.
  4. <`(<@|.)/. y–Масив косих діагоналей матриці y, діагоналі яких перевернуті
  5. ~. ; y–Масив діагоналей згорнувся у вектор елементів із видаленими дублікатами
  6. x { y–Товар у позиції xвy
  7. (u v) y–Це те саме, що y u v y. У цьому конкретному випадку використання uє {і vє3 : '~. ; <`(<@|.)/. (, % +.)"0/~ 1 + i. 1 + y'


8

Haskell, 78 символів

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

Проба зразка:

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

  • Редагувати: (100 → 87) нерозумно, достатньо лише тестувати gcd!
  • Редагувати: (87 → 85) розумний трюк із cycleта функціями для чергування порядку рядків
  • Редагувати: (85 → 82) замінити cycleручним побудованим нескінченним спискомd
  • Редагувати: (82 → 78) застосовану gcdособу, як запропонував Матіас

За визначенням, gcd (r-b) b == gcd r bви можете поголити ще чотирьох символів.
Матіас Джованніні

3

Пітон, 144 символів

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

Рубін 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 + батареї, 182 168 символів

Це те, що було б природно в Haskell, але це лише ледве можливо в 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))

Редагувати: Діагональ не потрібна


0

Perl 6 , 75 байт

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

Перевірте це

Це в основному генерує всю послідовність раціональних значень, зупиняючись лише після того, як генерується індексоване значення.

(На основі мого гольфу до іншого виклику.)

Розширено:

{  # 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}…*)створює нескінченну послідовність чисельників ( |(…)використовується вище для вирівнювання)

(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}…*) породжує нескінченну послідовність знаменників

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.