Katkı Kalıcılığı


20

Tüm olasılıkları geçecek en kısa kod kazanır.

Matematikte, bir sayının kalıcılığı, belirli bir sabit duruma ulaşılana kadar belirli bir işlemin basamaklarına kaç kez uygulanması gerektiğini ölçer. Tamsayının rakamlarını ekleyerek ve yineleyerek pozitif bir tamsayının toplam kalıcılığını belirleyebilirsiniz. Tek basamaklı bir sayı bulunana kadar toplamın rakamlarını eklemeye devam edersiniz. Bu tek haneli sayıya ulaşmak için gereken tekrar sayısı, bu sayının toplam kalıcılığıdır.

84523 kullanan örnek:

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.

Katkı kalıcılığını hesaplamanız gereken bir pozitif tamsayı dizisi verilecektir . Her satırda işlemek için farklı bir tamsayı bulunur. Giriş herhangi bir standart I / O yönteminde olabilir .

Her tamsayı için, tamsayıyı, ardından tek bir boşluk ve ardından ek kalıcılığını vermelisiniz. İşlenen her tam sayı kendi satırında olmalıdır.

Test Durumları


Giriş çıkış

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

1
Test durumlarınız 2 ^ 64 üzerinde bazı değerler içerir ve spesifikasyonunuz programın sadece 2 ^ 32'ye kadar değerleri işlemesi gerektiğini söyler. Bunu temizlemeye değer olabilir.
Peter Taylor

@Peter Taylor, bu sınırları kaldırmayı unuttu. Bir program sağladığım girdiyi işleyebiliyorsa, sınırlarla ilgili bir sorunu olmamalıdır.
Kevin Brown

5
999999999999 3 yerine kalıcılığı 2 değil mi?
Eelvex

@Evelex, bu yanlış bir son dakika değişikliği sanırım. Sabit.
Kevin Brown

Buradaki bazı cevaplar stdout'ta çıktı yapmıyor, bunun yerine komut satırı girdisini aldıktan sonra sonuçları döndürerek J'nin "etkileşimli" çıktısını kullanıyor. (Bu, diğer 2 J yanıtı ve tahmin ediyorum ki, K yanıtı içerir.) Bu yasal mıdır? Çünkü eğer öyleyse 18-ish karakter atabilirim.
Jesse Millikan

Yanıtlar:


6

K - 29 Karakter

Girdi, argüman olarak iletilen bir dosya adı, dosya adı içermeyen 29 karakter.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Dış işlevi kaldır.
  • 31 -> 29: Parentleri çıkarın.

1
-1+#=>#1_
streetster

4

Python 84 Karakterleri

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

Meydan okuma örneği: 06234.. başarılı bir meydan okuma sonucu :-)
Quixotic

@Debanjan Teşekkürler. Düzeltildi.
fR0DDY


4

Python (93 bayt)

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)

sanırım 9ve err arasındaki boşluğu kaldırabilirsiniz ...and
st0le 26:11

@ st0le: Teşekkürler :-)
Quixotic

ve input()yerine int(raw_input())....
st0le

@ st0le: değişikliği ile bu girişi deneyin: 06234.
Quixotic

4

Kabuk , 10 15 bayt

Korkunç I / O gereksinimi için +5 bayt

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

Çevrimiçi deneyin!

açıklama

Birden fazla girişi desteklemek için kullanmamız gerekir m(₁r)¶( ilginç hesaplamayı yapan işlev nerede ):

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

İşlev aşağıdakileri yapar:

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

Hemen hemen hiç golf aslında dahil, ama nasıl geliştirmek için göremiyorum.


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

Sen kullanarak 4 bayt kaydedebilirsiniz pureüzerinde (:[])ve yerine bir operatör tanımlayan s, bunu çevrimiçi deneyin!
ბიმო

3

Yakut, 85 Karakter

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

Alex'ten "toplam boyutu * 48" fikrini ödünç almak zorunda kaldım, çünkü kaçırmak için çok düzgün (en azından Ruby'de).


3

Golfscript, 40 karakter

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

3

J - 45 Karakter

Stdin'den okumalar

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

^:a:Kendimi kullanmaya çalışıyordum ama bazı uygun belgeler bulamadım ... herhangi bir ipucu?
Eelvex

1
U için sözlüğe giriş ^: n kullanımıyla ilgili bilgi vardır ama biraz yoğun. ^: a: diğer herhangi bir güç çağrısı gibidir, ancak sonuçları toplar ve ardışık çağrıların argümanı aynı olduğunda (yakınsak) sona erer.
isawdrones

1
@Eelvex FWIW keşfetti a:aracılığıyla ^:a:içinde hile J Referans Kartı [PDF]
JB

@JB: Bildiğim tek referans ^:a:bu: D
Eelvex

@Eelvex Oh. O zaman tam tersi bir deneyim yaşadım. Sözlükteki işlevselliği keşfettim ve ^:(<'')ilk başta (muhtemelen Kaprekar için) bir çeşit varyant olarak kullandım , kartta görene a:ve durum için öğrendim .
JB

3

c - 519

(veya çerçeve için bana kredi verirseniz 137 ...)

Sadece bu tek operasyonu çözmek yerine, tüm kalıcılık sorunlarını çözmek için bir çerçeve üretmeye karar verdim .

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

