Ketekunan Aditif

20

Kode terpendek untuk lulus semua kemungkinan menang.

Dalam matematika, kegigihan angka mengukur berapa kali operasi tertentu harus diterapkan pada digitnya sampai beberapa kondisi tetap tertentu tercapai. Anda dapat menentukan ketekunan aditif dari bilangan bulat positif dengan menambahkan digit bilangan bulat dan mengulangi. Anda akan terus menambahkan digit jumlah hingga satu digit angka ditemukan. Jumlah pengulangan yang diperlukan untuk mencapai angka satu digit itu adalah ketekunan aditif dari angka itu.

Contoh menggunakan 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.

Anda akan diberi urutan bilangan bulat positif yang harus Anda hitung dari persistensi aditif. Setiap baris akan berisi bilangan bulat yang berbeda untuk diproses. Input dapat dalam metode I / O standar apa pun .

Untuk setiap bilangan bulat, Anda harus menampilkan bilangan bulat, diikuti oleh satu spasi, diikuti dengan ketekunan aditif. Setiap bilangan bulat yang diproses harus pada jalurnya sendiri.

Uji Kasus


Input output

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0
Kevin Brown
sumber
1
Kasing uji Anda menyertakan beberapa nilai yang lebih dari 2 ^ 64, dan spek Anda mengatakan bahwa program hanya perlu menangani nilai hingga 2 ^ 32. Mungkin layak untuk membersihkannya.
Peter Taylor
@ Peter Taylor, lupa untuk menghapus batas-batas itu. Jika suatu program dapat menangani input yang saya berikan, seharusnya tidak ada masalah dengan batasan.
Kevin Brown
5
Bukankah kegigihan 999999999999 2 bukannya 3?
Eelvex
@ Evelex, itu adalah perubahan menit terakhir yang salah kurasa. Tetap.
Kevin Brown
Beberapa jawaban di sini tidak melakukan output pada stdout tetapi menggunakan output "interaktif" J dengan mengembalikan hasil setelah mengambil input baris perintah. (Ini termasuk 2 jawaban J lainnya dan, saya kira, jawaban K.) Apakah ini dianggap sah? Karena saya bisa menumpahkan karakter 18-ish jika demikian.
Jesse Millikan

Jawaban:

6

K - 29 Chars

Input adalah nama file yang diteruskan sebagai argumen, 29 karakter tidak termasuk nama file.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Hapus fungsi luar.
  • 31 -> 29: Hapus parens.
isawdrones
sumber
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
fR0DDY
sumber
Kasus tantangan: 06234.. hasilkan tantangan yang berhasil :-)
Quixotic
@ Debanjan Terima kasih. Dikoreksi.
fR0DDY
4

Haskell, 100 karakter

p[d]=0
p d=1+(p.show.sum$map((-48+).fromEnum)d)
f n=n++' ':shows(p n)"\n"
main=interact$(f=<<).lines
MtnViewMark
sumber
Anda dapat menyimpan 6 byte dengan menggunakan read.purealih-alih (-48+).fromEnum, coba online!
ბიმო
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)
Pemurah
sumber
saya pikir Anda dapat menghapus ruang antara 9dan err ...and
st0le
@ st0le: Terima kasih :-)
Quixotic
dan input()bukannya int(raw_input())....
st0le
@ st0le: Coba masukan ini dengan modifikasi bahwa: 06234.
Quixotic
4

Sekam , 10 15 byte

+5 byte untuk persyaratan I / O yang mengerikan

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

Cobalah online!

Penjelasan

Untuk mendukung banyak input, kita perlu menggunakan m(₁r)¶(di mana fungsi melakukan perhitungan yang menarik):

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

Fungsi melakukan hal berikut:

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"
ბიმო
sumber
3

bash, 105 karakter

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

Hampir tidak ada golf yang terlibat, tetapi saya tidak bisa memperbaikinya.

Peter Taylor
sumber
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
Joey Adams
sumber
Anda dapat menyimpan 4 byte dengan menggunakan purelebih dari (:[])dan mendefinisikan operator alih-alih s, coba online!
ბიმო
3

