Sharkovskii의 이상한 순서


33

소개

이 과제에서 우리는 양의 정수의 특정 순서를 다룰 것입니다. 순서는 다음과 같습니다.

   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

먼저 1보다 큰 모든 홀수를 오름차순으로 나열합니다. 모든 경우 : 다음 우리는 1보다 큰 정수 홀수 개의 시간 후, 4 배, 8 배 등 나열 K 우리 나열 2 유전율 승순 1 배 이상 홀수 정수를 더. 마지막으로, 우리는 2의 거듭 제곱을 내림차순으로 나열하고 1로 끝납니다. 모든 양의 정수는이 "목록"에서 정확히 한 번 발생합니다.

더 명확하게, 두 개의 양의 정수 A = n · 2 pB = m · 2 q를 고려하십시오 . 여기서 n, m ≥ 1 은 홀수이고 p, q ≥ 0 입니다. 그리고 A는 앞에 오는 B 다음 조건 중 하나가 보유하고있는 경우, 순서에 :

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

이 순서 는 동적 시스템의주기적인 점에 관한 Sharkovskii의 정리 로 알려진 놀라운 수학적 결과에 나타납니다 . 여기에 대해서는 자세히 설명하지 않겠습니다.

작업

이 과제의 임무는 위의 순서를 계산하는 것입니다. 입력 값은 양의 정수 AB 두 개 이며 같을 수 있습니다. 순서대로 AB 보다 앞에 오면 출력값이 참 값이고 , 그렇지 않으면 거짓 값입니다. A = B 인 경우 출력은 진실해야합니다. 일관된 한 AB 를 어느 순서 로나 취할 수 있습니다 .

정수 오버플로에 대해 걱정할 필요는 없지만 이론적으로 알고리즘은 임의로 큰 입력에 작동해야합니다.

테스트 사례

진실한 사례

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

거짓 인스턴스

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

답변:


5

파이썬 2, 87 71 바이트

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

이것은 아마도 어떤 규모의 상도 얻지 못할 것이지만,이 답변은 사전 식으로 정렬 될 때 올바른 순서를 초래하는 정수에서 3 개의 표현식을 사용하여 3 개의 튜플을 구성하여 작동합니다.

읽을 수있는 용어로 튜플은 A = n · 2 p입니다 .

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

5

자바 스크립트 (ES6), 53 49 바이트

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

설명:

  • b가 1이면 a는 b보다 앞에 오거나 같습니다
  • 그렇지 않으면 a가 1이면 a가 b보다 우선하지 않습니다.
  • 그렇지 않으면 a와 b가 모두 홀수이면 정기적 인 부등식 검사를 사용하십시오.
  • 그렇지 않으면 a가 홀수이면 b보다 앞에옵니다
  • 그렇지 않으면 b가 홀수이면 a가 b보다 우선하지 않습니다.
  • 그렇지 않으면 a와 b를 2로 나누고 다시 시도하십시오.

편집 : @Arnauld 덕분에 2 바이트가 절약되었습니다.


좋은. 나는 여기서 재귀를 사용하는 것에 대해 생각하지 않았다. 시겠습니까 a&1|~b&1&f(a/2,b/2)일?
아르나 울드

@Arnauld 확실하지 않습니다. 무한정 반복 될까봐 걱정되었습니다.

b<2결국 사실 이 될 수 없기 때문 입니다. 또 다른 문제는 필요한 것보다 많은 반복을 처리하고 부동 소수점 값을 얻는다는 것입니다. 그러나 예상대로 작동하지 않는 반례를 찾을 수 없습니다.
아르나 울드

@ Arnauld Ah, 맞아, b<2원래 는 사용하지 않았지만 지금은 효과가있을 것 같습니다.

@Arnauld 더 나은 아직, 이후 f(a/2,b/2)에만 반환 0, 1, false또는 true, 나는 심지어는 필요하지 않습니다 &1.
Neil

5

파이썬 2, 50 바이트

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

각 숫자는 정렬 순서가 원하는 순서 인 트리플에 매핑됩니다.

  • 기본 값은이며 [-n][n&n-1:], 마지막에 2의 거듭 제곱을 처리합니다. 의 거듭 제곱 일 n&n-1때 비트 단위 "and" 는 정확히 0 n입니다 2. 그렇다면 목록을 얻 [-n]거나 그렇지 않으면 빈 목록을 얻습니다 []. 이렇게하면 주문이 끝날 때 2의 모든 거듭 제곱이 내림차순으로 정렬됩니다.
  • 2 차 값은 2 n&-n의 거듭 제곱을 추출합니다 n.
  • 최종 값 n순위는 더 큰 수를 위해 2의 거듭 제곱입니다.

해당 튜플은 전달되어 cmp비교인지 확인 <=0합니다. 파이썬 3은 (n&n-1<1)/n트리플의 첫 번째 값에 대해 float 나누기 를 사용하여 바이트를 저장 하지만 부족 cmp합니다.


