星期一迷你高尔夫#4:JARVIS(又一大套整数序列)


22

星期一迷你高尔夫:每个星期一发布一系列简短的问题(希望!)。
(对不起,我又迟到了;昨天和今天基本上都离开了我的电脑。)

美国程序员(尤其是代码高尔夫球手)肯定喜欢任意整数序列。我们甚至拥有一个专门用于这些序列的完整站点,目前大约有200,000个条目。在这个挑战中,我们将实现另一组这些序列。

挑战

您面临的挑战是编写一个程序或函数,该程序或函数采用整数N,并输出以10为底的整数序列,其中每个下一个整数都是通过以下方式确定的:

  • 从1开始
  • 对于先前整数的以10为底的表示形式的每个数字D

    • 如果D为0,则将当前整数加1。
    • 否则,乘以目前的整数d

细节

  • 您可以假设0 < N <2 31
  • 您必须从输入数字开始输出序列中的每个整数,直到达到小于10的数字。
  • 输出可以是数组,也可以是由空格,逗号,换行符或它们的组合分隔的字符串。
  • 允许使用尾随空格和/或换行符,但不能使用尾部逗号。
  • 永远不应有任何前导零。

例子

范例1: 77

这个例子很简单:

77 = 1*7*7 = 49
49 = 1*4*9 = 36
36 = 1*3*6 = 18
18 = 1*1*8 = 8

因此,正确的输出为77 49 36 18 8

范例2: 90

这里我们有:

90 = 1*9+1 = 10
10 = 1*1+1 = 2

因此输出将是90 10 2

范例3: 806

从左到右阅读方程式:

806 = 1*8+1*6 = 54 (((1*8)+1)*6)
 54 = 1*5*4   = 20
 20 = 1*2+1   = 3

输出应为806 54 20 3

测试用例

每行中的第一个数字是输入,实线是预期的输出。

77 49 36 18 8
90 10 2
249 72 14 4
806 54 20 3
1337 63 18 8
9999 6561 180 9
10000 5
8675309 45369 3240 25 10 2
9999999 4782969 217728 1568 240 9
1234567890 362881 2304 28 16 6

作为参考,以下是10到100之间的下一个整数:

Current | Next
--------+-----
     10 |  2
     11 |  1
     12 |  2
     13 |  3
     14 |  4
     15 |  5
     16 |  6
     17 |  7
     18 |  8
     19 |  9
     20 |  3
     21 |  2
     22 |  4
     23 |  6
     24 |  8
     25 | 10
     26 | 12
     27 | 14
     28 | 16
     29 | 18
     30 |  4
     31 |  3
     32 |  6
     33 |  9
     34 | 12
     35 | 15
     36 | 18
     37 | 21
     38 | 24
     39 | 27
     40 |  5
     41 |  4
     42 |  8
     43 | 12
     44 | 16
     45 | 20
     46 | 24
     47 | 28
     48 | 32
     49 | 36
     50 |  6
     51 |  5
     52 | 10
     53 | 15
     54 | 20
     55 | 25
     56 | 30
     57 | 35
     58 | 40
     59 | 45
     60 |  7
     61 |  6
     62 | 12
     63 | 18
     64 | 24
     65 | 30
     66 | 36
     67 | 42
     68 | 48
     69 | 54
     70 |  8
     71 |  7
     72 | 14
     73 | 21
     74 | 28
     75 | 35
     76 | 42
     77 | 49
     78 | 56
     79 | 63
     80 |  9
     81 |  8
     82 | 16
     83 | 24
     84 | 32
     85 | 40
     86 | 48
     87 | 56
     88 | 64
     89 | 72
     90 | 10
     91 |  9
     92 | 18
     93 | 27
     94 | 36
     95 | 45
     96 | 54
     97 | 63
     98 | 72
     99 | 81
    100 |  3

您可以在此处找到扩展到10000的列表。

计分

这是,因此以字节为单位的最短有效代码获胜。Tiebreaker提交的提交首先达到其最终字节数。下个星期一,10月19日将选出获胜者。祝您好运!

编辑:恭喜您的获胜者@isaacg,再次使用Pyth获得14个字节

Answers:


10

Pyth,15个 14字节

