재귀 Collatz 추측


21

Collatz 추측에 당신이 어떤 양의 정수를 취할 경우, 다음 알고리즘 충분한 시간을 반복한다는 가설 :

if number is odd, then multiply by three and add one
if number is even, then divide by two

결국 1로 끝날 것입니다. 항상 작동하는 것 같지만 항상 작동하는 것으로 입증 된 적이 없습니다.

이미 1에 도달하는 데 걸리는 시간을 계산하여 골프를 쳤으므로 물건을 조금 바꾸려고 생각했습니다.

주어진 양의 정수로 시작하여 1에 도달하는 데 걸리는 시간 ( "정지 시간")을 계산하십시오. 그런 다음 숫자의 정지 시간을 찾으십시오 .

1에 도달 할 때까지 또는 완전히 임의의 100 회 반복 한계에 도달 할 때까지 반복하십시오. 전자의 경우 반복 횟수를 인쇄하십시오. 후자의 경우, 정수가 아닌 한 "실패"또는 선택한 다른 일관된 출력을 인쇄하십시오 1≤n≤100. 이 옵션에 대해 빈 문자열을 출력 할 수 없습니다. 그러나 [1, 100] 범위를 벗어나는 정수를 출력 할 수 있습니다.

예 :

Input: 2
2->1
Output: 1

Input: 5
5->5->5->5->5->...
Output: Fail

Input: 10
10->6->8->3->7->16->4->2->1
Output: 8

Input: 100
100->25->23->15->17->12->9->19->20->7->16->4->2->1
Output: 13

Input: 10^100
10^100->684->126->108->113->12->9->19->20->7->16->4->2->1
Output: 13

Input: 12345678901234567890
12345678901234567890->286->104->12->9->19->20->7->16->4->2->1
Output: 11

Input: 1
--Depending on your code, one of two things may happen. Both are valid for the purposes of this question.
1
Output: 0
--Or:
1->3->7->16->4->2->1
Output: 6

내가 계산 한대로 10^10012345678901234567890해당 크기의 실수 만 지원하는 언어를 하고 사용함에 따라 언어가 더 정확하면 다른 결과를 얻을 수 있습니다.

채점

이것이 이므로 가장 짧은 바이트 수의 응답이 이깁니다.


답변:




6

첨부 , 40 바이트

`-&3@`#@PeriodicSteps[CollatzSize@Max&1]

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

이것은 내가 만든 새로운 언어입니다. 나는 적절한 언어를 사용하고 싶었고, 그 결과는 수학입니다. 만세?

설명

이것은 몇 가지 기능으로 구성되어 있습니다. 이러한 기능은 다음과 같습니다.

  • PeriodicSteps[CollatzSize@Max&1]결과에 중복 요소가 포함될 때까지 인수를 적용하는 함수가 생성됩니다. 이 함수 ( CollatzSize@Max&1)는 CollatSize에 대한 잘못된 입력 을 피하기 위해 CollatzSize더 큰 1입력 0에 적용됩니다.
  • `#인용 된 연산자입니다. 이러한 의미에서 모나드 방식으로 적용하면 인수의 크기를 얻습니다.
  • `-&3는 인수 3를 함수에 결합하는 결합 함수이며 `-"-3"으로 읽습니다. 이는 PeriodicSteps 애플리케이션 0이을 산출 하기 때문에 계산해야하기 때문입니다. (또한 5로 매핑되는 범위를 벗어난 숫자를 깔끔하게 처리 합니다 -1.)

1
자신의 언어 사용이 실제로 허용됩니까? 당신은 단지 몇 바이트를 사용하여 각 코드 골프에 대한 언어를 만들 수 있습니까?
Tweakimp

2
@Tweakimp 물론 자신의 언어를 만들고 사용할 수 있습니다. 그러나 과제가 게시 된 후 작업이 단일 명령이되도록 수정하는 것은 표준 허점입니다.
caird coinheringaahing

2
@Tweakimp 더 기분이 좋으면이 도전을보기 전에이 기능을 설계했습니다. 저는 언어 디자이너이기 때문에 제가하는 일입니다.
코너 오브라이언

직접 만든 언어가 허용되는 일반적인 질문이었습니다.
Tweakimp

4

J , 49 45 바이트

@randomra의 의견 here 에서 가져온 Collatz Sequence 코드가 짧아서 -4 바이트 .

(2-~[:#(>&1*-:+2&|*+:+>:@-:)^:a:)^:(<101)i.1:

101유효하지 않은 결과를 출력 합니다.

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

설명

놀랍게도이 설명은 빨리 구식이되었습니다. 나는 내가 가지고 있었던 오래된 49 바이트 답변의 관점에서 그것을 남겨 둘 것입니다. 업데이트를 원하면 알려주세요. 재귀 시퀀스의 길이를 찾는 방법은 동일하게 유지됩니다. 더 짧은 Collatz 시퀀스 방법을 사용했습니다.

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)^:(<101)i.1:

Collatz 시퀀스의 길이 찾기

이 코드 섹션은 다음과 같습니다

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)

설명은 다음과 같습니다.

(1 -~ [: # %&2`(1+3&*)@.(2&|) ^: (1&<) ^: a:)  Given an input n
                                       ^: a:   Apply until convergence, collecting
                                                each result in an array.
                              ^: (1&<)         If n > 1 do the following, else
                                                return n.
                        (2&|)                  Take n mod 2.
           %&2                                 If n mod 2 == 0, divide by 2.
               (1+3&*)                         If n mod 2 == 1, multiply by 3 
                                                and add 1.
         #                                     Get the length of the resulting
                                                array.
 1 -~                                          Subtract 1.

