Thứ tự kỳ lạ của Sharkovskii


33

Giới thiệu

Trong thử thách này, chúng tôi sẽ xử lý một trật tự nhất định của các số nguyên dương. Việc đặt hàng diễn ra như sau:

   3,    5,    7,    9,    11, ...
 2*3,  2*5,  2*7,  2*9,  2*11, ...
 4*3,  4*5,  4*7,  4*9,  4*11, ...
 8*3,  8*5,  8*7,  8*9,  8*11, ...
16*3, 16*5, 16*7, 16*9, 16*11, ...
 ...
... 64, 32, 16, 8, 4, 2, 1

Trước tiên chúng tôi liệt kê tất cả các số nguyên lẻ lớn hơn 1 theo thứ tự tăng dần. Sau đó, chúng tôi liệt kê hai lần số nguyên lẻ lớn hơn 1, sau đó 4 lần, sau đó 8 lần, v.v.: với tất cả k , chúng tôi liệt kê 2 k lần số nguyên lẻ lớn hơn 1 theo thứ tự tăng dần. Cuối cùng, chúng tôi liệt kê các quyền hạn của hai theo thứ tự giảm dần , kết thúc ở 1. Mỗi số nguyên dương xảy ra trong "danh sách" này chính xác một lần.

Rõ ràng hơn, hãy xem xét hai số nguyên dương khác biệt A = n · 2 pB = m · 2 q , trong đó n, m ≥ 1 là số lẻ và p, q ≥ 0 . Sau đó A đến trước B theo thứ tự, nếu một trong các điều kiện sau giữ:

  • n> 1 , m> 1p <q
  • 1 <n <mp = q
  • n> m = 1
  • n = m = 1p> q

Thứ tự này xuất hiện trong kết quả toán học đáng ngạc nhiên được gọi là định lý Sharkovskii , liên quan đến các điểm định kỳ của các hệ động lực. Tôi sẽ không đi vào chi tiết ở đây.

Nhiệm vụ

Nhiệm vụ của bạn trong thử thách này là tính toán thứ tự trên. Đầu vào của bạn là hai số nguyên dương AB , có thể bằng nhau. Đầu ra của bạn là một giá trị trung thực nếu A đến trước B theo thứ tự và nếu không thì giá trị giả. Nếu A = B , đầu ra của bạn phải trung thực. Bạn có thể lấy AB theo thứ tự, miễn là bạn nhất quán.

Bạn không phải lo lắng về tràn số nguyên, nhưng về mặt lý thuyết, thuật toán của bạn sẽ hoạt động cho các đầu vào lớn tùy ý.

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

Trường hợp thật

3 11
9 6
48 112
49 112
158 158
36 24
14 28
144 32
32 32
32 8
3 1
1 1

Trường hợp giả

1 2
1 5
11 5
20 25
2 8
256 255
256 257
72 52
2176 1216
2176 2496

Câu trả lời:


5

Python 2, 87 71 byte

k=lambda n:[n&~-n<1,(n&-n)*cmp(n&~-n,1),n/(n&-n)]
lambda a,b:k(a)<=k(b)

Điều này có thể sẽ không giành được bất kỳ giải thưởng kích thước nào, nhưng câu trả lời này hoạt động bằng cách xây dựng 3 tuple bằng cách sử dụng 3 biểu thức từ một số nguyên mà khi được sắp xếp theo từ vựng sẽ dẫn đến thứ tự đúng.

Theo thuật ngữ có thể đọc được, bộ dữ liệu dành cho A = n · 2 p :

[n == 0, p * (1 - 2*(n == 0)), n]

5

JavaScript (ES6), 53 49 byte

f=(a,b)=>b<2||a>1&&(a&b&1?a<=b:a&1|~b&f(a/2,b/2))

Giải trình:

  • Nếu b là 1, thì a đứng trước (hoặc bằng) b
  • Mặt khác, nếu a là 1, thì a không đứng trước b
  • Mặt khác, nếu cả a và b là số lẻ, thì hãy sử dụng kiểm tra bất đẳng thức thường xuyên
  • Mặt khác, nếu a là số lẻ, thì nó đứng trước b
  • Mặt khác, nếu b là số lẻ thì a không đứng trước b
  • Nếu không, chia cả a và b cho 2 và thử lại.

Chỉnh sửa: Đã lưu 2 byte nhờ @Arnauld.


Tốt đẹp. Tôi đã không nghĩ về việc sử dụng đệ quy ở đây. Sẽ a&1|~b&1&f(a/2,b/2)làm việc?
Arnauld

@Arnauld Tôi không chắc chắn, tôi đã lo lắng rằng nó sẽ lặp đi lặp lại vô thời hạn.
Neil

Nó không thể bởi vì b<2cuối cùng sẽ là sự thật. Bây giờ, một vấn đề khác là bạn sẽ xử lý nhiều lần lặp hơn mức cần thiết và nhận các giá trị dấu phẩy động. Nhưng tôi không thể tìm thấy bất kỳ mẫu nào không hoạt động như mong đợi.
Arnauld

