Đánh số các tỷ lệ hợp lý


14

Các số hữu tỷ dương có thể được hiển thị là số với quy trình sau:

  1. Số không có số 0
  2. Sắp xếp các số khác trong một lưới sao cho hàng a, cột b chứa a / b
  3. Vẽ một đường chéo zig-zag từ phải sang dưới bên trái
  4. Tiếp tục kiểm tra các số duy nhất gặp phải dọc theo đường zig-zag

Đây là hình ảnh của zig-zag:

Bắt đầu từ 1/1, di chuyển ban đầu ngay

Vì vậy, các số gặp phải là, theo thứ tự

1/1, 2/1, 1/2, 1/3, 2/2, 3/1, 4/1, 3/2, 2/3, 1/4, 1/5, 2/4, 3/3, 4/2, 5/1, 6/1, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 2/6, 3/5, 4/4, 5/3 ...

Và các số đơn giản, duy nhất gặp phải là

1, 2, 1/2, 1/3, 3, 4, 3/2, 2/3, 1/4, 1/5, 5, 6, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 3/5, 5/3, ...

Thử thách:

  • Với hai lớn hơn-hơn-zero số nguyên pq , sản lượng các số thứ tự của p / q
  • p và q không nhất thiết phải là đồng nguyên tố
  • Mã ngắn nhất sẽ thắng
  • Sơ hở tiêu chuẩn bị cấm

Các trường hợp thử nghiệm:

Dưới đây là 24 số hữu tỷ đầu tiên gặp phải và đầu ra mong muốn cho mỗi số:

1/1: 1
2/1: 2
1/2: 3
1/3: 4
2/2: 1
3/1: 5
4/1: 6
3/2: 7
2/3: 8
1/4: 9
1/5: 10
2/4: 3
3/3: 1
4/2: 2
5/1: 11
6/1: 12
5/2: 13
4/3: 14
3/4: 15
2/5: 16
1/6: 17
1/7: 18
2/6: 4
3/5: 19

Và, đối với các trường hợp thử nghiệm tiếp theo, đây là 200 số hữu tỷ dương đầu tiên theo thứ tự:

1, 2, 1/2, 1/3, 3, 4, 3/2, 2/3, 1/4, 1/5, 
5, 6, 5/2, 4/3, 3/4, 2/5, 1/6, 1/7, 3/5, 5/3, 
7, 8, 7/2, 5/4, 4/5, 2/7, 1/8, 1/9, 3/7, 7/3, 
9, 10, 9/2, 8/3, 7/4, 6/5, 5/6, 4/7, 3/8, 2/9, 
1/10, 1/11, 5/7, 7/5, 11, 12, 11/2, 10/3, 9/4, 8/5, 
7/6, 6/7, 5/8, 4/9, 3/10, 2/11, 1/12, 1/13, 3/11, 5/9, 
9/5, 11/3, 13, 14, 13/2, 11/4, 8/7, 7/8, 4/11, 2/13, 
1/14, 1/15, 3/13, 5/11, 7/9, 9/7, 11/5, 13/3, 15, 16, 
15/2, 14/3, 13/4, 12/5, 11/6, 10/7, 9/8, 8/9, 7/10, 6/11, 
5/12, 4/13, 3/14, 2/15, 1/16, 1/17, 5/13, 7/11, 11/7, 13/5, 
17, 18, 17/2, 16/3, 15/4, 14/5, 13/6, 12/7, 11/8, 10/9, 
9/10, 8/11, 7/12, 6/13, 5/14, 4/15, 3/16, 2/17, 1/18, 1/19, 
3/17, 7/13, 9/11, 11/9, 13/7, 17/3, 19, 20, 19/2, 17/4, 
16/5, 13/8, 11/10, 10/11, 8/13, 5/16, 4/17, 2/19, 1/20, 1/21, 
3/19, 5/17, 7/15, 9/13, 13/9, 15/7, 17/5, 19/3, 21, 22, 
21/2, 20/3, 19/4, 18/5, 17/6, 16/7, 15/8, 14/9, 13/10, 12/11, 
11/12, 10/13, 9/14, 8/15, 7/16, 6/17, 5/18, 4/19, 3/20, 2/21, 
1/22, 1/23, 5/19, 7/17, 11/13, 13/11, 17/7, 19/5, 23, 24, 
23/2, 22/3, 21/4, 19/6, 18/7, 17/8, 16/9, 14/11, 13/12, 12/13, 
11/14, 9/16, 8/17, 7/18, 6/19, 4/21, 3/22, 2/23, 1/24, 1/25 

Hét lên câu hỏi ngược , nơi di chuyển đầu tiên xuống để bạn không thể sử dụng các câu trả lời để tạo ra các trường hợp kiểm tra bổ sung.