하지인가 cmp(...)<=0에 해당 cmp(...)<1?
mathmandan

@mathmandan 예 :)
xnor

나는 정수를 역순으로 가져 가서 ~대신 사용하는 것이 가능 하다고 생각한다<1
Mitch Schwartz

4

자바 스크립트 (ES6), 70 64 바이트

아마도 더 많은 골프를 쳤을 수도 있지만 첫 번째 시도는 다음과 같습니다.

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

카레 구문으로 입력을 (x)(y)받습니다. 0/를 반환 1합니다.

테스트 사례


당신은 주위와 내부에 괄호를 취할 수 있습니다 b>a||(b==a&&y>=x), 실행에 차이를 만들지 않습니다.
XavCo7

@ XavCo7 괄호 안을 제거해도 괜찮습니다. 기존의 모든 테스트 사례는 여전히 통과 [1, 5]할 수 있지만 입력 내용은 사실로 잘못 식별됩니다.
Arnauld

1
@Arnauld 나는 이것을 미래의 새로운 테스트 사례로 추가 할 것입니다.
Zgarb

3

펄 6 , 89 84 바이트

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

( 온라인으로 시도하십시오. )

정확히 짧지는 않지만 실제로 순서 순서를 생성하는 솔루션 (각 하위 시퀀스의 안전한 상한까지)을 작성하고 어떤 입력이 먼저 나타나는지 확인하는 것이 흥미로울 것이라고 생각했습니다.

예를 들면 다음과 같습니다.

  • 입력 2, 3을 위해 다음 을 생성합니다.

    3 5
    6
    12
    4 2 1
    ... 그리고 3이전 에 나타나는 것을 관찰하십시오 2.

  • 입력 9, 6을 위해 다음 을 생성합니다.

    3 5 7 9 11
    6 10
    12
    24
    48
    16 8 4 2 1
    ... 그리고 9이전 에 나타나는 것을 관찰하십시오 6.

더 똑똑하고 시퀀스를 훨씬 적게 생성 할 수 있지만 더 많은 바이트가 필요합니다.


2

파이썬 2, 54 바이트

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

Neil과 유사한 재귀 솔루션.


이것은 일부 테스트 사례를 망쳐 놓은 것 같습니다. 그것은 f(158,158)거짓이며 f(2,8)진실 이라고 말합니다 .
xnor

@xnor 죄송합니다. 지금 수정해야합니다.
orlp

이것은 f(1,5)거짓 이라고 말합니다 .
xnor

내 나쁜, 나는 그것이 f(1,5)거짓이어야 한다는 것을 의미 했지만 코드는 True를 제공합니다.
xnor

@ xnor 아아, 나는 버그를 발견했다. 이제 수정되었다. 나는 Neil의 설명을 너무 느슨하게 따라갔습니다.
orlp

1

Mathematica, 65 바이트

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

이름이없는 함수는 양의 정수 목록을 가져 와서 목록이 TrueSharkovskii 순서로 오름차순을 형성하는 경우 리턴 합니다 False. (특히 입력 목록에는 두 가지 요소 만있을 필요는 없습니다. 추가 기능은 무료로 제공됩니다.)

알고리즘의 핵심은 함수입니다.이 함수 {1,#}&/@#//.{a_,b_/;EvenQ@b}->{2a,b/2}는 2의 인수를 반복적으로 이동 m*2^k하여 m홀수 형식의 정수를 정렬 된 쌍 으로 변환합니다 {2^k,m}(입력 목록의 모든 요소에 적용). OrderedQ정렬 된 쌍의 결과 목록이 이미 정렬되어 있는지 여부를 결정합니다. 기본적으로 이는 첫 번째 요소에 따라 순서가 증가한 다음 두 번째 요소에 의해 순서가 증가 함을 의미합니다.

2의 거듭 제곱은 다른 규칙을 따르는 것을 제외하고는 정확히 우리가 원하는 것입니다. 그래서과에 확인하기 전에 OrderingQ, 우리는 마지막 규칙 적용 /.{a_,1}->{∞,-a}, 변환 (예를 들어) {64,1}로를 {∞,-64}; 주문의 올바른 자리에 2의 거듭 제곱을 넣습니다.


0

하스켈, 143138 바이트

기본적으로 비교적 간단한 기준 구현 :

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  

온라인으로 사용해보십시오!


0

파이썬 159 158 153 144 142 141 바이트

저장된 2 Kritixi LITHOS 덕분 바이트!

이것은 주로 내 파이썬을 골프 연습하는 것입니다!
모든 영리한 답변의 방법보다는 OP가 제공 한 공식을 사용했습니다.

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

불필요한 공백을 제거하여 골프를 타실 수 있습니다 (예 : (a, b)쉼표와 사이의 공백을 제거 할 수있는 두 번째 줄에서) b.
Kritixi Lithos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.