최고의 개구리 🐸


44

"프라임 개구리"는 3이나 19에 도달 할 때까지 정수 사이를 점프하는 이상한 동물입니다.


프로그램은 정수 n를 입력으로 받아 아래 알고리즘 ( 3또는 19) 의 결과를 출력해야합니다 .

주어진 정수의 경우 n >= 2:

  1. f개구리의 위치를 봅시다 . 처음에는n
  2. 경우 f = 3또는 f = 19다음 개구리 점프는 정지 - 프로그램 및 출력을 정지 f.
  3. f프라임 인 경우 : 개구리가 위치로 이동합니다 2×f-1. 2 단계로 돌아가십시오.
  4. 경우 f복합입니다 : 할 df의 가장 큰 주요 제수. 개구리는 그 위치로 점프합니다 f-d. 2 단계로 돌아가십시오.

예 :

예를 들면 다음과 n = 5같습니다.

5 > 9 > 6 > 3 stop

프로그램이 출력되어야합니다 3.

다른 예 n = 23:

23 > 45 > 40 > 35 > 28 > 21 > 14 > 7 > 13 > 25 > 20 > 15 > 10 > 5 > 9 > 6 > 3 stop

다시, 프로그램은을 출력해야합니다 3.

테스트 사례 :

10 => 3
74 => 19
94 => 3
417 => 3
991 => 19
9983 => 19

당신은 가정 할 수 있습니다 1 < n < 1000000(프로그램이 끝났는지 확인했습니다).


3
3 루프는 [3 5 9 6 3]이고 19 루프는 [19 37 73145116 87 58 29 57 38 19]
Arnaud

8
멋진 Collatz 변형.
Arthur

3
개구리가 항상 3또는에 온다는 것을 증명할 수 없다면 19알고리즘에서 항목 2를 변경하여 개구리가 루프에 들어간 경우 (이전에 본 위치를 만나면) 점프를 중단하고 가장 작은 것을 반환합니다. 그 루프의 멤버.
Jeppe Stig Nielsen

4
@PyRulez 도달하면 OP에 알려야합니다.
mbomb007

3
@KeyuGan 아마도 이것이 Math.SE에 게시하는 것이 좋습니다.
mbomb007

답변:



12

C (gcc),  87  65 바이트

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);n=~16&n-3?f(n-k?:n+n-1):n;}

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

설명:

i,k;
f(n)
{
    for (i=n; i>1;)              // Loop until `k` is prime (the largest positive
                                 // `i` inequal to `k` that divides `k` is 1).
        for (k=i; k%--i;);       // Find the largest factor `k`

    n =                          // Returning like this is undefined behaviour,
                                 // but happens to work with gcc. This can be
                                 // replaced with `return` at the cost of 4 bytes.

        ~16&n-3                  // If `n` is 3 or 19, this expression equals 0 and
                                 // the algorithm halts. Otherwise the function
                                 // calls itself to perform the next iteration.

        ? f(n-k ?: n+n-1)        // If `n-k` is non-zero, n is not prime.
                                 // In this case call `f` with the value of `n-k`.
                                 // (Omitting the second `n-k` between `?` and `:`
                                 // is a gcc extension)
                                 // Otherwise call `f` with `2*n-1`.

        : n;                     // All done, `n` is returned.
}

휴대용 버전 (72 바이트) :

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);return~16&n-3?f(n-k?n-k:n+n-1):n;}

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

더 적절한 변수 이름으로 :

f,r;o(g){for(f=g;f>1;)for(r=f;r%--f;);g=~16&g-3?o(g-r?:g+g-1):g;}

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


5
개구리라는 단어와 변수로 놀이를 완전히 좋아하십시오. +1.
rayryeng-복원 모니카

10

망막 , 63 62 바이트

1 바이트를 절약 해 준 Neil에게 감사드립니다.