Tôi tự hỏi nếu có các sơ đồ đánh số thay thế làm cho mã ngắn hơn.
qwr

1
Số tử phân số: oeis.org/A157807 mẫu số: oeis.org/A157813 Không có kết quả khớp nào cho chuỗi thứ tự: oeis.org/iêu
qwr

tôi hiểu rồi. bạn phải giảm phân số rồi đếm. nó không phải là zig-zag duy nhất
don sáng

Câu trả lời:


4

Thạch ,  21  20 byte

Có thể bị đánh bại bởi một số byte bằng cách sử dụng một số toán học thông minh ...

:g/
ǵSRRUĖ€UÐeẎÇ€Qi

Một liên kết đơn âm chấp nhận một danh sách trong [p,q]đó trả về số tự nhiên được gán cho p/q.

Hãy thử trực tuyến! Hoặc xem bộ thử nghiệm .

Làm sao?

Đầu tiên lưu ý rằng đường chéo thứ N gặp phải chứa tất cả các số hữu tỷ của lưới mà tổng của tử số và mẫu số bằng N + 1 , do đó, có một hàm làm giảm một [p,q]cặp thành dạng đơn giản nhất ( [p/gcd(p,q),q/gcd(p,q)]) chúng ta có thể xây dựng các đường chéo cho đến khi cần *, giảm tất cả các mục, bỏ trùng lặp và tìm chỉ mục của đầu vào đơn giản hóa.

* thực sự thêm một ở đây để tiết kiệm một byte

:g/ - Link 1, simplify a pair: list of integers, [a, b]
  / - reduce using:
 g  - Greatest Common Divisor -> gcd(a, b)
:   - integer division (vectorises) -> [a/gcd(a,b), b/gcd(a,b)]

ǵSRRUĖ€UÐeẎÇ€Qi - Main Link: list of integers, [p, q]
Ç                - call last Link as a monad (simplify)
 µ               - start a new monadic chain (call that V)
  S              - sum -> the diagonal V will be in plus one
   R             - range -> [1,2,3,...,diag(V)+1]
    R            - range (vectorises) -> [[1],[1,2],[1,2,3],...,[1,2,3,...,diag(V)+1]]
     U           - reverse each       -> [[1],[2,1],[3,2,1],[diag(V)+1,...,3,2,1]]
      Ė€         - enumerate €ach     -> [[[1,1]],[[1,2],[2,1]],[[1,3],[2,2],[3,1]],[[1,diag(V)+1],...,[diag(V)-1,3],[diag(V),2],[diag(V)+1,1]]]
         Ðe      - apply only to the even indexed items:
        U        -   reverse each     -> [[[1,1]],[[2,1],[1,2]],[[1,3],[2,2],[3,1]],[[4,1],[3,2],[2,3],[1,4]],...]
           Ẏ     - tighten            -> [[1,1],[2,1],[1,2],[1,3],[2,2],[3,1],[4,1],[3,2],[2,3],[1,4],...]
            Ç€   - for €ach: call last Link as a monad (simplify each)
                 -                    -> [[1,1],[2,1],[1,2],[1,3],[1,1],[3,1],[4,1],[3,2],[2,3],[1,4],...]
              Q  - de-duplicate       -> [[1,1],[2,1],[1,2],[1,3],[3,1],[4,1],[3,2],[2,3],[1,4],...]
               i - index of V in that list

3

Perl 6 ,  94  90 byte

->\p,\q{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique.first(p/q,:k)+1}

Kiểm tra nó

{(({|(1…($+=2)…1)}…*)Z/(1,{|(1…(($||=1)+=2)…1)}…*)).unique.first($^p/$^q):k+1}

Kiểm tra nó

Điều này về cơ bản tạo ra toàn bộ chuỗi giá trị và dừng lại khi tìm thấy kết quả khớp.

Mở rộng:

{  # bare block lambda with placeholder parameters $p,$q

  (
      ( # 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
  .first( $^p / $^q ) # find the first one that matches the input
  :k                  # get the index instead (0 based)
  + 1                 # add one               (1 based)
}

({1…($+=2)…1}…*)tạo ra dãy số vô hạn ( |(…)được sử dụng ở trên để làm phẳng)

(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}…*) tạo ra chuỗi mẫu số vô hạn

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)

3

Python 2 , 157 144 137 134 126 125 byte

def f(p,q):a=[((j-i)/(i+1.))**(j%-2|1)for j in range(p-~q)for i in range(j)];return-~sorted(set(a),key=a.index).index(p*1./q)

Hãy thử trực tuyến!

4 byte được lưu do ông Xcoder ; 1 byte từ Jonathon Frech .

Theo ghi nhận của ông Xcoder, chúng tôi có thể làm tốt hơn một chút trong Python 3 vì trong số những thứ khác, mặc định phân chia số nguyên cho kết quả nổi và chúng tôi có thể dễ dàng giải nén hơn list:

