加-乘-加序列


27

相关

给定的整数n > 1
1)构造号码的范围n, n-1, n-2, ... 3, 2, 1并计算出总和
2)取该数量的单独的数字和计算产品
3)采取的个别数字数目并计算出总和
4)重复步骤2和3,直到达到一位数。该数字是结果。

该序列的前20个术语如下:

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

注意:此序列不在OEIS中。

I / O和规则

  • 数字将很快变得非常大,因此该解决方案必须能够处理多达100,000个输入数字而不会失败(如果您的代码可以处理超过此数量的情况就可以了)。
  • 输入和输出可以通过任何方便的方法给出。
  • 完整的程序或功能都是可以接受的。如果是函数,则可以返回输出而不是打印输出。
  • 禁止出现标准漏洞
  • 这是因此所有常用的高尔夫规则都适用,并且最短的代码(以字节为单位)获胜。

例子

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0

3
+1这不是在OEIS序列挑战
JAD

2
每当n≤100000时仅步骤2和3的两次迭代就足以获得结果。我们可以利用这一优势吗?或者我们选择的算法应该在较大的n值下工作吗?
丹尼斯

2
@Dennis该算法应适用于的任何值n。发布的解决方案最多只能使用n = 100000
AdmBorkBork

3
Numbers will get very large quickly不,不是
l4m2

3
@ l4m2不是输出。但是100000 + 99999 + ... + 1 = 5000050000是一个33位数字,您选择的语言可能无法表示,也可能无法表示。
丹尼斯

Answers:


10

Python 2中77个 72 71 62 60字节

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

感谢@xnor打高尔夫球2个字节!

在线尝试!


只是切换到for循环,但将来我必须记住该技巧。
丹尼斯

repeat until you reach a single digit哪里?
泰特斯

2
@Titus我只执行步骤2和3的n次迭代,这总是足够的。实际上,由于n≤100000,所以三个迭代就足够了。
丹尼斯

现在您已经提到了:实际上,需要三个迭代的最小输入是236172;。这是唯一一百万以下的数字。
泰特斯




4

MATL15 13字节

为了向本月语言致敬:

:`sV!UpV!Utnq

在线尝试!

我认为没有比将数字转换为字符串V然后转置然后!将垂直向量转换回数字形式更简单的方法了U

感谢Creator 1自己节省了2个字节!我忘记了隐式结尾,这意味着我可以删除],而不是将元素数与进行比较,而1可以直接减小该值并将其直接用作布尔值。

因此,解释如下:

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... MATL,路易斯·门多。


3

JavaScript(ES6),60个字节

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

在线尝试!

已评论

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

备用版本,59字节(无竞争)

一种非递归版本,仅适用于n <236172。(它涵盖了所请求的范围,但不符合有效的通用算法的要求。)

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

在线尝试!


当N> = 77534568790时,您的主版本会中断。当N = 7753456879时,它将起作用。不确定断点在哪里。当然,这并不重要,因为需求量的仅仅是处理最多N = 100,000,所以我不知道为什么我写这个....
罗斯压

1
@RossPresser作为一个粗略的估计,我想说它可以工作到Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265
阿诺尔德

3

Haskell72 71 63字节

g=map(read.pure).show
f n=until(<10)(sum.g.product.g)$sum[1..n]

感谢@BMO提供一个字节,@nimi提供8个字节!

在线尝试!


2

Stax14 13 10 字节

ñu┌↕a√äJ²┐

运行并调试

制作起来很有趣。我想知道最后是否有更简洁的方法进行比较。

说明

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

-1字节归功于ovs

-3字节归功于Scrooble


2

R152130109字节

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

在线尝试!

@Giuseppe发现了21 42个字节,其中包含我还不熟悉的各种R东西,以及一种获取数字的数字而又不强迫字符串和数字返回的方法,并且字节更少!

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) 被需要的9854为老功能的情况下,由于第一阶段产物为80000,其中,R为打印8E + 05结束。


知道了 科学计数法输出。接得好!
AdmBorkBork

1
终于绕开了scipen在线试用!注意,这max(0,log10(x))是因为if x=0,则将log10(0)=-Inf导致错误。
朱塞佩

1

Pyth,11个字节

usj*FjGTTsS

在这里尝试!

usj * FjGTTsS –完整程序。N =输入。
          S –范围。产率[1,N]⋂。
         s –总和。
u –尽管没有两个连续的迭代产生相同的结果,但执行(变量:G):
   * FjGT –数字产品。
 sj T –数字总和。

1

木炭,18字节

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

在线尝试!链接是详细版本的代码。说明:

≔Σ…·¹Nθ

将整数相加直到输入。

 W›θ⁹≔ΣΠθθ

当结果大于9时,取数字乘积的数字总和。

Iθ

将结果转换为字符串并隐式打印。


1

盖亚 8字节

┅⟨Σ₸∨Π⟩°

在线尝试!

旧的解释(在修复Gaia的故障IMO:P的错误之前):

–ΣΠ⟩°–完整程序。N =输入。
┅–范围。将[1,N]推入堆栈。
 –没有两次连续的迭代都得到相同的结果,请执行以下操作:
  Σ–总和(或数字总和,当应用于整数时)。
   Π–数字产品。

感谢Dennis节省了1个字节。


┅⟨ΣΠ⟩°保存一个字节。
丹尼斯

这对于数字总和为0的值不起作用,例如4
Jo King

@JoKing固定,感谢您发现。不幸的是,在盖亚,由于某些原因,把0结果的位数[]:(
Xcoder先生18年

1

F#,175个字节

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

在线尝试!

该函数的唯一警告是输入值必须为type uint64

取消高尔夫有点像这样:

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

该功能d n将数字n转换为其组成数字。它首先转换为字符串,然后获取字符串中的每个字符。然后必须将每个字符都转换回字符串,否则,字符将被转换为其ASCII值而不是其“真实”值。

c n功能是主要功能,并具有n初始值。此功能r是我们的运行价值。该while循环执行以下操作:

  • 转换r为其组成数字(d r)。
  • 获取所有这些数字的乘积。该Seq.reduce函数使用具有累计值(a)和序列(x)中下一个值的函数,在这种情况下返回乘积。初始值是序列中的第一个元素。
  • 将此产品值转换为其组成数字(d)。
  • 对之前的数字求和,并将其分配给r

1

Befunge,136个字节

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

您可以在这里尝试

尽管并非所有的口译员都具有足够大的单元格大小,但它的数量很少,几乎可以为任何人使用。对于更多的人,n您可能需要像BefunExec这样的解释


1

Gol> <>35 33字节

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

在线尝试!

Jo King的-2个字节。

广泛使用函数和隐式无限循环。

完整程序示例及其工作方式

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top


1

Japt,16 14 13字节

_ì ×ìx}gN®õ x

试试吧


说明

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition

整洁,我试图自己解决这个问题,但没有找到一个好的解决方案,因此很高兴看到您的解决方案。
Nit

谢谢@Nit。不过,必须有一个更短的方法。
毛茸茸的

@Nit,明白了!仍然相信必须有更短的方法。
毛茸茸的


0

PHP 7,89字节

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

与管道一起运行-r在线尝试

  • PHP始终将输入作为字符串,因此我必须使用+强制转换为int才能按需~工作。
  • 预增量将不起作用:无论我放在何处,都会影响两个操作数。
  • 但是:单个数字出现在迭代之前还是之后都没关系(其他迭代不会改变任何事情);所以我可以for()代替使用do ... while()
  • 内联分配函数名称需要PHP 7或更高版本。
    较旧的PHP需要一个字节:(完全for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    不分配str_split给变量将浪费另一个字节。)



0

PowerShell Core91101 93字节

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

在线尝试!

脱开一点...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

第一步是将整数拆分为数字,方法是将整数拆分为字符串字符数组。之后,插入操作数,然后将字符串作为命令求值。然后,要进行多次加法运算直到输入为一位。

iex是一个别名,Invoke-Command用于评估传递到第一个参数位置的字符串。

编辑:按照@AdmBorkBork的要求,我已将函数标头添加到字节数。另外,我做了一点数学运算,意识到迭代次数的上限是< log log 10^6 < log 6 < 2,因此又节省了六个字节。

编辑x2: @AdmBorkBork找到了一种更简洁的方法,将整数转换为数学表达式,然后建议将其传递iex。这样节省了8个字节。谢谢!


很高兴看到另一个PowerSheller!但是,我认为您需要Function F($a){ }在字节数中包含函数定义。但是,我认为您应该可以使用[char[]]而不是保存一些内容-split''-ne''
AdmBorkBork,

[char[]]1234=Ӓ,无效;我也许可以使它工作,但现在可能并不明显。谢谢你的建议!
杰夫·弗里曼

对不起,我并不清楚- [char[]]"$o"|iex而不是iex( )
AdmBorkBork

这个技巧节省了我8%的代码。太棒了 谢谢!
杰夫·弗里曼



0

Java 8,129字节

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

在线尝试。

说明:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result

0

朱莉娅0.6,56字节

f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k

在线尝试!

非常简单:(n+1)n÷2从1..n 计算总和,检查它是否是一个数字(>9),如果不是,请再次尝试将k设置为k的数字乘积的总和,否则返回k。

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.