{`^(11+)(?<!^\2+(11+))(?=\1+$)

^(?!(11+)\1+$|111$|1{19}$)1
$_

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

단항으로 입력 및 출력합니다 (테스트 스위트는 편의를 위해 10 진수를 사용합니다). 이 솔루션은 더 큰 입력에 대해 엄청나게 느려집니다. 9983TIO에 밖으로 테스트 케이스 시간.

설명

로 인해 {프로그램의 두 단계는 더 이상 문자열에 영향을 미치지 않을 때까지 루프에서 실행됩니다. 우리는 스테이지 프로세싱 컴포지트와 스테이지 프로세싱 프라임을 번갈아 가며 보여줍니다. 따라서 실제 조건부 (Retina에는 실제로 존재하지 않음)를 피할 수 있습니다. 현재 값이 스테이지에 대해 잘못된 종류이면 스테이지는 아무 것도 수행하지 않습니다.

^(11+)(?<!^\2+(11+))(?=\1+$)

복합재를 처리합니다. 우리는 잠재적 제수와와 일치하지만와 (11+)혼합되지 않았는지 확인 (?<!^\2+(11+))하므로 주요 요인 만 고려합니다. 의 탐욕으로 인해 +가장 큰 요소가 우선시됩니다. 그런 다음 나머지 문자열을 반복하여 일치시켜이 잠재적 제수가 실제 제수인지 확인합니다 (?=\1+$). 이 제수는 단순히 문자열에서 제거되므로 단항에서 무언가를 빼는 방법입니다.

^(?!(11+)\1+$|111$|1{19}$)1
$_

이것은 319를 제외한 소수를 처리 합니다. 음의 룩어 입력이 아닌 복합 아닌지 확인한다 3 이 아닌 19 . 그런 다음 하나를 일치 1시키고 전체 문자열로 바꿉니다. 이것은 n-1 + n 을 계산하는 단항 형태이며 , 물론 2n-1 입니다.

3 또는 19를 맞추면 어느 스테이지도 문자열과 일치 할 수 없으며 더 이상 변경되지 않습니다.


1
하지가 1$'같은 $_?
Neil

4
@ 닐 예 ......
마틴 엔더

8

껍질 , 15 바이트

Ω€p57§|o←DṠ-o→p

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

설명

Ω€p57§|o←DṠ-o→p  Implicit input n.
Ω                Do this to n until
 €p57            you get a prime factor of 57 (which are 3 and 19):
            o→p   Take last element of the prime factors of n
          Ṡ-      and subtract it from n,
     §|           or if this gives 0 (so n is prime),
       o←D        double and decrement n.

8

젤리 , 12 바이트

_ÆfṂoḤ’$µÐḶṂ

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

작동 원리

_ÆfṂoḤ’$µÐḶṂ  Maink link. Argument: n

        µ     Combine the links to the left into a chain.
         ÐḶ   Repeatedly call the chain monadically until the results are no longer
              unique. Yield the loop, i.e., the first occurrence of the first
              repeated integer, up to and excluding the repetition.
              Let's call the argument of the chain k.
_Æf             Subtract all prime factors of k from k.
   Ṃ            Take the minimum of the differences. This yields 0 iff k is prime.
     Ḥ’$        Compute 2k-1.
    o           Take the logical OR of the results.
              The result is now a rotation of either [3, 5, 9, 6] or
              [19, 37, 73, 145, 116, 87, 58, 29, 57, 38].
          Ṃ   Take the minimum, yielding either 3 or 19.

7

볼프람 언어 (수학) , 6566 68 바이트

#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
  • Misha Lavrov 덕분에 -1 바이트!
  • Martin 덕분에 -2 바이트!

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

팁에서 영감을 얻었습니다 . 기본적으로 알고리즘을 다시 만듭니다.

//.이다 RepeatedReplace하고 /;있다 Condition. 따라서 코드는 평가 될 때까지 i_(단일 수량)을 If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]i!=3&&!=19바꿉니다 True.

기준:

기준


3
재미있는 사실 :이 코드는 같은 큰 숫자 작동하지 않을 것입니다 10000000010때문에maximum number of iterations is 2^16 (= 65536)
J42161217

1
약간 짧은 방법 3을 확인하고 19입니다#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
미샤 라브 로프

@MishaLavrov 그러나 결과가 잘못 되었습니까?
Keyu Gan

@KeyuGan 저에게, 두 함수는 정수 1에서 1000까지 정확히 같은 결과를냅니다.
Misha Lavrov

1
아마도 문제는 주석에서 복사하여 붙여 넣을 때 인쇄 할 수없는 문자가 삽입되어 발생하는 문제 일 수 있습니다.
Misha Lavrov

6

05AB1E , 19 18 17 바이트

[ÐƵηfså#pi·<ëDfθ-

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

설명

[      #            # loop until
 Ð   så             # a copy of the current value is contained in
  Ƶηf               # the unique prime factors of 171
        pi          # if the current value is prime
          ·<        # double and decrement
            ë   -   # else subtract
             Dfθ    # the largest prime factor of a copy of the current value

4
소스 코드에 실제 개구리가 있으면 +1
Arnaud

1 분 이상 57991
RosLuP

@RosLuP : 매우 긴 테스트 사례를 오프라인에서 실행하는 것이 좋습니다.)
Emigna

5

자바 스크립트 (ES6), 73 71 69 바이트

f=n=>57%n?f(n-(g=(k,d=1)=>++d<k?k%d?g(k,d):g(k/d):d<n?d:1-n)(n)):n%38

테스트 사례

형식화 및 의견

f = n =>                 // given n
  57 % n ?               // if n is neither 3, 19 or 57 (and assuming that n is > 1):
    f(                   //   do a recursive call to f() with:
      n -                //     n minus
      (g = (k, d = 1) => //     the result of the recursive function g():
        ++d < k ?        //       increment d; if d is less than k:
          k % d ?        //         if d is not a divisor of k:
            g(k, d)      //           recursive call to g() with k and d unchanged
          :              //         else:
            g(k / d)     //           recursive call to g() with k = k / d, d = 1
        :                //       else, d is now the highest prime divisor of n:
          d < n ?        //         if d is less than n:
            d            //           n is composite: return d, which results in f(n - d)
          :              //         else:
            1 - n        //           n is prime: return 1 - n, which results in f(2n - 1)
      )(n)               //     initial call to g()
    )                    //   end of recursive call to f()
  :                      // else:
    n % 38               //   return n % 38 (gives 19 as expected if n = 57)

1
스마트, 사용 57%n하고 n%38대신 n==3|n==19. Java 응답 에 1 바이트를 저장 했으므로 감사합니다!
Kevin Cruijssen '10

ideone 57991 입력에서 prog.js : 2 : 26 InternalError : 너무 많은 재귀 생성
RosLuP

티오 f = n => 57 % n? f (n- (g = (k, d = 1) => ++ d <k? k % d? g (k, d) : g (k / d) : d <n? d : 1-n) (n)) : n % 38 print (f (57991)) 출력 중지 프로그램을 생성하지 않습니다, 그것은 나에게 보인다
RosLuP

1
@RosLuP 이것은 특정한 제약이없는 코드 골프 도전입니다. 현재 합의 는 질문에서 달리 명시되지 않는 한 속도 또는 메모리 제한 (예 : 호출 스택 크기)을 무시할 수 있다는 것입니다. 시퀀스가 그 이상으로 테스트되지 않았기 때문에 1000000 한계는 유익한 정보라고 생각합니다. 덧붙여서, 70 바이트 솔루션은 완벽하게 훌륭하며 아마도 코드 골프 도전에 93 바이트 버전보다 더 관련이있을 것입니다.
Arnauld


4

파이썬 2 , 110 105 103 101 바이트

@Lynn 덕분에 -2 바이트

f=lambda n,i=2,k=0:i/n and(n*(n&~16==3)or f((2*i-1,k-i)[k>0]))or n%i and f(n,i+1,k)or f(n/i,2,k or n)

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


파이썬 (2) , 116 (112) 105 바이트

f=lambda n,i=2:i/n*i or n%i and f(n,i+1)or f(n/i)
n=input()
while~16&n-3:n=[2*n-1,n-f(n)][f(n)<n]
print n

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


1
…n*(n&~16==3)or…2 바이트를 절약합니다.
Lynn

입력 57991 sys.setrecursionlimit (20000)
RosLuP

4

MATL , 22 21 바이트

1 바이트를 제거 한 @Giuseppe 에게 감사드립니다 !

`tZp?Eq}tYfX>-]tI19h-

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

