原始青蛙🐸


44

“原始青蛙”是一种奇怪的动物,会在整数之间跳跃,直到到达3或19。


您的程序应接受一个整数n作为输入,并输出以下算法(319)的结果。

对于给定的整数n >= 2

  1. f青蛙的位置。最初设置为n
  2. 如果f = 3f = 19:青蛙停止跳跃停止程序和输出f
  3. 如果f是素数:青蛙跳到那个位置2×f-1。返回步骤2。
  4. 如果f为Composite:则将其d设为f最大的除数。青蛙跳到那个位置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 73 145 116 87 58 29 57 38 19]
Arnaud

8
很酷的Collat​​z变体。
亚瑟

3
如果我们不能证明青蛙总是来到319,我们可以更改算法中的第2项,说如果青蛙进入了任何循环(遇到了之前看到的位置),那么它将停止跳跃并返回最小的该循环的成员。
杰普·斯蒂格·尼尔森

4
@PyRulez如果达到了,您可能应该告诉OP。
mbomb007 '17

3
@KeyuGan也许这对在Math.SE上发布是一件好事。
mbomb007 '17

Answers:



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
完全喜欢frog和您的变量这个词。+1。
rayryeng-恢复莫妮卡

10

视网膜63 62字节

感谢Neil节省了1个字节。

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

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

在线尝试!

一元输入和输出(为了方便起见,测试套件使用十进制)。对于较大的输入,此解决方案变得异常缓慢。该9983测试用例会超时TIO。

说明

由于{有了,程序的两个阶段都简单地循环运行,直到不再影响字符串为止。我们在舞台处理复合材料和舞台处理底漆之间交替。这使我们避免了实际的条件(在视网膜中实际上不存在)。如果当前值是该阶段的错误类型,则该阶段完全不执行任何操作。

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

这将处理复合材料。我们将可能的除数与匹配(11+),但是然后检查它是否与不合成(?<!^\2+(11+)),因此我们仅考虑素数。由于的贪婪性+,因此优先考虑最大的因素。然后,通过尝试将字符串的其余部分与重复进行匹配,来检查该潜在除数是否为实际除数(?=\1+$)。只需从字符串中删除该除数,这就是您减去一进制数的方式。

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

除了319之外,此过程都会处理素数。负前瞻确保输入不是复合输入,不是3也不是19。然后,我们匹配一个1并用整个字符串替换它。这是计算n-1 + n的一元形式,当然是2n-1

一旦我们击中319,则任何阶段都无法匹配该字符串,并且将不再更改它。


1
1$'一样$_吗?
尼尔

4
@Neil是的……
Martin Ender

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

Wolfram语言(Mathematica),65岁66 68 个字节

#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
  • -1个字节,感谢Misha Lavrov!
  • -2个字节,感谢Martin!

在线尝试!

灵感来自小费。基本上,它只是重新创建算法。

//.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 '17

1
检查3和19的更短方法是#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
Misha Lavrov

@MishaLavrov但结果不正确?
Keyu Gan

@KeyuGan对我来说,这两个函数给出确切的整数1相同的结果通过1000
米莎拉夫罗夫

1
您可能遇到的问题是在注释中复制和粘贴时插入了无法打印的字符,这有时会发生。
米莎·拉夫罗夫

6

05AB1E19 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

对于57991超过1分钟的时间
RosLuP

@RosLuP:最好离线运行很长的测试用例;)
Emigna

5

JavaScript(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%nn%38代替n==3|n==19。在我的Java回答中也保存了1个字节,所以谢谢!
凯文·克鲁伊森

在ideone 57991输入中生成prog.js:2:26 InternalError:递归过多
RosLuP

在tio中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

Python 2中110个 105 103 101字节

-2个字节,感谢@Lynn

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)

在线尝试!


Python 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个字节。
林恩

对于输入57991 sys.setrecursionlimit(20000)
RosLuP '17

4

MATL22 21字节

感谢@Giuseppe删除了1个字节!

`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

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

在这里可能缺少一些高尔夫技巧,这是我第一次尝试Haskell高尔夫。


您好,欢迎来到该网站。您不需要换行符和模式保护符的空格。您也可以1>0True大多数时间使用,但是例如使用赋值通常可能会更好c<-z n
小麦巫师

1
[x|x<-[b-1,b-2..1],rem b x==0]reverse[x|x<-[1..(b-1)],b比雷姆还矮x==0]
小麦巫师

2
最后一件事,如果您想讨论Haskell打高尔夫球,可以加入Of Monads and Men
小麦巫师

3

Neim17 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

R + 数字102 99字节

function(n){while(!n%in%c(3,19))n="if"(isPrime(n),2*n-1,n-max(primeFactors(n)))
n}
library(numbers)

在线尝试!

R并不以短的内置程序而闻名,甚至包也照常!


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

-5个字节,将带有循环的递归Java 7方法转换为Java 8 lambda。@Arnauld的JavaScript答案(通过将and 更改为and)
隐含了-1个字节。我认为应该可以以某种方式组合两个循环并检查是否为素数,并同时获得最大的素数,但我还不能弄清楚(尚未)。因此,这将是目前的初始版本。 通过@Nevay,我可以做-40字节,这是我无法做到的:组合循环以一次检查素数和最大素数。n!=3&n!=19return n;57%n>0return n%38;
n

说明:

在这里尝试(甚至999999在1秒内执行)。

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
1个字符,不足为C#多种语言:(
Ian H.

@IanH。呵呵,是的,通常是这样: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个字节!
凯文·克鲁伊森

3

Bash,73个字节

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

在线尝试!稍作修改以在TIO上工作。

使用递归调用其自己的脚本文件$0./filename.sh文件在TIO中不起作用,因为它必须以形式运行。接受输入作为命令行参数。

使用与@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

Pyth,19个字节

.W!/P57H?P_ZtyZ-ZeP

验证所有测试用例!

稻壳答案启发了我节省2个字节(,3 19P57)。

如何运作

.W!/ P57H?P_ZtyZ-ZeP-完整程序。

.W-同时运行。虽然A(值)是真实的,但值= B(值)。返回最后一个值。
    P57-57的素因([3,19])。
   / H-计算当前值的出现次数。
  !-逻辑非。0-> Truthy,还有其他内容-> Falsy。
        P_Z-如果当前值为质数,则:
            tyZ-将当前值加倍,减1。
               -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没有内置的素数分解,因此这是从我对“素数好友”的回答中借鉴的代码。

首先是我们的for循环。设置设置$n为输入值,有条件的条件使循环一直持续到57%$n非零(感谢Arnauld使用该技巧)。在循环内部,我们首先获得$a(设置为$n)的主要因子的列表。这是从主要因素伙伴那里借来的代码。如果输入$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(如果我没记错的话),它超出了保留的堆栈空间。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.