Kiên trì phụ gia


20

Mã ngắn nhất để vượt qua tất cả các khả năng chiến thắng.

Trong toán học, sự tồn tại của một số đo lường bao nhiêu lần một hoạt động nhất định phải được áp dụng cho các chữ số của nó cho đến khi đạt được một số điều kiện cố định nhất định. Bạn có thể xác định độ bền phụ gia của một số nguyên dương bằng cách thêm các chữ số của số nguyên và lặp lại. Bạn sẽ tiếp tục thêm các chữ số của tổng cho đến khi tìm thấy một chữ số duy nhất. Số lần lặp lại cần thiết để đạt được số có một chữ số đó là sự tồn tại cộng của số đó.

Ví dụ sử dụng 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.

Bạn sẽ được cung cấp một chuỗi các số nguyên dương mà bạn phải tính toán độ bền của phụ gia. Mỗi dòng sẽ chứa một số nguyên khác nhau để xử lý. Đầu vào có thể trong bất kỳ phương pháp I / O tiêu chuẩn nào .

Đối với mỗi số nguyên, bạn phải xuất số nguyên, theo sau là một khoảng trắng, theo sau là tính bền vững cộng gộp của nó. Mỗi số nguyên được xử lý phải nằm trên dòng riêng của nó.

Các trường hợp thử nghiệm


Đầu ra đầu vào

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

1
Các trường hợp thử nghiệm của bạn bao gồm một số giá trị lớn hơn 2 ^ 64 và thông số kỹ thuật của bạn nói rằng chương trình chỉ phải xử lý các giá trị tối đa 2 ^ 32. Có thể có giá trị rõ ràng lên.
Peter Taylor

@Peter Taylor, quên xóa những giới hạn đó. Nếu một chương trình có thể xử lý đầu vào tôi đã cung cấp, thì nó không có vấn đề gì với các giới hạn.
Kevin Brown

5
Không phải 999999999999 là sự kiên trì 2 thay vì 3?
Eelvex

@Evelex, đó là một thay đổi không chính xác vào phút cuối tôi đoán. Đã sửa.
Kevin Brown

Một số câu trả lời ở đây không thực hiện đầu ra trên thiết bị xuất chuẩn mà thay vào đó sử dụng đầu ra "tương tác" của J bằng cách trả về kết quả sau khi lấy đầu vào dòng lệnh. (Điều này bao gồm 2 câu trả lời J khác và, tôi đoán là câu trả lời K.) Đây có được coi là hợp pháp không? Bởi vì tôi có thể rũ bỏ 18 ký tự nếu vậy.
Jesse Millikan

Câu trả lời:


6

K - 29 ký tự

Đầu vào là một tên tệp được truyền dưới dạng đối số, 29 ký tự không bao gồm tên tệp.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Xóa chức năng bên ngoài.
  • 31 -> 29: Xóa parens.

1
-1+#=>#1_
streetster

4

Python 84 Chars

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

Trường hợp thử thách: 06234.. kết quả thử thách thành công :-)
Quixotic

@Debanjan Cảm ơn. Đã sửa.
fR0DDY


4

Python (93 byte)

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

tôi nghĩ rằng bạn có thể xóa khoảng cách giữa 9và err ...and
st0le

@ st0le: Cảm ơn :-)
Quixotic

input()thay vì int(raw_input())....
st0le

@ st0le: Hãy thử đầu vào này với sửa đổi đó : 06234.
Quixotic

4

Husk , 10 15 byte

+5 byte cho yêu cầu I / O khủng khiếp

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

Hãy thử trực tuyến!

Giải trình

Để hỗ trợ nhiều đầu vào, chúng ta cần sử dụng m(₁r)¶(đâu là hàm thực hiện tính toán thú vị):

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

Hàm này thực hiện như sau:

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 ký tự

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

Hầu như không có môn đánh gôn nào thực sự có liên quan, nhưng tôi không thể thấy cách cải thiện nó.


3

Haskell - 114

s t n|n>9=s(t+1)$sum$map(read.(:[]))$show n|1>0=show t
f n=show n++" "++s 0n++"\n"
main=interact$(f.read=<<).lines

Bạn có thể lưu 4 byte bằng cách sử dụng purehơn (:[])và xác định toán tử thay vì s, thử trực tuyến!
ბიმო