Python 3 , 117 byte

def f(p,q):a=[((j-i)/-~i)**(j%-2|1)for j in range(p-~q)for i in range(j)];return-~sorted({*a},key=a.index).index(p/q)

Hãy thử trực tuyến!


128 byte (-6) bằng cách hoán đổi phân số và sử dụng **(j%-2|1)p-~q.
Ông Xcoder

@Ông. Xcoder: Hôm nay bạn là tất cả về modulo tiêu cực! :) Tôi nghĩ rằng tôi vẫn cần +1đến cuối cùng, vì 1,1'phải' cho 1, không 0.
Chas Brown


124 byte :) Vâng, modulo âm hóa ra thực sự hữu ích!
Ông Xcoder


3

Python 3 ,157, 146, 140, 133 byte

def f(p,q):a=[(i+i-abs(j-i-i))/(abs(j-i-i+.5)+.5)for i in range(p+q)for j in range(4*i)];return sorted(set(a),key=a.index).index(p/q)

Hãy thử trực tuyến!

giành được 11 byte nhờ Jonathan Frech

giành được thêm 6 byte và sau đó 7 nhờ Chas Brown




@bobrobbob: Chào mừng bạn đến với PPCG! Tôi không chắc chắn làm thế nào thuật toán của bạn hoạt động (mặc dù nó rõ ràng làm); nhưng về mặt thực nghiệm, có vẻ như bạn có thể tiết kiệm thêm một số byte bằng cách thay thế range(max(p,q)+1)bằng range(p+q).
Chas Brown

1
Bạn có thể lưu thêm một số byte bằng cách sử dụng {*a}thay vì set(a).
Ông Xcoder

2

J, 41 , 35 , 30 byte

-11 byte nhờ FrownyFrog

%i.~0~.@,@,[:]`|./.[:%/~1+i.@*

Hãy thử trực tuyến!

bài gốc 41 byte với lời giải thích

%>:@i.~[:([:~.@;[:<@|.`</.%"1 0)~(1+i.@*)

vô dụng