.uu|*GHhGjNT1Q

1个字节,感谢丹尼斯

测试套件

这种挑战感觉就像是Pyth的reduce函数所造成的。一减少数字,一减少直到值停止变化,我们就很好。


2
|*GHhG保存一个字节?H*GHhG
丹尼斯

4

PowerShell,92 91 90 88 87字节

($n=$args);while($n-gt9){$x=1;[char[]]"$n"|%{$x=if($y=$_-48){$x*$y}else{$x+1}};($n=$x)}

1
使用(...)自动输出,这真是太聪明了……将来我需要记住这一点。
AdmBorkBork,2015年

3

28 25 23字节

Tt>Pa{Y1FdaYy*d|y+1a:y}

以数字作为命令行参数,并在连续的行上输出序列。

说明:

                         a is cmdline arg; t is 10 (implicit)
Tt>Pa{                }  Loop till a<10, printing it each time the test is made:
      Y1                   Yank 1 into variable y
        Fda                For each digit d in a:
           Yy*d|y+1          If y*d is truthy (nonzero), yank it; otherwise, yank y+1
                   a:y     Assign value of y back to a

现在,我很高兴P在几个版本前从一个声明更改为一个运算符。Pa是一个表达式,其计算结果为,a但也输出,因此我可以使用进行打印a并同时测试其值是否小于10 t>Pa


3

果酱,26 25 24 22字节

riA,{_pAb{_2$*@)?}*j}j

要么

ri{_pAb{_2$*@)?}*_9>}g

在线尝试。

怎么运行的

两种程序本质上都是一样的。第一种是递归方法,第二种是迭代方法。我将解释第一个,我认为它更有趣。

ri                     Read an integer from STDIN and push it on the stack.
  A,{               }j Initialize a memoized, recursive function j with the array
                       [0 ... 9] as "base cases". If j is called on an integer
                       below 10, it returns the element at that index of the base
                       cases (which is same integer) and does not execute the code
                       block. The base case array is filled with new values as j is
                       called again and again, but we do not use this feature.
     _p                Copy and print the integer on the stack.
       Ab              Convert it into its base-10 digits.
         {       }*    Fold; push the first digit, for each remaining digit:
          _2$*         Multiply copies of the accumulator and the current digit.
              @)       Increment the original accumulator.
                ?      Select the product if the digit is non-zero, else the sum.
                   j   Call j on the result.
                       If the result was less than 10, it is retrieved from the
                       base cases and pushed on the stack. CJam prints it before
                       exiting the program.

2

Minkolang 0.752 46个字节

ndN((d25*%1R25*:)r11(x2~gd4&x1+!*I1-)dNd9`,?).

Woohoo嵌套循环!

说明

ndN     Takes integer input and outputs it
(       Starts overall loop

 (        Starts loop that separates top of stack into digits
  d25*%   Modulus by 10
  1R      Rotates stack 1 unit to the right
  25*:    Divides by 10
 )

 r11   Reverses stack and pushes two 1s; 1 for the dump and 1 for the multiply
 (     Starts the multiply/add loop
  x    Dumps top value

      -This top-of-stack dump is because
       while loops end when the stack is
       empty or the top of stack is 0. The
       top of stack is *not* popped for
       this conditional check, so if the loop
       continues, I need to dump the left-over
       from the previous iteration.

  2~gd    Gets next-to-last stack value and duplicates for the conditional
  4&      Jumps 4 spaces if top of stack is positive
   x1+!   Dumps the 0 leftover, adds 1 to top of stack, and jumps the multiply
   *      Multiplies the top two elements of stack
  I1-     Pushes length of stack - 1
 )        Exits the loop if top of stack is 0 (i.e., len(stack)=1)
 dN       Outputs as integer
 d9`,?    Jumps out of the loop if top of stack <=9
)
.    Stop.

2

Mathematica,66个字节

