スペースを節約するために整数を折りたたみます!


20

クレイジーな数学者は幅広い数のコレクションを所有しているため、彼が残したスペースはかなり限られています。いくらかを節約するために、彼は整数を折り畳まなければなりませんが、残念ながら彼は本当に怠け者です。あなたが彼を助けたいなら、あなたの仕事は、私たちの数マニアックのために与えられた正の整数を折り畳む関数/プログラムを作成することです。

整数の折り方

数字の合計で均等に割り切れる場合は、数字の合計で割ります。その要件を満たさない場合は、その桁数の合計で割ったときに残りを取ります。結果がに達するまでプロセスを繰り返します1。折り畳まれた整数は、実行する必要があった操作の数です。例を見てみましょう(たとえば1782):

  1. その桁の合計を取得します1 + 7 + 8 + 2 = 181782はで割り切れる18ので、次の数字は1782 / 18 = 99です。

  2. 99はで割り切れない9 + 9 = 18ため、残りを取ります:99 % 18 = 9

  3. 9は明らかにで割り切れる9ので、それを分割して取得し1ます。

結果は3、到達するために3つの操作が必要であったからです1

ルールと仕様

  • 一部の整数の桁数の合計は110またはなど100です。あなたのプログラムはそのような場合に対処する必要はありません。つまり、入力として指定された整数の桁数の合計がに等しくないことが保証され、指定された整数を使用した1操作では、桁数の合計が得られません11それ自体は例外で、ターゲット")。たとえば、入力として、10または受信することはありません20

  • 入力はより大きい正の整数になり1ます。

  • デフォルトの抜け穴が適用されます。

  • 入力を取得し、標準的な平均値で出力を提供できます。


テストケース

入力->出力

2-> 1
5-> 1
9-> 1
18-> 2
72-> 2
152790-> 2
152-> 3
666-> 3
777-> 3
2010-> 3
898786854-> 4

プロセスを視覚化し、さらにテストケースを試すことができるプログラムを次に示します。


これはなので、各言語で最も短いコード(バイト単位)が勝ちます!


この課題触発されましたが、最初は関連していないように見えますが。
ミスターXcoder

3
これは一時的な解決策として機能しますが、長期的には、数学者はHilbertのホテルの 1つを実際に購入することを検討する必要があります。それらのいずれかで、未使用の部屋をいつでも見つけることができます。
レイ

一方、8987868546有効な入力がある、それはあなたのテストツールを破る、と回答のも、多くの(すべてではない)...う
ミーシャ

@MischaBehrendあなたの例は有効な入力ではありません。私の最後のテストケースを誤ってコピーしたと思います。有効な入力は898786854でした89878685466最後にa を追加しました)
Mr. Xcoder

nvm ... 最初のルール全体を読む必要があります... これをここに残して、なぜ私がそれが有効であると思ったのかを知っている:それは間違いではなかった...これらのスクリプトをテストするために意図的に変更しました...そしてルールを読んである有効な入力。のすべての数字の合計は8987868546 1(ルール1に適合)では8987868546なく、1(ルール2に適合)よりも大きい正の整数です。
ミーシャ

回答:


6

05AB1E13 12バイト

[¼DSO‰0Kθ©#®

オンラインでお試しください!

説明

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter

6

パイソン263の 57バイト

-1完全に人間に
感謝-1 Mr. Xcoderに
感謝-4 reffuに感謝

def f(n):a=sum(map(int,`n`));return n>1and-~f(n%a or n/a)

オンラインでお試しください!




1
57バイトまた、最初はこれを自分自身の回答にしたことに対する謝罪。コメントとしてより理にかなっています
-reffu

5

Haskell、85 78バイト

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

Bruce Forteのおかげで7バイト節約されました。

オンラインでお試しください。


使用していくつかのより多くのバイトを保存divModし、落下whereオンラインそれをお試しください!
ライコニ

@ライコニうわー、それはかなり改善です!別の回答として投稿してください。それは私のものとは十分に異なっています。ところで:私はを取り除くためのトリックを探していましたwhere。これは将来使用します。:)
クリスティアンルパスク

sum[read[d]|d<-show n]バイトを保存
-nimi

5

JavaScript(ES6)、66 58 51 49バイト

入力を整数として受け取ります。戻り値falseのため01、それはその桁まで追加任意の数に遭遇した場合オーバーフローエラーがスローされます1

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • Justinの助けを借りて8バイトを節約しました。

試して

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
を使用して数字を合計することで、いくつかのバイトを節約できますeval(array.join`+`)か?
ジャスティンマリナー

確かに、@ JustinMariner-あなたは私をそれに忍び込ませました!ありがとう:)
シャギー

4

、12バイト

←€1¡Ṡ§|÷%oΣd

オンラインでお試しください!

説明

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.




2

Mathematica、73バイト

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&

==0に置き換えることができます<1か?
ミスターXcoder

@ Mr.Xcoderはい、もちろんです!ソーターバージョンを作成しました
...-J42161217

2

PHP、68 + 1バイト

単項出力:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

10進出力、73 + 1バイト:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

でパイプとして実行する-nR、オンラインで試してください


Elvisオペレーターには、PHP 5.3以降が必要です。古いPHPの場合は?:?$n%$s:(+ 5バイト)に置き換えます。


2

ルビー、46バイト

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}





1

Perl、71バイト、64バイト、63バイト

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

オンラインで試す

編集:Xcaliのコメントのおかげで7バイトを節約

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

編集:5.14以降の非破壊置換s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

された-pl上にではなく、コマンドラインフラグのはず?
エリックアウトゴルファー

はい、それらはperlオプションです
ナウエルフイユ

この投稿-plに従って旗を数えるべきです。
エリックアウトゴルファー

plオプションで69バイト+2をカウントしましたが、正しいですか?
ナウエルフイユル

これを少し下にゴルフできます。 $c初期化する必要はありません。undef0 から開始します。whileクロージャの後のセミコロンを使用できます。また、必要ありません-l。1回の実行で複数の入力を取得する必要はありません。
Xcali

1

Dyalog APL、36バイト

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

オンラインでお試しください!

どうやって?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}

1

ガイア、13バイト

-@{:ΣZ¤∨)‡}°\

オンラインでお試しください!

説明

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter

1

Matlab、150バイト

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

入力は、X( '152')などの文字列として関数に指定する必要があります。

この関数は、ループし、dを増分することで機能します。のx=y;行は、Matlabが変数値を同時に読み取って上書きしようとするエラーを回避するために必要でした。

ゴルフをしていない:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end


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