3

Ruby, 85 ký tự

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

Tôi đã phải mượn ý tưởng "tổng kích thước * 48" từ Alex, vì nó quá gọn gàng để bỏ lỡ (ít nhất là trong Ruby).


3

Golf, 40 ký tự

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

3

J - 45 ký tự

Đọc từ stdin

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

Tôi đã cố gắng sử dụng ^:a:bản thân mình nhưng tôi không thể tìm thấy một số tài liệu thích hợp ... bất kỳ gợi ý nào?
Eelvex

1
Mục từ điển cho u ^: n có thông tin về cách sử dụng nhưng nó hơi dày đặc. ^: a: giống như bất kỳ cuộc gọi quyền lực nào khác nhưng nó thu thập kết quả và kết thúc khi đối số cho các cuộc gọi liên tiếp là như nhau (hội tụ).
isawdrones

1
@Eelvex FWIW Tôi đã phát hiện ra a:thông qua ^:a:thủ thuật trong Thẻ tham chiếu J [PDF]
JB

@JB: Đó là tài liệu tham khảo duy nhất ^:a:mà tôi biết: D
Eelvex

@Eelvex ơi. Tôi đã có trải nghiệm ngược lại sau đó. Tôi đã phát hiện ra chức năng trong từ điển và sử dụng nó như một số biến thể ^:(<'')lúc đầu (có lẽ là cho Kaprekar), cho đến khi tôi phát hiện ra nó trong thẻ, và tìm hiểu về a:dịp này.
JB

3

c - 519

(hoặc 137 nếu bạn ghi có cho tôi vào khung ...)

Thay vì chỉ giải quyết một thao tác này, tôi quyết định tạo ra một khung để giải quyết tất cả các vấn đề tồn tại .

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

Chỉ có hai dòng bắt đầu từ char*blà duy nhất cho vấn đề này.

Nó coi đầu vào là các chuỗi, có nghĩa là các số "0" hàng đầu không bị tước trước giai đoạn đầu ra.

Ở trên đã có ý kiến, kiểm tra lỗi và báo cáo và đọc tệp (đầu vào phải đến từ đầu vào tiêu chuẩn) thoát khỏi:

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

Một chút nữa có thể được cứu nếu chúng ta sẵn sàng rò rỉ bộ nhớ như một cái sàng. Tương tự như vậy bằng cách #definequay trở lại và tương tự, nhưng tại thời điểm này tôi không quan tâm để làm cho nó xấu hơn.



2

J, 74 ký tự

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

Chỉnh sửa

  • (86 → 83) Một số mũ [:cho Ats@
  • (83 → 79) Dấu ngoặc đơn không cần thiết
  • (79 → 75) Thay đổi 0".để ".đơn giản hóa mọi thứ
  • (75 → 74) Cắt tốt hơn

Ví dụ

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  

Đầu ra được định dạng sai cho nhiều đầu vào. Xem "không gian duy nhất"
Jesse Millikan

@Jlie: Tôi thấy không có gì sai. Bạn có thể viết một ví dụ xin vui lòng?
Eelvex

Tôi không biết, tôi đang nhìn thấy những điều tôi đoán.
Jesse Millikan

1

Tôi nghĩ rằng đây là về điều tốt nhất tôi có thể đưa ra.

Ruby 101 Chars

f=->(n){n.sum-n.size*48}
$<.each{|l|i=0;i+=1 while(i+=1;n=f[(n||l.chop!).to_s])>10
puts "#{l} #{i}"}

Thật ra, chặt! thay vì chomp! cho tôi một khoản tiết kiệm một ký tự. 97 ký tự.
Alex Bartlow

Chỉ cần chơi gôn nhiều hơn - 91 ký tự.
Alex Bartlow

1

PARI / GP 101 Chars

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

Thật không may, không có chức năng đầu vào cho GP, vì vậy tôi đoán điều này thiếu phần IO. :( Đã sửa : Cảm ơn Eelvex! :)


Chắc chắn là có: input():)
Mười hai

@Eelvex, xong. :)
st0le

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

EDIT: Whoops không làm nhiều dòng


1
Chỉ cần lưu ý điều này không xuất ra nó chính xác.
Kevin Brown

