Collatz와 유사한 서열 분석


12

4 개의 양의 정수 로 Collatz 와 유사한 시퀀스 s를 정의합니다 .

  • n 시작 가치
  • d > 1 제수
  • m > 1 승수
  • i 증가

(원래의 Collatz 순서 d = 2 m = 3i = 1에서)

이러한 정수 s는 다음과 같은 방식으로 생성됩니다.

  • s(0) = n
  • 경우 k > 0s(k-1) mod d = 0다음s(k) = s(k-1) / d
  • 경우 k > 0s(k-1) mod d != 0다음s(k) = s(k-1) * m + i

함께 예시적인 시퀀스 d = 2, m = 3, i = 5n = 80것이다 s = 80, 40, 20, 10, 5, 20, 10, 5, 20, ....

모든 순서 중 하나라도 구속 주어진보다 (즉, 순서가 발산)보다 높은 값에 도달하거나 일부 경우 무한 루프에 얻을 것이다 tu( t!=u) s(t) = s(u)평등이 사실이 될 것입니다.

우리의 문제에서 시퀀스 요소의 값이 요소보다 크 10^9거나 요소 반복이 없으면 1000요소가 시퀀스로 분기되는 것으로 간주됩니다.

작업

사용자는 양의 정수를 취하는 프로그램이나 함수를 작성해야 d m하고 i입력 및 출력으로서 시작 값은 시퀀스 (무한 루프 발산)의 모든 다른 유형의 종료 n = 1, 2, 3, ... 999, 1000생산할 수있다.

입력 세부 사항

  • 입력 문자열 또는 목록 (또는 해당 언어에 가장 가까운 상당)를 나타내는 (일반적인 방법) 세 개의 양의 정수이고 d, m그리고 i그 순서. d그리고 m적어도 2. 어느 숫자도보다 큽니다 100.

출력 세부 사항

출력 사양은 약간 까다 롭습니다. 먼저 예제를 확인하십시오.

  • 표준 출력 (또는 가장 가까운 대안)으로 출력하거나 문자열을 반환해야합니다.
  • 분기 순서가 가능한 경우 첫 번째 줄은이어야합니다 DIVERGENT.
  • 시퀀스 루프의 고유 한 표현은 가장 작은 숫자가 공백으로 구분 된 마지막 회전입니다. 예를 s = 2 1 4 2 1 4 2 1들어 루프가 4 2 1입니다.
  • 모든 다음 줄에서 단어 앞에 정확히 한 번만 모든 고유 루프를 출력해야합니다 LOOP. 예 :LOOP 4 2 1
  • 루프는 마지막 요소와 관련하여 오름차순이어야합니다.
  • 후행 줄 바꿈은 선택 사항입니다.

예 :

첫 번째 라인은 입력이고 빈 라인이 출력 될 때까지 다음 라인입니다.

2 3 1
LOOP 4 2 1

2 2 6
LOOP 8 4 2 1
LOOP 12 6 3

3 7 8
DIVERGENT
LOOP 15 5 43 309 103 729 243 81 27 9 3 1
LOOP 22 162 54 18 6 2
LOOP 36 12 4

3 9 1
DIVERGENT

6 9 9
DIVERGENT
LOOP 18 3 36 6 1
LOOP 27 252 42 7 72 12 2
LOOP 45 414 69 630 105 954 159 1440 240 40 369 3330 555 5004 834 139 1260 210 35 324 54 9 90 15 144 24 4
LOOP 81 738 123 1116 186 31 288 48 8
LOOP 99 900 150 25 234 39 360 60 10
LOOP 126 21 198 33 306 51 468 78 13

10 10 10
LOOP 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100 10 1

93 91 92
DIVERGENT
LOOP 2185 198927 2139 23
LOOP 4278 46

Ideone의 Python 3에서 참조 구현.

이것은 코드 골프이므로 가장 짧은 엔트리가 승리합니다.

답변:


5

파이썬 3, 269 254 252 246 바이트

d,m,i=eval(input())
S=set()
for n in range(1,1001):
 T=X=()
 while len(T)**3<1e9>=n:
  T=(n,)+T;n=[n//d,n*m+i][n%d>0]
  if n in T:I=T.index;L=T[:I(n)+1];M=I(min(L));X=L[M:]+L[:M]
 S|={X}
for x in sorted(S):print(x and"LOOP"or"DIVERGENT",*x[::-1])

(이제 몇 바이트를 절약하기 위해 10 배 느리다. 전형적인 코드 골프.)

STDIN을 통해 목록을 입력하십시오 (예 :) [2, 3, 1]. 사이클을 표준화하는 더 좋은 방법이 있어야한다고 생각합니다 ...

이 접근 방식은 매우 간단합니다. 1000 개의 숫자를 모두 테스트하고 고유 한 출력 만 취하십시오. 그러나 거기에는 두 가지 작은 트릭이 있습니다.

  • 루프는 비어 있지 않은 튜플로 표현되지만 더 중요한 분기는 튜플로 표현됩니다 . 이것은 다음과 같은 이유로 좋습니다.

    • 그것은 깨지지 않으며 모든 루프 튜플 앞에sorted 나타납니다.
    • 이를 통해 문자열을 선택할 수 있습니다 x and"LOOP"or"DIVERGENT"
    • *()[::-1] 영향을 미치지 않습니다 print
  • 루프는 "마지막 요소에 의한 오름차순 정렬"을 "첫 번째 요소에 의한 오름차순 정렬"로 변환하기 위해 거꾸로 구축되어 람다를로 전달할 필요가 없습니다 sorted.

이전 제출, 252 바이트

d,m,i=eval(input())
def f(n,T=()):
 x=[n//d,n*m+i][n%d>0];I=T.index
 if x in T:L=T[:I(x)+1];M=I(min(L));return L[M:]+L[:M]
 return()if(T[1000:]or x>1e9)else f(x,(x,)+T)
for x in sorted(set(map(f,range(1,1001)))):print(x and"LOOP"or"DIVERGENT",*x[::-1])

이것은 훨씬 빠릅니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.