@Arnauld Ah, đúng rồi, tôi không sử dụng b<2ban đầu, nhưng tôi đoán nó sẽ hoạt động ngay bây giờ.
Neil

@Arnauld Vẫn còn tốt hơn, vì f(a/2,b/2)chỉ lợi nhuận 0, 1, falsehay true, tôi thậm chí không cần &1.
Neil

5

Python 2, 50 byte

lambda*l:cmp(*[([-n][n&n-1:],n&-n,n)for n in l])<1

Mỗi số được ánh xạ tới một bộ ba có thứ tự được sắp xếp là thứ tự mong muốn.

  • Giá trị chính là [-n][n&n-1:], xử lý quyền hạn của 2 ở cuối. Bitwise "và" n&n-1bằng 0 chính xác khi nào nlà lũy thừa của 2. Nếu vậy, chúng tôi nhận được danh sách [-n], và nếu không thì danh sách trống []. Điều này đặt tất cả các quyền hạn của 2 vào cuối đơn hàng, theo thứ tự giảm dần.
  • Giá trị thứ cấp n&-ntrích xuất hệ số lũy thừa của 2 n.
  • Giá trị cuối cùng nhòa vốn với quyền hạn bằng 2 có lợi cho số lượng lớn hơn.

Các bộ dữ liệu tương ứng được thông qua cmpđể xem nếu so sánh đó là <=0. Python 3 sẽ lưu một byte với phép chia float (n&n-1<1)/ncho giá trị đầu tiên trong bộ ba, nhưng thiếu cmp.


Không cmp(...)<=0tương đương với cmp(...)<1?
mathmandan

@mathmandan Có :)
xnor

Tôi nghĩ việc cho phép lấy các số nguyên theo thứ tự ngược lại và sử dụng ~thay vì<1
Mitch Schwartz

4

JavaScript (ES6), 70 64 byte

Có thể có thể được đánh gôn thêm, nhưng như một nỗ lực đầu tiên:

x=>y=>(a=x&-x,x/=a,b=y&-y,y/=b,y<2?x>1|b<=a:x>1&(b>a|b==a&y>=x))

Đưa đầu vào với cú pháp currying (x)(y). Trả về 0/ 1.

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


Bạn có thể lấy ra các dấu ngoặc xung quanh và bên trong b>a||(b==a&&y>=x), sẽ không tạo ra sự khác biệt để thực hiện.
XavCo7

@ XavCo7 Bạn có thể xóa dấu ngoặc bên trong nhưng không phải xung quanh. Tất cả các trường hợp thử nghiệm hiện tại vẫn sẽ vượt qua, nhưng một đầu vào như [1, 5]sẽ được xác định không chính xác là trung thực.
Arnauld

1
@Arnauld Tôi sẽ thêm nó như một trường hợp thử nghiệm mới cho tương lai.
Zgarb

3

Perl 6 , 89 84 byte

->\a,\b{my \u=*>max a,b;a==first a|b,flat [1,2,4...u].&{(3*$_,5*$_...u for $_),.reverse}}

{my \u=*>@_.max;@_[0]==first @_.any,flat [1,2,4...u].&{.map(*X*(3,5...u)),.reverse}}

( Dùng thử trực tuyến. )

Không chính xác ngắn, nhưng tôi nghĩ sẽ rất thú vị khi viết một giải pháp thực sự tạo ra chuỗi thứ tự (lên đến giới hạn trên an toàn cho mỗi chuỗi con), và sau đó kiểm tra xem đầu vào nào xuất hiện trong đó trước.

Ví dụ:

  • Đối với đầu vào, 2, 3nó tạo ra:

    3 5
    6
    12
    4 2 1
    ... và sau đó quan sát thấy 3xuất hiện trước đó 2.

  • Đối với đầu vào, 9, 6nó tạo ra:

    3 5 7 9 11
    6 10
    12
    24
    48
    16 8 4 2 1
    ... và sau đó quan sát thấy 9xuất hiện trước đó 6.

Nó có thể thông minh hơn và tạo ra ít hơn chuỗi, nhưng điều đó sẽ tốn nhiều byte mã hơn.


2

Python 2, 54 byte

f=lambda a,b:b<2or[f(a/2,b/2),a>1,0,1<a<=b][a%2+b%2*2]

Một giải pháp đệ quy tương tự như của Neil.


Điều này dường như làm rối tung một số trường hợp thử nghiệm. Nó nói f(158,158)là Sai và f(2,8)là Đúng.
xnor

@xnor Rất tiếc, nên sửa ngay.
orlp

Điều này nói f(1,5)là sai.
xnor

Xấu của tôi, tôi có nghĩa là f(1,5)nên sai, nhưng mã cho đúng.
xnor