1

J, 78

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

Giải pháp đệ quy. Đọc từ stdin. Viết lên thiết bị xuất chuẩn , vì vậy hãy cắt cho tôi một chút chùng - phải mất thêm 18 ký tự.


1

Perl - 77 ký tự

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

1

JavaScript , 57 47 byte

-10 byte nhờ @ l4m2!

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

Hãy thử trực tuyến!


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

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

@ l4m2 Cảm ơn! s>9evallà những ý tưởng tuyệt vời. Tôi nghĩ rằng bạn đã có thêm một paren trong đó, làm cho nó có tổng cộng 10 byte bạn đã lưu cho tôi :-)
Oliver

Lưu ý I / O nghiêm ngặt;)
Xù xì

1

05AB1E , 13 byte

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

Nhập dưới dạng danh sách các số nguyên.

Hãy thử trực tuyến.

Giải trình:

ε     # 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 byte

hÅ_Σ]▀£(k ?

Hãy thử trực tuyến!

Cực kỳ không hiệu quả, nhưng chúng tôi không quan tâm đến điều đó. Về cơ bản, sử dụng thực tế là độ bền phụ gia của một số nhỏ hơn hoặc bằng chính số đó.

Sử dụng thực tế là sự tồn tại của phụ gia nhỏ hơn hoặc bằng số chữ số của số. Vượt qua tất cả các trường hợp thử nghiệm dễ dàng bây giờ.

Định dạng đầu vào, trong khi tối ưu cho một số ngôn ngữ, thực sự là phương pháp tiêu chuẩn để lấy nhiều trường hợp thử nghiệm làm đầu vào trong MathGolf. Mỗi dòng của đầu vào được xử lý như thực hiện chương trình riêng của nó và đầu ra được phân tách bằng một dòng mới cho mỗi lần thực hiện.

Giải thích (sử dụng 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 byte

Dung dịch:

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

Hãy thử trực tuyến!

Giải trình:

{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)

1

Stax , 8 11 byte

ªwæMε∞ö?îm⌐

Chạy và gỡ lỗi nó

+3 byte nhờ @Khuldraeseth (câu trả lời đầu tiên không có đầu ra tuân thủ)


1
Tôi đã đạt được giải pháp tương tự, nhưng với ivị trí của u. Tuân thủ các thông số kỹ thuật IO hà khắc, điều này trở thành 11 byte .
Khuldraeseth na'Barya

Rất tiếc. Tôi đoán tôi đã không đọc các yêu cầu IO rất tốt. Tôi sẽ cập nhật câu trả lời của tôi.
đệ quy

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 byte

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

0

Tcl , 95 byte

proc P {v n\ 0} {set V $v
while \$v>9 {set v [expr [join [split $v ""] +]]
incr n}
puts $V\ $n}

Hãy thử trực tuyến!


3
Bởi vì câu trả lời mới nhất tiếp theo là một đứa trẻ đủ 6 tuổi, mà tôi nghĩ là trước khi TIO tồn tại
fnɛtɪk

0

Japt , 28 byte

Ë+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.

Hãy thử trực tuyến!


0

PHP, 72 + 1 byte

+1 cho -Rcờ.

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

Chạy như ống với -R.

  • chạy PHP dưới dạng ống sẽ thực thi mã một lần cho mỗi dòng đầu vào
  • nhưng nó không bỏ đặt các biến giữa; do đó $iphải được khởi tạo.
    (Ngoài ra, nó sẽ không in gì thay vì các 0chữ số đơn lẻ mà không khởi tạo.)

0

Bash + coreutils, 83 byte

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

Hãy thử trực tuyến!

Nên được lưu vào một tập lệnh được gọi avà đặt trong hệ thống PATH, vì nó tự gọi nó theo cách đệ quy. Lấy đầu vào từ dòng lệnh, như a 1999. Trả về bằng mã thoát.

TIO có một số hạn chế về những gì bạn có thể làm với một tập lệnh, do đó, có một số mã soạn sẵn để thực hiện điều này trong tiêu đề.

In một lỗi để stderrđầu vào lớn hơn số nguyên bash có thể xử lý, nhưng vì tính toán thực tế được thực hiện bằng chuỗi, dù sao nó vẫn cho kết quả đúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.