折叠整数以节省空间!


20

疯狂的数学家拥有大量的数字,因此他留下的空间非常有限。为了节省一些钱,他必须折叠整数,但是不幸的是他确实很懒。如果您想帮助他,您的任务是创建一个函数/程序,该函数可以折叠一个给定的正整数以表示我们的数字疯子。

如何折叠整数?

如果可以用位数之和均匀除以它,请用位数之和除。如果不满足该要求,则将其余数除以位数之和。重复该过程,直到达到结果1。折叠后的整数是您必须执行的操作数。让我们举个例子(例如1782):

  1. 获取其数字的总和:1 + 7 + 8 + 2 = 181782被整除18,所以下一个数字是1782 / 18 = 99

  2. 99不能被整除9 + 9 = 18,因此我们取余数:99 % 18 = 9

  3. 9显然可以被整除9,因此我们将其除以并得到1

结果是3,因为要达到,需要3个操作1

规则和规格

  • 某些整数可能具有等于的数字总和1,例如10100。您的程序无需处理此类情况。也就是说,您可以确保输入的整数不具有等于的数字总和1,并且使用给定整数进行的任何运算都不会导致数字的总和为11本身除外,即“目标”)。例如,您将永远不会收到1020作为输入。

  • 输入将是一个大于的正整数1

  • 默认漏洞适用。

  • 您可以采用任何标准均值进行输入并提供输出。


测试用例

输入->输出

2-> 1
5-> 1
9-> 1
18-> 2
72-> 2
152790-> 2
152-> 3
666-> 3
777-> 3
2010-> 3
898786854-> 4

这是一个程序,可让您可视化过程并尝试更多的测试用例。


这是,因此每种语言中最短的代码(以字节计)将获胜!


受此挑战启发,尽管起初似乎并不相关。
Xcoder先生17年

3
这将是一个权宜之计,但是从长远来看,数学家应该真正考虑购买希尔伯特酒店之一。您总是可以在其中之一中找到一些未使用的房间。

虽然8987868546是有效输入,但它会破坏您的测试工具以及许多(如果不是全部)答案……
Mischa

@MischaBehrend您的示例不是有效的输入。我认为您错了我的最后一个测试用例。有效输入是898786854,不是8987868546(您6在末尾添加了)
Xcoder先生,

nvm ...应该阅读整个第一条规则... 将此留在这里,以便您知道为什么我认为它是有效的:这不是一个错误...我有意将其更改为测试这些脚本...并阅读规则有效的输入。中的所有数字的总和8987868546 不为1(符合规则1),并且8987868546是大于1的正整数(符合规则2)。
米沙(Mischa)

Answers:


6

05AB1E13 12字节

[¼DSO‰0Kθ©#®

在线尝试!

说明

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter


5

Haskell,85 78字节

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

感谢Bruce Forte,节省了7个字节。

在线尝试。


使用divMod和删除,节省更多字节where在线尝试!
Laikoni '17

@Laikoni Wow,这是一个很大的进步!请以其他答案发布;它和我的完全不同。顺便说一句:我一直在寻找摆脱困境的技巧where。以后会用到。:)
Cristian Lupascu

sum[read[d]|d<-show n]保存一个字节
nimi

5

JavaScript(ES6),66 58 51 49字节

将输入作为整数。返回false01当它遇到的任何数字,其数字加起来并引发溢出错误1

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • Justin的帮助下节省了8个字节。

测试一下

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
您可以通过使用来对数字求和来节省一些字节eval(array.join`+`)吗?
贾斯汀·马里纳

我确实可以,@ JustinMariner-你让我忍不住了!谢谢:)
毛茸茸的

4

外壳,12个字节

←€1¡Ṡ§|÷%oΣd

在线尝试!

说明

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.



2

视网膜,100字节

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

在线尝试!链接仅包含较小的测试用例,因为较大的测试用例花费的时间太长。


2

Mathematica,73个字节

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&

可以==0代替<1吗?
Xcoder先生17年

@ Mr.Xcoder当然可以!我做了一个分拣机版本...
J42161217

2

PHP,68 + 1字节

一元输出:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

十进制输出,73 + 1字节:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

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


Elvis操作员需要PHP 5.3或更高版本。对于较旧的PHP,请替换?:?$n%$s:(+5个字节)。


2

Ruby,46个字节

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}

2

Haskell94 93 89 88字节

感觉真长。

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

在线尝试!

感谢@Laikoni&@nimi每人打1个字节!





1

Perl,71个字节,64个字节,63个字节

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

在线尝试

编辑:由于Xcali的评论,保存了7个字节

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

编辑:由于5.14无损替换s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

-pl顶部应该是一个命令行标志呢?
暴民埃里克(Erik the Outgolfer)'17年

是的,它们是perl的选择
Nahuel Fouilleul

您应该-pl根据这篇文章算一下国旗。
暴民埃里克(Erik the Outgolfer)'17年

我为pl选项计算了69个字节+2,对吗?
Nahuel Fouilleul

你可以打一点。 $c不需要初始化。它将从undef0 开始。while闭包后的分号可以删除。另外,您不需要-l。无需一次运行即可获得多个输入。
Xcali

1

Dyalog APL,36个字节

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

在线尝试!

怎么样?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}

1

盖亚(Gaia),13个字节

-@{:ΣZ¤∨)‡}°\

在线尝试!

说明

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter

1

Matlab,150字节

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

输入应作为字符串提供给函数,例如X('152')。

该函数通过循环并递增d来工作。该x=y;行对于避免Matlab尝试同时读取和覆盖变量值的错误很有必要,显然,这对我来说是新的。

取消高尔夫:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end


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.