加性持久性


20

传递所有可能性的最短代码将获胜。

在数学中,数字的持久性表示必须对某位数字进行某种操作,直到达到某种特定的固定条件。您可以通过将整数的数字相加并重复来确定正整数的加性余辉。您将不断添加总和的数字,直到找到一个数字为止。达到该单个数字所花费的重复次数是该数字的累加持久性。

使用84523的示例:

84523
8 + 4 + 5 + 2 + 3 = 22
2 + 2 = 4

It took two repetitions to find the single digit number.
So the additive persistence of 84523 is 2.

您将得到一个正整数序列,您必须计算它们的加法持久性。每行将包含一个不同的整数要处理。输入可以采用任何标准的I / O方法

对于每个整数,必须输出整数,后跟一个空格,再加上其累加持久性。每个处理的整数必须在自己的行上。

测试用例


输入输出

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0

1
您的测试用例包括一些大于2 ^ 64的值,并且您的规范说该程序只需要处理最大2 ^ 32的值。可能值得澄清。
彼得·泰勒

@Peter Taylor,忘记删除这些限制。如果程序可以处理我提供的输入,则它应该没有限制问题。
凯文·布朗

5
999999999999的持久性不是2而是3?
Eelvex

@Evelex,我猜这是不正确的最后一刻更改。固定。
凯文·布朗

这里有几个答案不是在stdout上进行输出,而是通过在接受命令行输入后返回结果来使用J的“交互式”输出。(这包括另外2个J答案,我猜是K答案。)这被认为是合法的吗?因为如果这样的话,我可以丢掉18个字符。
杰西·米利坎

Answers:


6

K-29个字符

输入是作为参数传递的文件名,不包括文件名的29个字符。

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35-> 31:取消外部功能。
  • 31-> 29:删除括号。

1
-1+#=>#1_
streetster

4

Python 84个字符

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c

挑战案例:06234..结果成功挑战:-)
Quixotic

@Debanjan谢谢。已更正。
fR0DDY 2011年

4

Haskell,100个字符

p[d]=0
p d=1+(p.show.sum$map((-48+).fromEnum)d)
f n=n++' ':shows(p n)"\n"
main=interact$(f=<<).lines

您可以使用read.pure代替来保存6个字节(-48+).fromEnum,请在线尝试!
'18 -4-25


4

外壳10 15字节

+5个字节用于可怕的I / O要求

m(wΓ·,LU¡oΣdr)¶

在线尝试!

说明

为了支持多个输入,我们需要使用m(₁r)¶函数进行有趣的计算在哪里):

m(₁r)¶  -- expects newline-separated inputs: "x₁␤x₂␤…␤xₙ"
     ¶  -- split on newlines: ["x₁","x₂",…,"xₙ"]
m(  )   -- map over each string
 ( r)   -- | read integer: [x₁,x₂,…,xₙ]
 (₁ )   -- | apply the function described below

该函数执行以下操作:

wΓ·,LU¡(Σd)  -- input is an integer, eg: 1234
      ¡(  )  -- iterate the following forever and collect results in list:
       ( d)  -- | digits: [1,2,3,4]
       (Σ )  -- | sum: 10
             -- : [1234,10,1,1,1,…
     U       -- keep longest prefix until repetition: [1234,10,1]
 Γ           -- pattern match (x = first element (1234), xs = tail ([10,1])) with:
  · L        -- | length of xs: 2
   ,         -- | construct tuple: (1234,2)
w            -- join with space: "1234 2"

3

bash,105个字符

while read x
do
for((i=0,z=x;x>9;i++))do
for((y=0;x>0;y+=x%10,x/=10))do :
done
x=$y
done
echo $z $i
done

实际上几乎没有打高尔夫球,但是我看不出如何改进它。



3

Ruby,85个字符

puts $<.map{|n|v=n.chop!;c=0;[c+=1,n="#{n.sum-n.size*48}"] while n[1];[v,c]*' '}*"\n"

我不得不从Alex借用“ sum-size * 48”的想法,因为它太整齐了,所以不能错过(至少在Ruby中)。


3

Golfscript,40个字符

n%{.:${;${48-}%{+}*`:$,}%.,1>\1?+' '\n}%

3

J-45个字符

从stdin读取

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3

我试图用^:a:自己,但找不到合适的文档...有任何提示吗?
Eelvex

1
u ^:n字典条目具有用法信息,但有点密集。^:a:就像其他任何次幂调用一样,但是它收集结果并在连续调用的参数相同(收敛)时结束。
isawdrones 2011年

1
a:通过J参考卡 [PDF]中的^:a:技巧发现了@Eelvex FWIW
JB

@JB:那^:a:是我所知道的唯一参考文献:D
Eelvex 2011年

@Eelvex哦。那时我经历了相反的经历。我发现了字典中的功能,并一开始将其用作^:(<'')(可能是Kaprekar的)某种变体,直到在卡中找到它,并a:为此进行了了解。
JB

3

c-519

(如果您相信我的框架,则为137 ...)

我决定不仅仅解决一个操作,而是决定创建一个框架来解决所有持久性问题

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char*(*O)(char*);
char*b(char*s){long long int v=0,i,l=0;char*t=0;l=strlen(s);t=malloc(l+2);
for(i=0;i<l;i++)v+=s[i]-'0';snprintf(t,l+2,"%lld",v);return t;}
int a(char**s,O o){int r;char*n;n=o(*s);r=!strcmp(*s,n);free(*s);
*s=n;return r;}
int main(int c, char**v){size_t l, m=0;char *d,*n=0;O o=b;FILE*f=stdin;
while(((l=getline(&n,&m,f))>1)&&!feof(f)){int i=0;n=strsep(&n,"\n");
d=strdup(n);while(!a(&n,o))i++;printf("%s %d\n",d,i);free(d);free(n);n=0;m=0;}}

从此开始只有两行char*b是唯一的此问题。

它将输入视为字符串,这意味着在输出级之前不会去除前导“ 0”。

上面有注释,错误检查和报告,以及文件读取(输入必须来自标准输入),其中包括:

/* persistence.c
 *
 * A general framework for finding the "persistence" of input strings
 * on opperations.
 *
 * Persistence is defined as the number of times we must apply
 *
 *    value_n+1 <-- Opperation(value_n)
 *
 * before we first reach a fixed point.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../getline.h"

/* A function pointer type for operations */
typedef char*(op_func)(char*);
typedef op_func* op_ptr;
/* Op functions must
 * + Accept the signature above
 * + return a point to a newly allocated buffer containing the updated str
 */

char* addop(char*s){
  int i,l=0;
  long long int v=0;
  char *t=NULL;
  /* protect against bad input */
  if (NULL==s) return s;
  /* allocate the new buffer */
  l = strlen(s);
  t = malloc(l+2);
  if (NULL==t) return t;
  /* walk the characters of the original adding as we go */
  for (i=0; i<l; i++) v += s[i]-'0';
  //fprintf(stderr,"   '%s' (%d) yields %lld\n",s,l,v);
  snprintf(t,l+2,"%lld",v);
  //fprintf(stderr,"   %lld is converted to '%s'\n",v,t);
  return t;
}

/* Apply op(str), return true if the argument is a fixed point fo
 * falsse otherwise,
 */ 
int apply(char**str, op_ptr op){ 
  int r;
  char*nstr;
  /* protect against bad input */
  if ( NULL==op ) exit(1); 
  if ( NULL==*str ) exit(4); 
  /* apply */
  nstr = op(*str); 
  /* test for bad output */
  if ( NULL==nstr ) exit(2); 
  r = !strcmp(*str,nstr); 
  /* free previous buffer, and reasign the new one */
  free(*str); 
  *str = nstr; 
  return r; 
}

int main(int argc, char**argv){
  size_t len, llen=0;
  char *c,*line=NULL;
  op_ptr op=addop;
  FILE *f=stdin;
  if (argc > 1) f = fopen(argv[1],"r");
  while( ((len=getline(&line,&llen,f))>1) && line!=NULL && !feof(f) ){
    int i=0;
    line=strsep(&line,"\n"); // Strip the ending newline
    /* keep a copy for later */
    c = strdup(line);
    /* count necessary applications */
    while(!apply(&line,op)) i++;
    printf("%s %d\n",c,i);
    /* memory management */
    free(c);
    free(line);
    line=NULL;
    llen=0;
  }
}

如果我们愿意像筛子一样泄漏内存,则可以节省更多。同样,也可以#define通过return等来实现,但是在这一点上,我并不介意使其更难看。



2

J,74个字符

i=:<;._2(1!:1)3
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i

编辑

  • (86→83) 的一些帽[:到ATS@
  • (83→79) 不需要的括号
  • (79→75) 更改0".".简化形式
  • (75→74) 更好的切割

例如

i=:<;._2(1!:1)3
74621
39
2677889
0
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i
74621 2  
39 2     
2677889 3
0 0  

多个输入的输出格式错误。参见“单个空间”
Jesse Millikan

@杰西:我没看错。你能写一个例子吗?
Eelvex

我不知道,我在看我猜的东西。
杰西·米利坎


1

PARI / GP 101字符

s(n)=r=0;while(n>0,r+=n%10;n\=10);r
f(n)=c=0;while(n>9,c++;n=s(n));c
while(n=input(),print(n," ",f(n)))

不幸的是,GP没有输入功能,所以我想这缺少IO部分。:( 固定:谢谢Eelvex!:)


当然有:input():)
Eelvex

@Eelvex,完成了。:)
st0le 2011年

1

Javascript-95

i=prompt();while(i>9){i=''+i;t=0;for(j=0;j<i.length;j++)t+=parseInt(i.charAt(j));i=t;}alert(t);

编辑:哎呀不做多行


1
只是注意到这不能正确输出。
凯文·布朗

1

J,78

f=:[:+/"."0&":
r=:>:@$:@f`0:@.(=f)
(4(1!:2)~LF,~[:":@([,r)".@,&'x');._2(1!:1)3

递归解决方案。从stdin读取。写到stdout,所以给我留一点懈怠-它确实需要额外的18个字符。


1

Perl-77个字符

sub'_{split//,shift;@_<2?0:1+_(eval join'+',@_)}chop,print$_,$",(_$_),$/for<>

1

JavaScript57 47字节

-10个字节,感谢@ l4m2!

f=(s,c=0)=>s>9?f(eval([...s+""].join`+`),++c):c

在线尝试!


f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
l4m2

f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x- -y),++c):c
l4m2 '18年

1
f=(s,c=0)=>s>9?f(eval([...s+""].join`+`)),++c):c
l4m2 '18年

@ l4m2谢谢!s>9eval是伟大的想法。我认为您那里有一个多余的括号,使它总共节省了10个字节:-)
奥利弗

