Lipat bilangan bulat untuk menghemat tempat!


20

Matematikawan yang gila memiliki banyak koleksi angka, dan karena itu ruang yang dia tinggalkan sangat terbatas. Untuk menghemat, ia harus melipat bilangan bulatnya, tetapi sayangnya ia benar-benar malas. Tugas Anda, jika Anda ingin membantunya, adalah membuat fungsi / program yang melipat bilangan bulat positif yang diberikan untuk maniak nomor kami.

Bagaimana cara melipat bilangan bulat?

Jika habis dibagi dengan jumlah digitnya, bagilah dengan jumlah digitnya. Jika tidak memenuhi persyaratan itu, ambil sisanya ketika dibagi dengan jumlah digitnya. Ulangi proses ini hingga hasilnya tercapai 1. Bilangan bulat terlipat adalah jumlah operasi yang harus Anda lakukan. Mari kita ambil contoh (katakanlah 1782):

  1. Mendapatkan jumlah dari digit: 1 + 7 + 8 + 2 = 18. 1782dibagi secara merata oleh 18, jadi nomor selanjutnya adalah 1782 / 18 = 99.

  2. 99tidak dibagi secara merata 9 + 9 = 18, maka kita mengambil sisanya: 99 % 18 = 9.

  3. 9jelas dibagi oleh 9, jadi kami membaginya dan mendapatkan 1.

Hasilnya adalah 3, karena 3 operasi diperlukan untuk mencapai 1.

Aturan dan Spesifikasi

  • Beberapa bilangan bulat mungkin memiliki jumlah digit yang sama dengan 1, seperti 10atau 100. Program Anda tidak perlu menangani kasus seperti itu. Itu berarti, Anda akan dijamin bahwa bilangan bulat yang diberikan sebagai input tidak memiliki jumlah digit sama dengan 1, dan tidak ada operasi dengan bilangan bulat yang diberikan akan menghasilkan angka yang jumlah digitnya 1(kecuali untuk 1dirinya sendiri, yaitu " target"). Misalnya, Anda tidak akan pernah menerima 10atau 20sebagai masukan.

  • Input akan bilangan bulat positif lebih tinggi dari 1.

  • Berlaku celah default .

  • Anda dapat mengambil input dan memberikan output dengan cara standar apa pun .


Uji Kasus

Input -> Output

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

Berikut adalah program yang memungkinkan Anda memvisualisasikan proses dan mencoba lebih banyak kasus uji.


Ini adalah , jadi kode terpendek di setiap bahasa (dicetak dalam byte) menang!


Terinspirasi oleh tantangan ini , meskipun mungkin tidak tampak terkait pada awalnya.
Tn. Xcoder

3
Ini akan berfungsi sebagai solusi sementara, tetapi dalam jangka panjang, ahli matematika harus benar-benar mempertimbangkan untuk membeli salah satu dari Hotel Hilbert . Anda selalu dapat menemukan ruang yang tidak digunakan di salah satu dari itu.
Ray

sementara 8987868546input yang valid, itu akan merusak alat tes Anda, dan juga banyak (jika tidak semua) dari jawabannya ...
Mischa

@MischaBehrend Contoh Anda bukan input yang valid. Saya pikir Anda salah menyalin test case terakhir saya. Masukan yang valid adalah 898786854, bukan 8987868546(Anda telah menambahkan 6di akhir)
Tn. Xcoder

nvm ... harus membaca seluruh aturan pertama ... meninggalkan ini di sini sehingga Anda tahu mengapa saya pikir itu valid: itu bukan kesalahan ... Saya mengubahnya dengan sengaja untuk menguji skrip ini ... dan membaca aturan itu adalah input yang valid. Jumlah semua digit dalam 8987868546 bukan 1 ( Aturan 1 bertemu ) dan 8987868546bilangan bulat positif lebih tinggi dari 1 ( Aturan 2 bertemu ).
Mischa

Jawaban:


6

05AB1E , 13 12 byte

[¼DSO‰0Kθ©#®

Cobalah online!

Penjelasan

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


5

Haskell, 85 78 byte

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

Disimpan 7 byte berkat Bruce Forte.

Cobalah online.


Simpan lebih banyak byte dengan menggunakan divModdan menjatuhkan where: Coba online!
Laikoni

@Laikoni Wow, itu cukup perbaikan! Silakan posting sebagai jawaban yang berbeda; itu cukup berbeda dari milikku. BTW: Saya sedang mencari trik untuk menyingkirkan where. Saya akan menggunakan ini di masa depan. :)
Cristian Lupascu

sum[read[d]|d<-show n]menghemat satu byte
nimi

5

JavaScript (ES6), 66 58 51 49 byte

Mengambil input sebagai integer. Pengembalian falseuntuk 0atau 1dan melempar kesalahan meluap ketika bertemu sejumlah yang digit menambahkan hingga 1.

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • 8 byte disimpan dengan bantuan dari Justin .

Menguji

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
Bisakah Anda menyimpan beberapa byte dengan menjumlahkan digit menggunakan eval(array.join`+`)?
Justin Mariner

Saya memang bisa, @JustinMariner - Anda ninja saya untuk itu! Terima kasih :)
Shaggy

4

Sekam , 12 byte

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

Cobalah online!

Penjelasan

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

Retina , 100 byte

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

Cobalah online! Tautan hanya mencakup test case yang lebih kecil karena yang lebih besar terlalu lama.


2

Mathematica, 73 byte

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

Bisakah ==0diganti <1?
Tn. Xcoder

@ Mr.Xcoder ya, tentu saja! Saya membuat versi penyortir ...
J42161217

2

PHP, 68 +1 byte

keluaran unary:

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

output desimal, 73 +1 byte:

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

Jalankan sebagai pipa dengan -nRatau coba online .


Operator Elvis membutuhkan PHP 5.3 atau yang lebih baru. Untuk PHP yang lebih lama, ganti ?:dengan ?$n%$s:(+5 byte).


2

Ruby, 46 byte

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

2

Haskell , 94 93 89 88 byte

Ini terasa sangat panjang ..

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

Cobalah online!

Terima kasih @Laikoni & @nimi untuk bermain golf masing-masing 1 byte!





1

Perl, 71 byte, 64 byte, 63 byte

-pl

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

Cobalah online

EDIT: disimpan 7 byte, berkat komentar Xcali

-p

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

EDIT: sejak 5.14 substitusi non destruktif s /// r

-pl

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

Apakah yang -pldi atas seharusnya merupakan bendera baris perintah?
Erik the Outgolfer

ya mereka pilihan perl
Nahuel Fouilleul

Anda harus menghitung -plbendera menurut pos ini .
Erik the Outgolfer

Saya menghitung 69 byte +2 untuk opsi pl, apakah benar?
Nahuel Fouilleul

Anda bisa memainkan golf ini sedikit. $ctidak perlu diinisialisasi. Ini akan mulai dari undefyang 0. Titik koma setelah penutupan sementara bisa pergi. Anda juga tidak perlu -l. Tidak perlu mengambil banyak input dalam satu kali proses.
Xcali

1

Dyalog APL, 36 byte

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

Cobalah online!

Bagaimana?

{
   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

Gaia , 13 byte

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

Cobalah online!

Penjelasan

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

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

Input harus diberikan ke fungsi sebagai string, seperti X ('152').

Fungsi ini bekerja dengan sambil mengulang dan menambah d. Itux=y; garis itu diperlukan untuk menghindari kesalahan dari Matlab mencoba membaca dan menimpa nilai variabel pada saat yang sama, rupanya, yang adalah satu baru pada saya.

Tidak Terkumpul:

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


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.