Most@FixedPointList[Fold[If[#2<1,#+1,1##]&,1,IntegerDigits@#]&,#]&

2

Python 3、74、76字节

这里已经有了一个带有reduce的Python答案,所以我想在没有它的情况下做一个。应该用一个int来调用它。

def j(n,m=1):
 print(n)
 if n>9:
  for d in str(n):m=m*int(d)or m+1
  j(m)

2

Python,85 80字节

def g(n):y=reduce(lambda i,x:i*int(x)or i+1,`n`,1);return[n]+(g(y)if n>9else[])

现在,这可以正确打印出整个列表,而不仅仅是第一个值。


您可以使用未命名的lambda来节省两个字节,即省略g=
Alex A.

1

K5,24字节

(1{(x*y;x+1)@~y}/.:'$:)\

扫描操作员\所做的正是在迭代到固定点的同时收集项目列表。在每次迭代中,我首先将数字转换为字符串,然后求值每个字符(.:'$:),将数字分解为数字。然后,我/从1开始并使用lambda 进行归约(){(x*y;x+1)@~y}。在这种情况下,x是递减值,并且y是序列的每个连续项。

实际上:

  f: (1{(x*y;x+1)@~y}/.:'$:)\

  f'77 90 249 806 1337 9999 10000 8685309 9999999 1234567890
(77 49 36 18 8
 90 10 2
 249 72 14 4
 806 54 20 3
 1337 63 18 8
 9999 6561 180 9
 10000 5
 8685309 51849 1440 17 7
 9999999 4782969 217728 1568 240 9
 1234567890 362881 2304 28 16 6)

1

朱莉娅93 89 88 86 83 77字节

f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)

这将创建一个递归函数 f,该将序列元素打印在单独的行上。

取消高尔夫:

function f(n::Int)
    println(n)
    if (d = n > 9)
        for i in reverse(digits(n))
            i < 1 ? d += 1 : d *= i
        end
        f(d)
    end
end

在线尝试

感谢Dennis,节省了6个字节!


它应该n>9符合第二个示例。而且,f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)有点短。
丹尼斯

@丹尼斯很棒的主意,谢谢!
Alex A.

1

Ruby 83,72个字节

原始声明为函数:

def f(d)loop{p d;break if d<10;d=d.to_s.bytes.inject(1){|r,i|i>48?r*(i-48):r+1}}end

我尝试使用,Enumerator.new但是它使用了很多字节:-(

使用递归进行了改进

def f(d)p d;f(d.to_s.bytes.inject(1){|r,i|i>48?r*(i-48):r+1})if d>10 end

0

C#和LINQ,165个 146字节

void j(int a){r.Add(a);var l=a.ToString().Select(d=>int.Parse(d.ToString()));int n=1;foreach(int i in l)n=i==0?n+1:n*i;if(n>9)j(n);else r.Add(n);}

j(对于jarvis)是递归函数。r是结果的int列表。

在LINQPAD中测试:

void Main()
{
    j(806);
    r.Dump();
}
List<int> r = new List<int>();

void j(int a){r.Add(a);var l=a.ToString().Select(d=>int.Parse(d.ToString()));int n=1;foreach(int i in l)n=i==0?n+1:n*i;if(n>9)j(n);else r.Add(n);}

您可以通过删除围绕运营商的空间节省一些字节,例如int n = 1可以int n=1
亚历A.

好抓@AlexA。减少到
146。– noisyass2

您也可以通过执行a +“”而不是a.tostring()来节省一点时间
Alex Carlsen

0

Haskell,71个字节

x!'0'=x+1
x!c=x*read[c]
g x|h>9=x:g h|1<2=[x,h]where h=foldl(!)1$show x

用法:g 8675309-> [8675309,45369,3240,25,10,2]


0

Matlab,108岁

N=input('');disp(N)
k=1;while k
x=1;for n=num2str(N)-48
if n
x=x*n;else
x=x+1;end
end
disp(x)
N=x;k=x>9;
end

0

Java 8,148字节

String f(int j){String s="";Function r=i->(""+i).chars().map(x->x-48).reduce(1,(x,y)->y>0?x*y:x+1);while((j=(int)r.apply(j))>9)s+=j+" ";return s+j;}

格式化的

String f(int j) {
    String s = "";
    Function r = i -> ("" + i).chars().map(x -> x - 48).reduce(1, (x, y) -> y>0 ? x*y : x+1);
    while ((j = (int)r.apply(j)) > 9) s += j+" ";
    return s+j;
}

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.