Ruby, 85 Karakter

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

Saya harus meminjam ide "jumlah * 48" dari Alex, karena terlalu rapi untuk dilewatkan (setidaknya di Ruby).

Ezran
sumber
3

Golfscript, 40 karakter

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

J - 45 Chars

Baca dari stdin

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3
isawdrones
sumber
Saya mencoba menggunakan ^:a:diri saya sendiri tetapi saya tidak dapat menemukan dokumentasi yang tepat ... ada petunjuk?
Eelvex
1
The isi kamus untuk u ^: n memiliki info tentang penggunaannya tapi itu adalah padat sedikit. ^: a: seperti panggilan ke kekuasaan lainnya, tetapi mengumpulkan hasil dan berakhir ketika argumen untuk panggilan berurutan adalah sama (konvergen).
isawdrones
1
@Eelvex FWIW Saya menemukan a:melalui ^:a:trik di Kartu Referensi J [PDF]
JB
@ JK: Itu satu-satunya referensi ^:a:yang saya tahu: D
Eelvex
@Eelvex Oh. Saya memiliki pengalaman sebaliknya. Saya menemukan fungsi dalam kamus, dan menggunakannya sebagai beberapa varian ^:(<'')pada awalnya (mungkin untuk Kaprekar), sampai saya melihatnya di kartu, dan belajar tentang a:kesempatan itu.
JB
3

c - 519

(atau 137 jika Anda menghargai saya untuk kerangka kerja ...)

Daripada menyelesaikan operasi yang satu ini saja, saya memutuskan untuk menghasilkan kerangka kerja untuk menyelesaikan semua masalah kegigihan .

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

Hanya dua baris mulai dari char*byang unik untuk masalah ini.

Ini memperlakukan input sebagai string, yang berarti bahwa memimpin "0" tidak strip sebelum tahap output.

Di atas memiliki komentar, pengecekan dan pelaporan kesalahan, dan pembacaan file (input harus berasal dari input standar) dihapus dari:

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

Sedikit lagi bisa diselamatkan jika kita mau membocorkan memori seperti saringan. Demikian juga dengan #definepengembalian dan sejenisnya, tetapi pada titik ini saya tidak peduli untuk membuatnya lebih buruk.

dmckee
sumber
273 byte
ceilingcat
2

J, 74 karakter

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

Suntingan

  • (86 → 83) Some Caps [:to Ats@
  • (83 → 79) Kurung yang tidak dibutuhkan
  • (79 → 75) Mengubah 0".untuk ".menyederhanakan hal-hal
  • (75 → 74) Pemotongan yang Lebih Baik

Misalnya

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  
Eelvex
sumber
Output diformat salah untuk beberapa input. Lihat "ruang tunggal"
Jesse Millikan
@Jesse: Saya melihat tidak ada yang salah. Bisakah Anda menulis contoh?
Eelvex
Saya tidak tahu, saya melihat hal-hal yang saya kira.
Jesse Millikan
1

Saya pikir ini tentang yang terbaik yang bisa saya dapatkan.

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}"}
Alex Bartlow
sumber
Sebenarnya, potong! bukannya chomp! memberi saya penghematan satu karakter. 97 karakter.
Alex Bartlow
Baru saja bermain golf lagi - 91 karakter.
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)))

Sayangnya, tidak ada fungsi input untuk GP, jadi saya kira ini tidak memiliki bagian IO. :( Tetap: Terima kasih Eelvex! :)

st0le
sumber
Tentu ada: input():)
Eelvex
@Eelvex, selesai. :)
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 tidak melakukan multi-baris

t123
sumber
1
Hanya perhatikan ini tidak menghasilkan dengan benar.
Kevin Brown
1

J, 78

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

Solusi rekursif. Baca dari stdin. Menulis ke stdout , jadi kurangi sedikit - butuh 18 karakter tambahan.

Jesse Millikan
sumber
1

Perl - 77 karakter

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

