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!

Tuan Xcoder
sumber
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
Emigna
sumber
6

Python 2 , 63 57 byte

-1 terima kasih untuk benar-benar manusia
-1 terima kasih untuk Tuan Xcoder
-4 terima kasih kepada reffu

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

Cobalah online!

Arfie
sumber
1
57 byte Juga permintaan maaf saya untuk membuat ini jawaban saya sendiri pada awalnya. Lebih masuk akal sebagai komentar
reffu
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.

Cristian Lupascu
sumber
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>

Shaggy
sumber
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.
Zgarb
sumber
3

C # (.NET Core) , 87 byte

n=>{int i=0,k,l;for(;n>1;++i){for(l=n,k=0;l>0;l/=10)k+=l%10;n=n%k>0?n%k:n/k;}return i;}

Cobalah online!

Fungsi Lambda yang mengambil dan mengembalikan integer.

jkelm
sumber
3

Japt , 22 19 17 byte

-3 byte terima kasih kepada @Shaggy.
-2 byte terima kasih kepada @ETHproductions


ìx
>1©1+ßU%VªU/V

Cobalah online!

Justin Mariner
sumber
1
<s> 20 byte </s> 19 byte
Shaggy
1
Sebenarnya, Anda dapat mengubah s_¬untuk ìmenyimpan dua byte lagi :-)
ETHproduksi
@ ETHproductions Oh, benar-benar keren, terima kasih!
Justin Mariner
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.

Neil
sumber
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)&
J42161217
sumber
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).

Titus
sumber
2

Ruby, 46 byte

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}
m-chrzan
sumber
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!

ბიმო
sumber
1

Jelly , 12 byte

dDS$Ṛȯ/µÐĿL’

Cobalah online!

Erik the Outgolfer
sumber
Pendekatan yang menarik! Sekarang kami menunggu Jonathan: P
Mr. Xcoder
@ Mr.Xcoder Saya tidak berpikir begitu kali ini :)
Erik the Outgolfer
Saya juga tidak, itu adalah lelucon :)
Mr. Xcoder
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
Nahuel Fouilleul
sumber
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
}
Uriel
sumber
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
Kucing Bisnis
sumber
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
sintaks
sumber
0

R , 85 byte

function(n){while(n>1){n="if"(x<-n%%(d=sum(n%/%10^(nchar(n):0)%%10)),x,n/d)
F=F+1}
F}

Fungsi anonim yang mengembalikan output yang diperlukan.

Verifikasi semua kasus uji!

Giuseppe
sumber