불행하게도, 적용 동사 (^: 결과를 저장하라는 지시가있을 때 )는 초기 값도 저장하므로 항상 같은 값을 갖습니다. 따라서 왜 우리는 1을 뺍니다.

재귀 시퀀스의 길이 찾기

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:) ^: (< 101) i. 1:  Given an input n.
                                      ^: (< 101)        Apply 100 times,
                                                         collecting results
                                                         in an array.
(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)                   Collatz sequence length.
                                                 i. 1:  Index of first 1 (returns
                                                         101, the length of the
                                                         array if 1 not found).

1
머리글 섹션을 사용하여 괜찮다면, 이는 아마도 더 정확하게 답변 선보일 예정
코너 오브라이언

@ ConorO'Brien 전혀 모르겠습니다. 그러한 형식을 얻는 방법을 몰랐습니다 (그러나 지금부터 당신을 훔칠 것입니다). 감사합니다
cole

1
아니에요!
코너 O'Brien

1
38 바이트 *i.~(<101)1&(#@}.a:2&(<*|{%~,*+1+])])]동일해야
마일


3

자바 스크립트 (ES6), 57 바이트

true실패하면 반환 합니다. 에 대해 반환 0합니다 1.

f=(n,k=i=0)=>n>1?f(n&1?n*3+1:n/2,k+1):k?i>99||f(k,!++i):i

테스트 사례


프로그램이 오버플로 / 부정확성을 제외 하고 올바른 결과 를 계산 하거나 OP가 비슷한 숫자 구현 언어를 사용하여 결과를 도출 한 경우 회의적입니다 (모든 테스트 사례를 수동으로 계산하지는 않았다고 가정).
Jonathan Frech

@JonathanFrech 참으로. 두 결과 모두 똑같이 유효하지 않은 것으로 나타났습니다.
Arnauld

3

APL (Dyalog Unicode) , 39 60 53 52 49 바이트

@ngn 덕분에 -3 바이트

0∘{99<⍺:⋄1=⍵:01+(⍺+1)∇{1=⍵:01+∇⊃⍵⌽0 1+.5 3×⍵}⍵}

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

Collatz에 @ngn 코드를 사용하지만 이전에는 @Uriel의 코드를 사용했습니다.

사양을 충족하지 않은 이전 버전은 다음과 같습니다.

{1=⍵:01+∇{1=⍵:02|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}⍵}

2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2->1+∇⊃⍵⌽0 1+.5 3×⍵
ngn


2

껍질 , 21 바이트

←€1↑101¡ȯ←€1¡?½o→*3¦2

온라인으로 사용해보십시오! -1실패시 반품0입력 합니다 1.

설명

←€1↑101¡ȯ←€1¡?½o→*3¦2  Implicit input (a number).
             ?½o→*3¦2  Collatz function:
             ?     ¦2   if divisible by 2,
              ½         then halve,
               o→*3     else multiply by 3 and increment.
        ȯ←€1¡?½o→*3¦2  Count Collatz steps:
            ¡           iterate Collatz function and collect results in infinite list,
          €1            get 1-based index of 1,
        ȯ←              decrement.
       ¡               Iterate this function on input,
   ↑101                take first 101 values (initial value and 100 iterations),
←€1                    get index of 1 and decrement.

2

C (gcc) , 70 73 바이트

g(x){x=x-1?g(x%2?3*x+1:x/2)+1:0;}f(x,m){for(m=0;(x=g(x))&&100>m++;);x=m;}

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

101반복 횟수가 100을 초과하면 반환합니다 .


1
PPCG에 오신 것을 환영합니다! 이 답변은하지 있기 때문에, 유효한 모든 기능 제출 재사용 할 필요 . 에 삽입 하여이 문제를 해결할 수 있다고 생각 m=0합니다 f(아마도 현재 비어있는 forintiailiser를 사용하여 하나를 저장합니다 ;).
Martin Ender

2

클린 , 146 ... 86 바이트

Ørjan Johansen 덕분에 -11 바이트

import StdEnv
?f l n=hd[u\\1<-iterate f n&u<-l]

?(?(\b|isOdd b=3*b+1=b/2)[0..])[0..99]

부분 함수 리터럴로.

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

hd of []반복 횟수가 100을 초과하면 중단됩니다 . 더 큰 힙 크기를 지정하지 않으면 ~를 초과 하는 입력으로
종료 합니다.Heap Full2^23


1
나는 Haskell과 다른 Clean 구문을 귀하의 답변과 이해하기 시작했습니다 ... 도우미 함수를 사용하여 단축 할 수 있습니다 j f l n=hd[u\\1<-iterate f n&u<-l].
Ørjan Johansen

@ ØrjanJohansen 감사합니다!
OUurous

당신은 \a=...a부분이 필요하지 않습니다 . 카레. – 또는 에타 감소.
Ørjan Johansen

@ ØrjanJohansen 아, 그거 감사합니다!
OUurous




1

APL NARS, 115 바이트, 63 문자

{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}

아마도 루프를 사용하는 것이 더 명확 할 것입니다 ... 4 개의 함수, 2 개의 중첩 및 엄격함이 있으며 첫 번째 함수는 전역 변수 카운터로서 2 번째 함수에서 볼 수있는 변수 d를 = 0으로 정의하고 초기화하는 것입니다.

q←{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}

이 세 번째 함수는 arg에 대한 Collatz 추측을 해결하기 위해 호출 횟수를 반환하는 함수입니다.

{⍵=1:d⋄99<d+←1:¯1⋄∇q⍵}

이 함수는 arg = 1 인 경우 두 번째 함수이며 재귀를 중지하고 d-1을 호출 한 횟수를 반환합니다. 그렇지 않으면 자체가 99 회 이상 호출되면 재귀를 중지하고 -1 (fail)을 반환합니다. 그렇지 않으면 인수에 대한 Collatz 추측을 계산하고 Collatz 시퀀스 길이 값을 호출합니다. 프로그래머가 전역 변수를 로컬 변수로 볼 때 전역 변수와 동일한 이름의 함수에 하나의 변수가 정의되어 있으면이 모든 것이 실행되는 것처럼 보이지만 큰 문제가 될 수 있습니다.

  f←{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}     
  f 2
1
  f 3
5
  f 5
¯1
  f 10
8
  f 100
13
  f 12313
7
  f 1
0

1

(Emacs, Common, ...) 리스프, 105 바이트

반복> 100에 대해 t를 반환합니다.

(defun f(n k c)(or(> c 100)(if(= n 1)(if(= k 0)c(f k 0(1+ c)))(f(if(oddp
n)(+ n n n 1)(/ n 2))(1+ k)c))))

넓히는:

(defun f (n k c)
  (or (> c 100)
      (if (= n 1)
          (if (= k 0) c
            (f k 0 (1+ c)))
        (f (if (oddp n) (+ n n n 1) (/ n 2))
           (1+ k) c))))
(f (read) 0 0)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.