JavaScript , 57 47 byte

-10 byte terima kasih kepada @ l4m2!

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

Cobalah online!

Oliver
sumber
f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
14m2
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 Terima kasih! s>9dan evalide-ide bagus. Saya pikir Anda memiliki paren tambahan di sana, sehingga total 10 byte Anda menyelamatkan saya :-)
Oliver
Perhatikan I / O yang ketat;)
Shaggy
1

05AB1E , 13 byte

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

Input sebagai daftar bilangan bulat.

Cobalah online.

Penjelasan:

ε     # 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)
Kevin Cruijssen
sumber
1

MathGolf , 11 byte

hÅ_Σ]▀£(k ?

Cobalah online!

Sangat tidak efisien, tapi kami tidak peduli soal itu. Pada dasarnya, menggunakan fakta bahwa persistensi aditif dari suatu bilangan lebih kecil dari atau sama dengan bilangan itu sendiri.

Menggunakan fakta bahwa ketekunan aditif kurang dari atau sama dengan jumlah digit angka. Lewati semua test case dengan mudah sekarang.

Format input, sementara suboptimal untuk beberapa bahasa, sebenarnya adalah metode standar untuk mengambil beberapa test case sebagai input dalam MathGolf. Setiap baris input diproses sebagai eksekusi programnya sendiri, dan output dipisahkan oleh satu baris baru untuk setiap eksekusi.

Penjelasan (menggunakan 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)
maks
sumber
1

K (ngn / k) , 16 byte

Larutan:

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

Cobalah online!

Penjelasan:

{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)
streetster
sumber
1

Stax , 8 11 byte

ªwæMε∞ö?îm⌐

Jalankan dan debug itu

+3 byte berkat @Khuldraeseth (jawaban pertama tidak memiliki keluaran yang sesuai)

rekursif
sumber
1
Saya mencapai solusi yang sama, tetapi dengan imenggantikan u. Mengikuti spesifikasi IO yang kejam, ini menjadi 11 byte .
Khuldraeseth na'Barya
Ups. Saya kira saya tidak membaca persyaratan IO dengan sangat baik. Saya akan memperbarui jawaban saya.
Rekursif
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)))
Pengguna tidak diketahui
sumber
0

Java (OpenJDK 8) , 79 byte

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

Cobalah online!

Mungkin ada potensi untuk bermain golf lebih jauh, tapi saya akan melihat itu di masa depan, tetapi untuk sekarang, saya cukup senang dengan hasil kecil ini.

X1M4L
sumber
1
70 byte .
Jonathan Frech
Membangun @JonathanFrech 67 byte
ceilingcat
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)))
PieCot
sumber
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}

Cobalah online!

sergiol
sumber
3
Karena jawaban terbaru berikutnya adalah 6 tahun penuh, yang saya pikir sebelum TIO ada
fəˈnɛ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.

Cobalah online!

Nit
sumber
0

PHP, 72 +1 byte

+1 untuk -Rbendera.

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

Jalankan sebagai pipa dengan -R.

  • menjalankan PHP sebagai pipa akan mengeksekusi kode sekali untuk setiap baris input
  • tetapi tidak membatalkan variabel antara; jadi $iharus diinisialisasi.
    (Juga, itu tidak akan mencetak apa pun selain 0untuk digit tunggal tanpa inisialisasi.)
Titus
sumber
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

Cobalah online!

Harus disimpan ke skrip yang dipanggil adan ditempatkan di sistem PATH, karena itu menyebut dirinya secara rekursif. Mengambil input dari baris perintah, seperti a 1999. Kembali dengan kode keluar.

TIO memiliki beberapa batasan pada apa yang dapat Anda lakukan dengan skrip, jadi ada beberapa kode boilerplate untuk menjalankan ini di header.

Mencetak kesalahan ke stderruntuk input yang lebih besar daripada yang bisa ditangani bash integer, tetapi karena perhitungan sebenarnya dilakukan dengan string, tetap saja memberikan hasil yang benar.

Chris
sumber