注意严格的I / O;)
Shaggy

1

05AB1E,13 个字节

ε.µΔSO¼}¾}<ø»

输入为整数列表。

在线尝试。

说明:

ε     # Map each integer in the (implicit) input to:
    #  Reset the counter variable to 0
 Δ    #  Loop until the integer no longer changes:
  S   #   Convert it to a list of digits
   O  #   And take the sum of those
  ¼   #   Increase the counter variable by 1
    #  After the inner loop: Push the counter variable
}<    # After the map: decrease each value by 1
  ø   # Zip/transpose it with the (implicit) input to create a paired list
   »  # Join each pair by a space, and then each string by newlines
      # (after which the result is output implicitly)

1

MathGolf,11个字节

hÅ_Σ]▀£(k ?

在线尝试!

效率低得令人难以置信,但是我们不在乎。基本上,使用数字的加法持久性小于或等于数字本身的事实。

使用加法持久性小于或等于数字位数的事实。现在轻松通过所有测试用例。

输入格式虽然在某些语言中不是最优的,但实际上是在MathGolf中将多个测试用例作为输入的标准方法。输入的每一行都作为其自己的程序执行来处理,对于每次执行,输出都由单个换行符分隔。

说明(使用n = 6234

h             push length of number without popping (6234, 4)
 Å            loop 4 times using next 2 operators
  _           duplicate TOS
   Σ          get the digit sum
    ]         wrap stack in array
              this gives the array [6234, 15, 6, 6, 6]
     ▀        unique elements of string/list ([6234, 15, 6])
      £       length of array/string with pop (3)
       (      decrement (2)
        k ?   push input, space, and rotate top 3 elements to produce output (6234 2)

1

K(ngn / k),16字节

解:

{x,#1_(+/10\)\x} 

在线尝试!

说明:

{x,#1_(+/10\)\x} / the solution
{              } / lambda taking implicit x
      (     )\x  / iterate until convergence
         10\     / split into base-10 (123 => 1 2 3)
       +/        / sum
    1_           / drop first result (iterate returns input as first result)
   #             / count length of result
 x,              / prepend x (original input)


0

scala 173:

def s(n:BigInt):BigInt=if(n<=9)n else n%10+s(n/10)
def d(n:BigInt):Int=if(n<10)0 else 1+d(s(n))
Iterator.continually(readInt).takeWhile(_>0).foreach(i=>println(i+" "+d(i)))



0

Python 3,82字节

while 1:f=lambda n:n//10and 1+f(sum(map(int,str(n))));i=input();print(i,f(int(i)))


0

Japt,28个字节

Ë+S+(@D=X©A<D©ì x ªD D<AÃa÷
Ë                            // Map over the inputs and return each, followed by
 +S+                         // a space, followed by the number's persistence.
      D=     ©ì x            // To find it, fold the number up
        X©A<D     ªD         // if we can (handles unfoldable cases),
    (@               D<AÃa   // until it can't be folded up any further.
                          ÷ // Then, join everything up with newlines.

在线尝试!


0

PHP,72 + 1字节

+1表示-R标志。

for($i=0,$a=$argn;$a>9;$i++)$a=array_sum(str_split($a));echo"$argn $i
";

与一起作为管道运行-R

  • 将PHP作为管道运行将对每个输入行执行一次代码
  • 但是它不会在它们之间设置变量;因此$i必须初始化。
    (此外,如果0不进行初始化,它将不打印任何内容,而只打印单个数字。)

0

Bash + coreutils,83个字节

[ $1 -le 9 ]&&exit $2
let x=$2+1
for z in `fold -w1<<<$1`
do let y+=$z
done
a $y $x

在线尝试!

应该将其保存为一个脚本,a并将其放置在系统的中PATH,因为它会递归地调用自身。从命令行获取输入,例如a 1999。按退出代码返回。

TIO对脚本的操作有一些限制,因此有一些样板代码可以在标头中运行。

stderr对于大于bash整数可以处理的输入,将错误输出到,但是由于实际计算是使用字符串完成的,因此无论如何仍会给出正确的结果。

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.