Yalnızca iki satır char*b bu soruna özgüdür.

Girişi dize olarak ele alır, yani önde gelen "0" lar çıkış aşamasından önce şerit değildir.

Yukarıdaki açıklamalar, hata kontrolü ve raporlaması ve dosya okuması (girdi standart girdiden gelmelidir) aşağıdakilerden çıkarılmıştır:

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

Bir elek gibi hafızayı sızdırmaya istekli olsaydık biraz daha tasarruf edilebilirdi. Aynı şekilde #definedönüş ve benzeri ing, ama bu noktada daha çirkin yapmak umurumda değil.



2

J, 74 karakter

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

Düzenlemeler

  • (86 → 83) Bazı Caps [:-Ats@
  • (83 → 79) Gereksiz parantezler
  • (→ 75 79) değiştirilmesi 0".için ".basitleştirir şeyler
  • (75 → 74) Daha İyi Kesme

Örneğin

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  

Çıkış, birden çok giriş için yanlış biçimlendirilmiş. "Tek boşluk"
Jesse Millikan

@ Jesse: Yanlış bir şey görmüyorum. Lütfen bir örnek yazabilir misiniz?
Eelvex

Hiçbir fikrim yok, tahmin ettiğim şeyleri görüyorum.
Jesse Millikan

1

Bence bu, gelebileceğim en iyilerle ilgili.

Yakut 101 Karakter

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

Aslında doğrayın! chomp yerine! bana bir karakter kazandırıyor. 97 karakter.
Alex Bartlow

Biraz daha golf yaptım - 91 karakter.
Alex Bartlow

1

PARI / GP 101 Karakterleri

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

Ne yazık ki, GP için hiçbir giriş işlevi yoktur, bu yüzden bu IO kısmı eksik sanırım. :( Sabit: Teşekkürler Eelvex! :)


Tabii var: input():)
Eelvex

@Eelvex, bitti. :)
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 çok satırlı yapmaz


1
Sadece bunun doğru çıktı olmadığını fark ettim.
Kevin Brown

1

J, 78

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

Özyinelemeli çözüm. Stdin'den okur. Stdout'a yazıyor , bu yüzden beni biraz gevşetin - ekstra 18-ish karakter gerektiriyor.


1

Perl - 77 karakter

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

1

JavaScript , 57 47 bayt

@ L4m2 sayesinde -10 bayt!

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

Çevrimiçi deneyin!


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 Teşekkürler! s>9ve evalharika fikirlerdi. Sanırım orada fazladan bir paren vardı, beni kurtardın toplam 10 bayt :-)
Oliver

Sıkı I / O'ya dikkat edin;)
Shaggy

1

05AB1E , 13 bayt

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

Tamsayıların bir listesi olarak girin.

Çevrimiçi deneyin.

Açıklama:

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

hÅ_Σ]▀£(k ?

Çevrimiçi deneyin!

İnanılmaz derecede verimsiz, ama bunu umursamıyoruz. Temel olarak, bir sayının toplam kalıcılığının sayının kendisinden küçük veya ona eşit olması gerçeğini kullanarak.

Ek kalıcılığın sayının basamak sayısından küçük veya ona eşit olduğu gerçeğini kullanır. Tüm test senaryolarını kolaylıkla geçiyor.

Giriş biçimi, bazı diller için yetersiz olsa da, aslında MathGolf'da birden çok test vakasını girdi olarak almanın standart yöntemidir. Girdinin her satırı kendi program yürütmesi olarak işlenir ve çıktı her yürütme için tek bir yeni satırla ayrılır.

Açıklama (kullanma 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 bayt

Çözüm:

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

Çevrimiçi deneyin!

Açıklama:

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

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

0

Tcl , 95 bayt

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

Çevrimiçi deneyin!


3
Bir sonraki en yeni cevap tam 6 yaşında, çünkü TIO var olmadan önce olduğunu düşünüyorum
fəˈnɛtɪk

0

Japt , 28 bayt

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

Çevrimiçi deneyin!


0

PHP, 72 + 1 bayt

-RBayrak için +1 .

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

İle boru olarak çalıştırın -R.

  • PHP'yi dikey olarak çalıştırmak, kodu her giriş satırı için bir kez yürütür
  • ancak aradaki değişkenleri belirlemez; bu yüzden $ibaşlatılmalıdır.
    (Ayrıca, 0başlatma olmadan tek basamak yerine hiçbir şey yazdırmaz .)

0

Bash + coreutils, 83 bayt

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

Çevrimiçi deneyin!

Özyinelemeli olarak adlandırdığı aiçin sisteme çağrılan ve yerleştirilen bir komut dosyasına kaydedilmelidir PATH. Gibi komut satırından girdi alır a 1999. Çıkış koduna göre döner.

TIO'nun bir komut dosyasıyla yapabileceklerinizle ilgili bazı sınırlamaları vardır, bu nedenle bunu başlıkta çalıştırmak için bazı ortak kod kodu vardır.

stderrBash tamsayılarının işleyebileceğinden daha büyük giriş için bir hata yazdırır , ancak gerçek hesaplama dizelerle yapıldığından yine de doğru sonucu verir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.