@xnor Ah, tôi phát hiện ra lỗi, đã sửa ngay bây giờ (vì tôi hy vọng tốt). Tôi đã đi theo mô tả của Neil một chút quá lỏng lẻo.
orlp

1

Toán học, 65 byte

OrderedQ[{1,#}&/@#//.{a_,b_/;EvenQ@b}->{2a,b/2}/.{a_,1}->{∞,-a}]&

Hàm không tên lấy danh sách các số nguyên dương và trả về Truenếu danh sách tạo thành một chuỗi tăng dần theo thứ tự Sharkovskii, Falsenếu không. (Đặc biệt, danh sách đầu vào không nhất thiết phải có hai yếu tố mà chúng tôi có được chức năng bổ sung miễn phí.)

Trung tâm của thuật toán là hàm {1,#}&/@#//.{a_,b_/;EvenQ@b}->{2a,b/2}, liên tục di chuyển các yếu tố của 2 xung quanh để chuyển đổi một số nguyên có dạng m*2^k, mlẻ, thành cặp theo thứ tự {2^k,m}(và làm như vậy cho mọi phần tử của danh sách đầu vào). OrderedQsau đó quyết định xem danh sách kết quả của các cặp theo thứ tự đã được sắp xếp chưa; theo mặc định, điều đó có nghĩa là tăng thứ tự theo phần tử thứ nhất, sau đó tăng thứ tự theo phần tử thứ hai.

Đó chính xác là những gì chúng ta muốn, ngoại trừ các số có quyền hạn theo 2 quy tắc khác nhau. Vì vậy, trước khi OrderingQđăng ký, chúng tôi áp dụng một quy tắc cuối cùng /.{a_,1}->{∞,-a}, chuyển đổi (ví dụ) {64,1}thành {∞,-64}; đặt quyền hạn của 2 vào đúng vị trí trong thứ tự.


0

Haskell, 143 138 byte

Về cơ bản việc thực hiện các tiêu chí tương đối đơn giản:

e n=head[k-1|k<-[0..],n`mod`(2^k)>0]   -- exponent of 2
f n=n`div`2^e n                        -- odd part
a#b|n<-f a,p<-e a,m<-f b,q<-e b=n>1&&(m>1&&p<q||n<m&&p==q||m<2)||n<2&&m<2&&p>q||a==b  

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


0

Python, 159 158 153 144 142 141 byte

Lưu một 2 byte nhờ Kritixi Lithos!

Điều này chủ yếu chỉ để thực hành chơi gôn Python của tôi!
Đã sử dụng công thức do OP đưa ra thay vì cách của tất cả các câu trả lời thông minh hơn

f=lambda a,p=0:(a&1)*(a,p)or f(a>>1,p+1)
t=lambda(n,p),(m,q):(n==1)*(m==1)&(p>=q)or (m>1)&(p<=q)|(n<=m)&(p==q)or m==1
lambda a,b:t(f(a),f(b))

Bạn có thể đánh gôn bằng cách xóa các khoảng trắng không cần thiết: ví dụ (a, b)trên dòng thứ hai nơi bạn có thể xóa khoảng trắng giữa dấu phẩy và b.
Kritixi Lithos

0

APL (Dyalog mở rộng) , 27 byte

1⊃∘⍋⍮⍥{p⍵⍮⍨-⍵⍴⍨⍵=2*p←⊥⍨~⊤⍵}

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

Một hàm dyadic ngầm có đối số bên trái là avà bên phải là b.

Cách tiếp cận gần giống với giải pháp Python 2 của xnor , trong đó chúng tôi chuyển đổi từng số thành một mảng lồng nhau và thực hiện so sánh từ điển giữa chúng.

Phần 1: Chuyển đổi số thành mảng lồng nhau

{p⍵⍮⍨-⍵⍴⍨⍵=2*p←⊥⍨~⊤⍵}   Input: positive integer N
                  ⊤⍵    Convert N to binary digits
                 ~      Flip all the bits (1 to 0, 0 to 1)
             p←⊥⍨       Count trailing ones and assign it to p
                        (maximum power of 2 that divides N)
         ⍵=2*           Test if N itself is equal to 2^p
     -⍵⍴⍨               If true, create 1-element array containing -N;
                        otherwise, an empty array
 p⍵⍮⍨                   Form a 2-element nested array;
                        1st element is the above, 2nd is [p, N]

Phần 2: So sánh hai mảng lồng nhau

1⊃∘⍋⍮⍥f   Input: A (left) and B (right)
     f   Evaluate f A and f B
         Create a 2-element nested array [f A, f B]
         Grade up; indexes of array elements to make it sorted
          Here, the result is [0 1] if A  B, [1 0] otherwise
1⊃∘       Take the element at index 1 (0-based)

Cú pháp dfn không hỗ trợ các câu điều kiện, ví dụ như {a:x ⋄ b:y ⋄ z}ý nghĩa if a then x else if b then y else z, nhưng nó quá dài dòng để sử dụng trong trường hợp này.

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.