ความคงทนต่อสารเติมแต่ง


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

@ Peter Taylor ลืมที่จะลบขีด จำกัด เหล่านั้น หากโปรแกรมสามารถจัดการอินพุตที่ฉันได้จัดเตรียมไว้มันไม่ควรมีปัญหากับข้อ จำกัด
เควินบราวน์มี. ค.

5
การคงอยู่ของ 2 999999999999 ไม่ใช่ 3 หรือไม่?
Eelvex

@Evelex นั่นเป็นการเปลี่ยนแปลงในนาทีสุดท้ายที่ไม่ถูกต้องฉันเดา แก้ไขแล้ว.
Kevin Brown

คำตอบมากมายที่นี่ไม่ได้ทำเอาต์พุตบน stdout แต่ควรใช้เอาต์พุต "แบบโต้ตอบ" ของ J โดยส่งคืนผลลัพธ์หลังจากรับอินพุตบรรทัดคำสั่ง (ซึ่งรวมถึง 2 คำตอบ J อื่น ๆ และฉันคาดเดาคำตอบ K) นี่ถือว่าถูกต้องหรือไม่ เพราะฉันสามารถหลั่ง 18-ish ตัวละครถ้าเป็นเช่นนั้น
Jesse Millikan

คำตอบ:


6

K - 29 ตัวอักษร

อินพุตเป็นชื่อไฟล์ที่ส่งผ่านเป็นอาร์กิวเมนต์ 29 ตัวอักษรไม่รวมถึงชื่อไฟล์

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: ลบฟังก์ชั่นภายนอก
  • 31 -> 29: ลบ parens

1
-1+#=>#1_
roadster

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


4

Python (93 ไบต์)

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)

ฉันคิดว่าคุณสามารถลบช่องว่างระหว่าง9และ err ...and
st0le

@ st0le: ขอบคุณ :-)
Quixotic

และinput()แทนที่จะเป็นint(raw_input())....
st0le

@ st0le: 06234ลองป้อนข้อมูลนี้มีการดัดแปลงที่:
Quixotic

4

Husk , 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

ทุบตี 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 Chars

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

ฉันต้องขอยืมแนวคิด "sum-size * 48" จาก Alex เพราะมันเป็นเรื่องง่ายเกินกว่าจะพลาด (ใน Ruby อย่างน้อย)



3

J - 45 ตัวอักษร

อ่านจาก stdin

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

ฉันพยายามใช้^:a:ตัวเอง แต่ไม่พบเอกสารที่เหมาะสม ... คำใบ้ใด ๆ ?
Eelvex

1
รายการพจนานุกรมสำหรับ U ^: nมีข้อมูลเกี่ยวกับการใช้งานของมัน แต่มันก็เป็นความหนาแน่นบิต ^: a: เป็นเหมือนการโทรเพื่อรับสายอื่น ๆ แต่จะรวบรวมผลลัพธ์และสิ้นสุดลงเมื่ออาร์กิวเมนต์สำหรับการโทรติดต่อกันเป็นแบบเดียวกัน (มาบรรจบกัน)
isawdrones

1
@Eelvex FWIW ผมค้นพบa:ผ่าน^:a:เคล็ดลับในJ บัตรอ้างอิง [PDF]
JB

@JB: นั่นเป็นเพียงการอ้างอิงเดียวกับ^:a:ที่ฉันรู้: D
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" s ไม่ได้ตัดออกก่อนขั้นตอนการส่งออก

ด้านบนมีความคิดเห็นการตรวจสอบข้อผิดพลาดและการรายงานและการอ่านไฟล์ (อินพุตต้องมาจากอินพุตมาตรฐาน) สไทรพ์จาก:

/* 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กลับมาและชอบ แต่ ณ จุดนี้ฉันไม่สนใจที่จะทำให้มันน่าเกลียดใด ๆ



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  

เอาต์พุตมีรูปแบบไม่ถูกต้องสำหรับอินพุตหลายอินพุต ดูที่ "single space"
Jesse Millikan

@Jesse: ฉันเห็นอะไรผิดปกติ คุณช่วยเขียนตัวอย่างได้ไหม
Eelvex

ฉันไม่มีความคิดฉันเห็นสิ่งที่ฉันเดา
Jesse Millikan

1

ฉันคิดว่านี่เป็นสิ่งที่ดีที่สุดที่ฉันสามารถทำได้

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}"}

อันที่จริงสับ! แทนการ chomp! ทำให้ฉันประหยัดตัวละครตัวหนึ่ง 97 ตัวอักษร
Alex Bartlow

เพิ่งเล่นกอล์ฟเพิ่มอีก - 91 ตัวอักษร
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)))

น่าเสียดายที่ไม่มีฟังก์ชั่นอินพุตสำหรับ GP ดังนั้นฉันเดาว่านี่ขาดส่วน IO :( แก้ไข: ขอบคุณ Eelvex! :)


แน่นอนว่ามี: input():)
Eelvex

@ สิบสองเสร็จแล้ว :)
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);

แก้ไข: อ๊ะไม่ได้ทำหลายบรรทัด


1
เพิ่งสังเกตเห็นว่ามันไม่ได้ส่งออกอย่างถูกต้อง
Kevin Brown

1

J, 78

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

โซลูชันแบบเรียกซ้ำ อ่านจาก stdin เขียนไปที่ stdoutดังนั้นลดความหย่อนลงหน่อย - ใช้เวลาเพิ่มอีก 18 ตัวอักษร



1

JavaScript , 57 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

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

@ l4m2 ขอบคุณ! s>9และevalเป็นความคิดที่ดี ฉันคิดว่าคุณมีวงเล็บพิเศษในที่นั่นทำให้มันรวมเป็น 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)

1

Stax , 8 11 ไบต์

ªwæMε∞ö?îm⌐

เรียกใช้และแก้ไขข้อบกพร่อง

+3 ไบต์ขอบคุณ @Khuldraeseth (คำตอบแรกไม่มีเอาต์พุตที่สอดคล้อง)


1
ฉันถึงวิธีการแก้ปัญหาเดียวกัน แต่มีในสถานที่ของi uยึดมั่นในข้อกำหนด IO เข้มงวดนี้จะกลายเป็น11 ไบต์
Khuldraeseth na'Barya

อุ่ย ฉันเดาว่าฉันไม่ได้อ่านข้อกำหนดของ IO เป็นอย่างดี ฉันจะอัปเดตคำตอบของฉัน
เรียกซ้ำ



0

Java (OpenJDK 8) , 79 ไบต์

a->{int d=0;while(a/10>0){int c=0;d++;while(a>0){c+=a%10;a/=10;}a=c;}return d;}

ลองออนไลน์!

มีแนวโน้มที่จะเป็นไปได้ที่จะเล่นกอล์ฟต่อไป แต่ฉันจะพิจารณาเรื่องนี้ในอนาคต แต่สำหรับตอนนี้ฉันค่อนข้างมีความสุขกับผลลัพธ์เล็กน้อยนี้


1
70 ไบต์
Jonathan Frech

อาคารใน
@JonathanFrech




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 ที่สามารถจัดการได้ แต่เนื่องจากการคำนวณจริงทำด้วยสตริงจึงยังคงให้ผลลัพธ์ที่ถูกต้องอยู่ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.