付加的な永続性


20

すべての可能性を渡す最短のコードが勝ちです。

数学では、数値持続性は、特定の一定の条件に達するまで特定の操作をその数字に適用する必要がある回数を測定します。整数の桁を追加して繰り返すことにより、正の整数の相加持続性を決定できます。1桁の数字が見つかるまで、合計の数字を追加し続けます。その1桁の数字に達するまでにかかった繰り返しの回数は、その数字の付加的な持続性です。

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の永続性は3ではなく2ではありませんか?
エルベックス

@Evelex、それは間違った土壇場の変更だったと思う。一定。
ケビンブラウン

ここでのいくつかの答えは、stdoutでの出力ではなく、コマンドライン入力を取得した後に結果を返すことでJの「インタラクティブ」出力を使用しています。(これには、他の2つのJの回答と、Kの回答が含まれます。)これは合法と見なされますか?もしそうなら、私は18のようなキャラクターを流すことができるからです。
ジェシーミリカン

回答:


6

K-29文字

入力は、引数として渡されるファイル名で、ファイル名を含まない29文字です。

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35-> 31:外部機能を削除します。
  • 31-> 29:括弧を削除します。

1
-1+#=>#1_
ストリートスター

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

そしてinput()代わりにint(raw_input())...
st0le

@ st0le:その変更でこの入力を試してください:06234
キクソチック

4

10 15バイト

恐ろしいI / O要件の場合は+5バイト

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

ルビー、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:自分を使おうとしていましたが、適切なドキュメントが見つかりませんでした...ヒントはありますか?
エルベックス

1
u ^:nディクショナリエントリには、その使用法に関する情報がありますが、少し密集しています。^:a:他のpowerの呼び出しと同様ですが、結果を収集し、連続した呼び出しの引数が同じ(収束)になったときに終了します。
-isawdrones

1
@Eelvex FWIW私は発見しa:^:a:中にトリックJリファレンスカード [PDF]
JB

@JB:それ^:a:は私が知っていることの唯一の参照です:D
Eelvex

@Eelvexああ。その時、私は反対の経験をしました。辞書で機能を発見し、^:(<'')最初に(おそらくKaprekarの)バリアントとして使用しましたが、カードで見つけてa:その機会について学びました。
JB

3

c-519

(またはフレームワークを私に信用している場合は137 ...)

この1つの操作だけを解決するのではなく、すべての永続性の問題を解決するためのフレームワークを作成することにしました。

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

から始まる2行のみが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;
  }
}

ふるいのようにメモリをリークしたい場合は、もう少し節約できます。同様に#definereturnなどを実行しますが、この時点で私はそれをanyいものにしたいとは思いません。



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  

複数の入力に対して出力のフォーマットが間違っています。「シングルスペース」
ジェシーミリカン

@ジェシー:私は間違って何も見ない。例を書いていただけますか?
エルベックス

私にはわからない、私は推測するものを見ている。
ジェシーミリカン


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、できました。:)
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
これが正しく出力しないことに気づいただけです。
ケビンブラウン

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バイト

@ l4m2のおかげで-10バイト!

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で入力として複数のテストケースを使用する標準的な方法です。入力の各行は独自のプログラム実行として処理され、出力は実行ごとに1つの改行で区切られます。

説明(を使用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

スタックス8 11 バイト

ªwæMε∞ö?îm⌐

実行してデバッグする

@Khuldraesethのおかげで+3バイト(最初の回答には準拠した出力がありませんでした)


1
私は同じ解決策に到達しましたがi、の代わりにu。厳格なIO仕様に従って、これは11バイトになります
Khuldraeseth na'Barya

おっとっと。IO要件をあまりよく読んでいないと思います。回答を更新します。
再帰的

0

スカラ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バイト

-Rフラグに+1 。

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

でパイプとして実行し-Rます。

  • PHPをパイプとして実行すると、入力行ごとにコードが1回実行されます
  • ただし、その間の変数の設定は解除されません。$i初期化する必要があります。
    (また、0初期化なしの1桁の代わりに何も出力しません。)

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には、スクリプトで実行できることに関していくつかの制限があるため、ヘッダーでこれを実行するための定型コードがいくつかあります。

stderrbash整数で処理できる以上の入力に対してエラーを出力しますが、実際の計算は文字列を使用して行われるため、とにかく正しい結果が得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.