설명

`           % Do...while
  t         %   Duplicate. Takes (implicit) input the first time
  Zp        %   Is it prime? 
  ?         %   If so
    Eq      %     Times 2, minus 1
  }         %   Else
    t       %     Duplicate
    YfX>-   %     Prime divisors, maximum, subtract
  ]         %   End
  t         %   Duplicate
  I19h      %   Push array [3 19]
  -         %   Subtract, element-wise. The result is truthy if and only if
            %   it doesn't contain any zero
            % End (implicit). Next iteraton if top of the stack is truthy
            % Display (implicit)

4

하스켈-154 바이트

f 3=3
f 19=19
f n
 |(c==[1])=f$2*n-1
 |True=f$n-head c
 where c=z n;v b=reverse[x|x<-[1..(b-1)],b`rem`x==0];z j=case v j of[1]->[1];s->filter((==[1]).v)$s

아마도 골프 트릭을 놓친 것 같습니다. 이것이 하스켈 골프에서의 첫 시도입니다.


안녕하세요. 사이트에 오신 것을 환영합니다. 패턴 가드에 줄 바꿈과 공백이 필요하지 않습니다. 당신은 또한 사용할 수 있습니다 1>0에 대한 True대부분의 시간 그러나 종종 예를 들어, 할당을 사용하는 것이 좋습니다 수 있습니다 c<-z n.
밀 마법사

1
[x|x<-[b-1,b-2..1],rem b x==0]reverse[x|x<-[1..(b-1)],brem 보다 짧습니다 x==0].
밀 마법사

2
마지막으로, 하스켈 골프에 대해 이야기하고 싶다면 Of Monads and Men 에서 우리와 함께 할 수 있습니다 .
밀 마법사

3

Neim , 17 16 바이트

ͻY𝐏𝕚÷D𝐌Ξᚫ<#D𝐏𝐠𝕊

설명:

ͻ                   Start infinite loop
 D                  Duplicate
  Y                 Push 57
   𝐏                Prime factors: [3 19]
     𝕚              If the second-to-top of stack is in the list
      ÷             Break the loop
       D            Duplicate
        𝐌Ξᚫ<       If prime, double and decrement
            #D𝐏𝐠𝕊   Otherwise, subtract the largest prime factor

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



3

자바 8 140 135 134 94 바이트

n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;t/=m=f);return n%38;}

재귀 Java 7 메소드를 루프가있는 Java 8 람다로 변환하는 -5 바이트
-1 바이트 암시 덕분에 @Arnauld 의 자바 스크립트 응답 변경하여 n!=3&n!=19return n;57%n>0return n%38;.
어떻게 든 두 루프를 결합하고 n소수 인지 확인 하고 동시에 가장 큰 주요 요소를 얻는 것이 가능해야하지만 생각할 수는 없습니다 (아직). 이것은 현재 초기 버전이 될 것입니다.
@Nevay 덕분에 내가 할 수 없었던 일을함으로써 -40 무려 바이트가되었습니다 : 루프를 결합하여 소수와 최대 소수를 한 번에 확인하십시오.

설명:

여기에서 시도하십시오 ( 9999991 초 미만으로 도 실행 됨 ).

n->{                  // Method with integer as both parameter and return-type
  for(int f,          //  Flag-integer
          t,          //  Temp-integer
          m=1;        //  Max prime factor integer, starting at 0
      57%n>0;         //  Loop (1) as long as `n` is not 3, not 19 and not 57:
      n=f>n?          //    After every iteration: if `f` is larger than `n`:
         2*n-1        //     Change `n` to `2*n-1`
        :             //    Else:
         n-m)         //     Change `n` to `n-m`
    for(t=n,          //   Reset `t` to `n`
        f=1;          //   Reset `f` to 1
        f++<t;)       //   Inner loop (2) from 2 to `t` (inclusive)
      for(;t%f<1;     //    Inner loop (3) as long as `t` is divisible by `f`
        t/=m=f;       //     Set `m` to `f`, and set `t` to `t/f`
      );              //    End of inner loop (3)
                      //   End of inner loop (2) (implicit / single-line body)
                      //  End of loop (1) (implicit / single-line body)
  return n%38;        //  Return `n%38`, which is now either 3 or 19
}                     // End of method

1
C # 폴리 글 로트가 아닌 1 문자 :(
Ian H.

@IanH. Hehe, 그렇습니다. n=>대신에 그렇습니다 n->. 때로는 소문자 / 대문자 호출이 있습니다. ;)
Kevin Cruijssen

1
94 바이트 :n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;)t/=m=f;return n%38;}
Nevay

@Nevay 감사합니다! 루프를 결합하는 것이 가능해야한다는 것을 알았지 만 알아낼 수 없었습니다. 덕분에 무려 40 바이트가 절약되었습니다!
Kevin Cruijssen

3

배쉬, 73 바이트

((57%$1))&&$0 $[(x=$1-`factor $1|sed 's/.* //'`)?x:2*$1-1]||echo $[$1%38]

온라인으로 사용해보십시오! TIO에서 작동하도록 약간 수정되었습니다.

반복적으로 사용하여 자신의 스크립트 파일을 호출 $0, 그것으로 실행해야하기 때문에 TIO에 일을하지 않습니다./filename.sh . 명령 행 인수로 입력을 승인합니다.

@Arnauld의 JS answer 와 동일한 계수 트릭을 사용합니다 .

테스트 사례

$ for t in 5 23 10 74 94 417 991 9983;{ echo -n "$t -> "; ./prime-frog.sh $t; }
5 -> 3
23 -> 3
10 -> 3
74 -> 19
94 -> 3
417 -> 3
991 -> 19
9983 -> 19


1

피스 , 19 바이트

.W!/P57H?P_ZtyZ-ZeP

모든 테스트 사례를 확인하십시오!

껍질 답변 (2 바이트 저장 나에게 영감 ,3 19을을 P57).

작동 원리

.W! / P57H? P_ZtyZ-ZeP-전체 프로그램.

.W-기능적. A (값)는 사실이지만 값 = B (값)입니다. 마지막 값을 반환합니다.
    P57-57의 주요 요인 ([3, 19]).
   / H-현재 값의 발생 횟수를 계산합니다.
  ! -논리 NOT 0-> Truthy, 다른 것-> Falsy.
        ? P_Z-현재 값이 소수 인 경우 :
            tyZ-현재 값을 두 배로 줄입니다.
               -ZeP-그렇지 않으면 현재 값의 최대 소수를 뺍니다.
                     -암시 적으로 인쇄합니다.

1

PowerShell을 , 150 126 바이트

for($n="$args";57%$n){$a=$n;$d=for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}};if($n-in$d){$n+=$n-1}else{$n-=$d[-1]}}$n%38

온라인으로 사용해보십시오! (경고 : 숫자가 클수록 느림)

반복적 인 방법. PowerShell에는 기본 인수 분해 기능이 내장되어 있지 않으므로 Prime Factors Buddies 에 대한 답변에서 코드를 빌려줍니다 .

먼저 우리의 for루프입니다. 설정 $n은 입력 값으로 설정 되며 조건부는 루프 57%$n가 0이 아닌 한 계속 진행 합니다 ( Arnauld 덕분 에 해당 트릭). 루프 내부에서 먼저 $a(로 설정된 $n) 의 주요 요인 목록을 얻습니다 . Prime Factors Buddies에서 빌린 코드입니다. 입력 $a이 이미 소수라면, 이것은 단지 $a중요하다 (나중에 중요하다). 그것은 (잠재적으로 $a)에 저장됩니다 $d.

다음은 if/ else조건부입니다. 를 들어 if부분, 우리는 여부를 확인 $n이다 -in $d. 이 경우, 그 수단이 $n우리가 취할 수 있도록, 소수 $n=2*$n-1또는 $n+=$n-1. 그렇지 않으면 복합적이므로 가장 큰 주요 요소를 찾아야합니다. 즉, 우리는 마지막 취할 필요 [-1]의를 $d과에서 해당 빼기 $n$n-=. 이것은 우리가 루핑하고 있기 때문에 2마지막 요소 $d가 이미 가장 클 것이므로 작동합니다.

루핑이 끝나면 $n%38파이프 라인에 (다시 말해 Arnauld 덕분에) 배치 하고 출력은 암시 적입니다.


1

APL (Dyalog Unicode) , 113 90 59 바이트

CY 'dfns'
g←{1pco ⍵:f(2×⍵)-1f⍵-⊃⌽3pco ⍵}
f←{⍵∊3 19:⍵⋄g ⍵}

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

TIO는 ~ 3200까지의 값으로 작동합니다. 마지막 테스트 사례에 대해 내 PC에서 테스트했습니다. TIO를 테스트하려면 f value코드 하단에 추가하십시오 . @ Adám 덕분에 우선 순위 확인 알고리즘이 실제로 나쁘고 대체 기능을 제공했다는 사실을 지적 해 주셔서 더 이상 적용되지 않습니다. 23 바이트 저장에도 적용됩니다.

바이트 수를 수정하도록 편집되었습니다.

작동 원리

CY 'dfns'                      # Imports every Defined Function, which is shorter than importing just the function I used (pco).

g←{1pco ⍵:f(2×⍵)-1f⍵-⊃⌽3pco ⍵} 
g                              # define g as
   1pco ⍵:                      # if the argument ⍵ is prime
          f(2×⍵)-1              # Call f over 2×⍵-1
                  f            # else, call f over
                               # the first element of the
                      3pco     # list of prime factors of ⍵
                               # reversed

f←{⍵∊3 19:⍵⋄g ⍵}
f                              # Define f as
        :                      # if the argument ⍵
                               # is in
     3 19                       # the list [3, 19]
                               # return the argument ⍵
                               # else
            g                  # call g over the argument ⍵

1

공리, 93 바이트

h(n)==(repeat(n=3 or n=19 or n<2=>break;prime? n=>(n:=2*n-1);n:=n-last(factors(n)).factor);n)

테스트:

(4) -> [[i,h(i)] for i in [10,74,94,417,991,9983]]
   (4)  [[10,3],[74,19],[94,3],[417,3],[991,19],[9983,19]]
                                                  Type: List List Integer

68 바이트 기능이있을 것입니다

q x==(n<4=>3;n=19=>n;prime? n=>q(2*n-1);q(n-last(factors n).factor))

그러나 n = 57991 (잘 기억하면) 예약 된 스택 공간을 나갑니다.


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