% >:@i.~ [: ([: ~.@; [: <@|.`</. %"1 0)~ 1 + i.@*

giải trình

                  +
                  | Everything to the right of this
                  | calculates the list
p (left arg)      |                                      create the
divided by q      |                                      diagonals.  yes,
      (right)     |                                     +this is a         +create this list
   |              |        ++ finally rmv ^alternately  |primitive ADVERB  |1..(p*q), and pass
   |   + the index          | the boxes,  |box, or      |in J              |it as both the left
   |   | of that  |         | and remove  |reverse and  |                  |and right arg to the
   |   | in the   |         | any dups    |box, each    |                  |middle verb, where each
   |   | list on  |         |             |diagonal     |                  |element will divide the
   |   | the right|         |             |             |       +----------+entire list, producing
   |   | plus 1   |         |             |             |       |          |the undiagonalized grid
   |   |          |         |             |             |       |          |
   |   |          |         |             |             |       |          |
   |   |          +         |             |             |       |          |
  ┌+┬──|──────────┬─────────|─────────────|─────────────|───────|──────────|─────────────┐
  │%│┌─+───────┬─┐│┌──┬─────|─────────────|─────────────|───────|────────┬─|────────────┐│
  │ ││┌──┬─┬──┐│~│││[:│┌────|─────────────|─────────────|───────|─────┬─┐│┌+┬─┬────────┐││
  │ │││>:│@│i.││ │││  ││┌──┬|───────┬─────|─────────────|───────|────┐│~│││1│+│┌──┬─┬─┐│││
  │ ││└──┴─┴──┘│ │││  │││[:│+──┬─┬─┐│┌──┬─|─────────────|─┬─────|───┐││ │││ │ ││i.│@│*││││
  │ │└─────────┴─┘││  │││  ││~.│@│;│││[:│┌|───────────┬─+┐│┌─┬─┬+──┐│││ │││ │ │└──┴─┴─┘│││
  │ │             ││  │││  │└──┴─┴─┘││  ││+────────┬─┐│/.│││%│"│1 0││││ ││└─┴─┴────────┘││
  │ │             ││  │││  │        ││  │││┌─┬─┬──┐│<││  ││└─┴─┴───┘│││ ││              ││
  │ │             ││  │││  │        ││  ││││<│@│|.││ ││  ││         │││ ││              ││
  │ │             ││  │││  │        ││  │││└─┴─┴──┘│ ││  ││         │││ ││              ││
  │ │             ││  │││  │        ││  ││└────────┴─┘│  ││         │││ ││              ││
  │ │             ││  │││  │        ││  │└────────────┴──┘│         │││ ││              ││
  │ │             ││  │││  │        │└──┴─────────────────┴─────────┘││ ││              ││
  │ │             ││  ││└──┴────────┴────────────────────────────────┘│ ││              ││
  │ │             ││  │└──────────────────────────────────────────────┴─┘│              ││
  │ │             │└──┴──────────────────────────────────────────────────┴──────────────┘│
  └─┴─────────────┴──────────────────────────────────────────────────────────────────────┘

Hãy thử trực tuyến!


35:1+~.@;@([:<@|.`</.%~/~)@(1+i.@*)i.%
FrownyFrog

cảm ơn bạn rất tốt tôi sẽ cập nhật đầy đủ sau vì nó sẽ yêu cầu làm lại lời giải thích ...
Jonah

Và 30:%i.~0~.@,@,[:]`|./.[:%/~1+i.@*
FrownyFrog

thật thông minh, sử dụng 0 và ~. để tránh quyền anh và sự gia tăng, tôi yêu nó
Jonah

2

Python 3, 121 byte

import math
def o(x,y):
 p=q=n=1
 while x*q!=p*y:a=p+q&1;p+=1+a*~-~-(p<2);q+=1-~-a*~-~-(q<2);n+=math.gcd(p,q)<2
 return n

2

Rust, 244 byte

Tôi đã tạo ra một công thức đơn giản để tìm ra số thứ tự "đơn giản" của zigzag "đơn giản", không có ràng buộc của câu đố, sử dụng các công thức số tam giác: https://www.mathsisfun.com/acheebra/triangular-numbers.html . Điều này đã được sửa đổi với modulo 2 để giải thích cho các đường zic zắc lật hướng của chúng từng hàng chéo trong câu đố. Đây là hàm h ()

Sau đó, cho mẹo chính của câu đố này: làm thế nào để 'không tính' các giá trị lặp lại nhất định, như 3/3 so với 1/1, 4/2 so với 2/1, trong đường mòn zig-zag. Tôi đã chạy các ví dụ 1-200, và nhận thấy sự khác biệt giữa một bộ đếm tam giác zig-zag đơn giản, và một cái mà câu đố mong muốn, có một mẫu. Mẫu số "thiếu" là 5, 12, 13, 14, 23, v.v., dẫn đến một cú đánh trong OEIS. Nó được mô tả bởi Robert A Stump, tại https://oeis.org/A076537 , để "lặp lại" các số như 3/3, 4/2 và 1/1, bạn có thể kiểm tra xem GCD> 1 cho x, y của tất cả các mệnh lệnh "trước" trong zigzag. Đây là vòng lặp 'for' và g () là gcd.

Tôi đoán với một số gcd dựng sẵn, nó sẽ ngắn hơn, nhưng tôi không thể tìm thấy một thứ rất dễ dàng (tôi là người mới ở Rust và Integer làm tôi bối rối), và tôi thích thực tế rằng cái này sử dụng số học số nguyên thẳng lên, và không có nội dung hay thư viện nào.

fn f(x:i64,y:i64)->i64 {
        fn h(x:i64,y:i64)->i64 {let s=x+y;(s*s-3*s+4)/2-1+(s+1)%2*x+s%2*y}
        fn g(x:i64,y:i64)->i64 {if x==0 {y} else {g(y%x,x)}}
        let mut a=h(x,y);
        for i in 1..x+y {for j in 1..y+x {if h(i,j)<h(x,y) && g(i,j)>1 {a-=1;}}}
        a
}

1

JavaScript (ES6), 86 byte

Đưa đầu vào theo cú pháp currying (p)(q).

p=>q=>(g=x=>x*y?x*q-y*p?g(x+d,g[x/=y]=g[x]||++n,y-=d):n:g(x+!~d,y+=!~(d=-d)))(d=n=y=1)

Hãy thử trực tuyến!


0

Javascript, 79 byte

a=(p,q)=>p*q==1?1:1+((p+q)%2?q==1?a(p-1,q):a(p+1,q-1):p==1?a(p,q-1):a(p-1,q+1))

(Tôi chưa quen với việc chơi golf, vì vậy điều này có thể được cải thiện dễ dàng)

Giải trình

let a = (p, q) => p * q == 1 // If they are both 1
    ? 1
    // Do a recursive call and increment the result by 1
    : 1 + (
        (p + q) % 2 // If on an even-numbered diagonal
        ? q == 1 // If at the beginning of the diagonal
            ? a(p - 1, q) // Go to previous diagonal
            : a(p + 1, q - 1) // Go one back
        : p == 1 // rougly the same
            ? a(p, q - 1)
            : a(p - 1, q + 1)
    )

4
(3,5)nên kết quả trong 19(không 24) vì (1,1)==(2,2)==(3,3), (2,4)==(1,2), (4,2)==(2,1)(2,6)==(1,3). (tức là (2,2)nên kết quả trong 1không 5, vv ...)
Jonathan Allan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.