Urutan Tambah-Multiply-Tambah

27

( Terkait )

Diberikan bilangan bulat n > 1,
1) Bangun kisaran angka n, n-1, n-2, ... 3, 2, 1dan hitung jumlah
2) Ambil angka individu dari angka itu dan hitung produk
3) Ambil angka individual angka itu dan hitung jumlahnya
4) Ulangi langkah 2 dan 3 hingga Anda mencapai satu digit. Angka itu adalah hasilnya.

Dua puluh istilah pertama dari urutan di bawah ini:

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

Catatan: Urutan ini BUKAN di OEIS.

I / O dan Aturan

  • Angka akan menjadi sangat besar dengan cepat, sehingga solusinya harus dapat menangani angka input hingga 100.000 tanpa kegagalan (tidak masalah jika kode Anda dapat mengatasi itu).
  • Input dan output dapat diberikan dengan metode apa pun yang mudah .
  • Program lengkap atau fungsi dapat diterima. Jika suatu fungsi, Anda dapat mengembalikan output daripada mencetaknya.
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.

Contohnya

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0
AdmBorkBork
sumber
3
+1 untuk tantangan urutan yang tidak ada dalam OEIS
JAD
2
Setiap kali n ≤ 100000 , hanya dua iterasi dari langkah 2 dan 3 yang cukup untuk mendapatkan hasilnya. Bisakah kita mengambil keuntungan dari itu atau haruskah algoritma yang kita pilih berfungsi untuk nilai n yang lebih besar ?
Dennis
2
@ Dennis Algoritma harus bekerja untuk nilai apa pun n. Solusi yang diposting hanya perlu bekerja hingga n = 100000.
AdmBorkBork
3
Numbers will get very large quicklytidak itu
l4m2
3
@ l4m2 Bukan output. Tetapi 100000 + 99999 + ... + 1 = 5000050000 adalah angka 33-bit, yang bahasa Anda pilihan mungkin atau mungkin tidak mengalami masalah.
Dennis

Jawaban:

10

Python 2 , 77 72 71 62 60 byte

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

Terima kasih kepada @xnor karena bermain golf 2 byte!

Cobalah online!

Dennis
sumber
Saya baru saja beralih ke loop for, tetapi saya harus mengingat trik itu untuk masa depan.
Dennis
Dimana repeat until you reach a single digit?
Titus
2
@Titus saya hanya melakukan n iterasi dari langkah 2 dan 3, yang selalu cukup. Bahkan, sejak n ≤ 100000 , tiga iterasi akan cukup.
Dennis
Sekarang Anda menyebutkannya: Sebenarnya, input terkecil yang membutuhkan tiga iterasi adalah 236172; dan itu satu-satunya di bawah 1 juta.
Titus
Anda dapat mengurangi
xnor
8

05AB1E , 7 byte

LOΔSPSO

Cobalah online!

Penjelajahan

L         # push range [1 ... input]
 O        # sum range
  Δ       # loop until top of stack stops changing
   SP     # product of digits
     SO   # sum of digits
Emigna
sumber
Hampir ASCII saja! : D
AdmBorkBork
@ AdmBorkBork: Ya, tidak terlalu umum: P
Emigna
4

Jelly , 8 byte

RSDPDƲÐL

Cobalah online!

Program lengkap (ini mengembalikan array tunggal yang berisi hasilnya, tetapi tanda kurung tidak terlihat di STDOUT).

Erik the Outgolfer
sumber
Ini adalah jawaban Jelly yang paling "tampak alami" yang pernah saya lihat. Hanya ada 2 karakter non-ASCII
RedClover
Uh, bisakah kita tidak berdiskusi di sini, terima kasih. : P TNB bisa menjadi tempat alternatif untuk mendiskusikan hal ini, jika tidak ada suara bising. ;)
Erik the Outgolfer
4

MATL , 15 13 byte

Sebagai penghormatan untuk Bahasa bulan ini :

:`sV!UpV!Utnq

Cobalah online!

Saya tidak berpikir ada cara yang lebih sederhana untuk mendapatkan digit angka daripada mengubah angka menjadi string V, lalu mentransposasinya !, dan mengubah vektor vertikal ini kembali ke angka U.

Disimpan 2 byte berkat Pencipta 1 sendiri! Saya lupa ujung yang tersirat, artinya saya bisa menghapus] , dan alih-alih membandingkan jumlah elemen dengan 1, saya hanya bisa mengurangi nilai itu dan menggunakannya sebagai boolean secara langsung.

Jadi, penjelasannya seperti ini:

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... dari MATL, Luis Mendo.

Stewie Griffin
sumber
3

JavaScript (ES6), 60 byte

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

Cobalah online!

Berkomentar

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

Versi alternatif, 59 byte (tidak bersaing)

Versi non-rekursif yang hanya berfungsi untuk n <236172 . (Ini mencakup rentang yang diminta tetapi tidak memenuhi syarat sebagai algoritma generik yang valid.)

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

Cobalah online!

Arnauld
sumber
versi utama Anda rusak ketika N> = 77534568790. Ini berfungsi saat N = 7753456879; tidak yakin persis di mana breakpoint berada. Tentu saja, ini tidak masalah karena syaratnya hanya untuk menangani hingga N = 100.000, jadi saya tidak yakin mengapa saya menulis ini ....
Ross Presser
1
@RossPresser Sebagai perkiraan kasar, saya akan mengatakan itu agak berhasil Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld
3

Haskell , 72 71 63 byte

g=map(read.pure).show
f n=until(<10)(sum.g.product.g)$sum[1..n]

Terima kasih kepada @BMO untuk byte dan @nimi selama 8 byte!

Cobalah online!

Angs
sumber
2

Stax , 14 13 10 byte

ñu┌↕a√äJ²┐

Jalankan dan debug itu

Cukup menyenangkan untuk dibuat. Saya ingin tahu apakah ada cara yang lebih ringkas untuk melakukan perbandingan di bagian akhir.

Penjelasan

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

-1 byte berkat ovs

-3 byte terima kasih kepada Scrooble

Multi
sumber
2

R , 152 130 109 byte

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

Cobalah online!

@Giuseppe ditemukan 21 42 byte dengan berbagai hal R yang saya belum terbiasa, bersama dengan cara untuk mendapatkan digit angka tanpa paksaan untuk string dan kembali, dan dengan lebih sedikit byte!

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) aku s diperlukan untuk kasus 9854 untuk fungsi tua, karena tahap produk pertama berakhir sebagai 80000, yang R cetak sebagai 8e + 05.

ngm
sumber
Ah, begitu. Output notasi ilmiah. Tangkapan yang bagus!
AdmBorkBork
1
Akhirnya berkeliling scipen: Cobalah secara online ! perhatikan max(0,log10(x))ini karena jika x=0, maka log10(0)=-Infyang menyebabkan kesalahan.
Giuseppe
1

Pyth , 11 byte

usj*FjGTTsS

Coba di sini!

usj * FjGTTsS - Program lengkap. N = Input.
          S - Range. Hasil [1, N] ⋂ ℤ.
         s - Jumlah.
u - Meskipun tidak ada dua iterasi yang berurutan menghasilkan hasil yang sama, lakukan (var: G):
   * FjGT - Produk digital.
 sj T - Jumlah digital.
Tuan Xcoder
sumber
1

Arang , 18 byte

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

≔Σ…·¹Nθ

Jumlah bilangan bulat hingga input.

 W›θ⁹≔ΣΠθθ

Sementara hasilnya lebih besar dari 9, ambil jumlah digit dari produk digit.

Iθ

Keluarkan hasilnya ke string dan cetak secara implisit.

Neil
sumber
1

Gaia , 8 byte

┅⟨Σ₸∨Π⟩°

Cobalah online!

Penjelasan lama (sebelum memperbaiki bug yang merupakan kesalahan Gaia IMO: P):

┅⟨ΣΠ⟩ ° - Program lengkap. N = Input.
┅ - Rentang. Tekan [1, N] ⋂ ℤ ke tumpukan.
 ⟨⟩ ° - Meskipun tidak ada dua iterasi yang berurutan menghasilkan hasil yang sama, lakukan:
  Σ - Jumlah (atau jumlah digital, bila diterapkan ke bilangan bulat).
   Π - Produk digital.

Disimpan 1 byte berkat Dennis .

Tuan Xcoder
sumber
┅⟨ΣΠ⟩°menghemat satu byte.
Dennis
Ini tidak berfungsi untuk nilai karena jumlah digitalnya adalah 0, seperti4
Jo King
@ JoKing Fixed, terima kasih telah melihatnya. Sayangnya, di Gaia, mengambil digit 0hasil []untuk beberapa alasan :(
Mr. Xcoder
1

F #, 175 byte

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

Cobalah online!

Satu-satunya peringatan untuk fungsi adalah bahwa nilai input harus bertipe uint64.

Tidak digabungkan sedikit seperti ini:

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

Fungsi d nmengubah angka nmenjadi digit komponennya. Pertama-tama mengkonversi ke string, kemudian mendapatkan setiap karakter di string. Setiap karakter kemudian harus dikonversi kembali menjadi string, jika tidak karakter akan dikonversi ke nilai ASCII mereka alih-alih nilai "nyata" mereka.

The c nfungsi fungsi utama, dengan nsebagai nilai awal. Dalam fungsi ini radalah nilai berjalan kami. The whileloop tidak berikut:

  • Konversikan rke dalam digit komponennya ( d r).
  • Dapatkan produk dari semua digit itu. Ini menggunakan Seq.reduceyang mengambil fungsi dengan nilai akumulasi ( a) dan nilai berikutnya dalam urutan ( x) dan dalam hal ini mengembalikan produk. Nilai awal adalah elemen pertama dalam urutan.
  • Ubah nilai produk ini menjadi digit komponennya ( d).
  • Jumlahkan digit dari sebelumnya, dan tetapkan ke r.
Ciaran_McCarthy
sumber
1

Befunge, 136 byte

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

Anda bisa mencobanya di sini .

Meskipun tidak semua penerjemah memiliki ukuran sel yang cukup besar, ia bekerja dengan jumlah kecil untuk hampir semua orang di luar sana. Untuk jumlah yang lebih besar, nAnda mungkin membutuhkan juru bahasa seperti BefunExec .

Gegell
sumber
1

Gol> <> , 35 33 byte

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

Cobalah online!

-2 byte oleh Jo King.

Penggunaan fungsi yang luas dan loop tak terbatas implisit.

Contoh program lengkap & Cara kerjanya

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top
Bubbler
sumber
33 byte
Jo King
1

Japt, 16 14 13 byte

_ì ×ìx}gN®õ x

Cobalah


Penjelasan

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition
Shaggy
sumber
Rapi, saya mencoba menyelesaikan yang ini sendiri tetapi tidak menemukan solusi yang baik sehingga menarik untuk melihat milik Anda.
Nit
Terima kasih, @Nit. Tapi pasti ada jalan yang lebih pendek.
Shaggy
@Nit, mengerti! Tetap yakin harus ada jalan yang lebih pendek.
Shaggy
0

PHP 7, 89 byte

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

Jalankan sebagai pipa dengan -ratau coba online .

  • PHP selalu mengambil input sebagai string, jadi saya harus menggunakan +cast ke int untuk ~bekerja sesuai yang diinginkan.
  • Pre-increment tidak akan berfungsi: di mana pun saya meletakkannya, itu akan mempengaruhi kedua operan.
  • Tetapi: Tidak masalah jika digit tunggal terjadi sebelum atau setelah iterasi (iterasi tambahan tidak akan mengubah apa pun); jadi saya bisa menggunakannya for()sebagai gantinya do ... while().
  • PHP 7 atau lebih baru diperlukan untuk penugasan sebaris nama fungsi.
    PHP yang lebih lama membutuhkan satu byte lagi: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (Tidak menetapkan str_splitke variabel sama sekali akan membuang byte lain.)
Titus
sumber
0

Perl 6 , 49 byte

{($_*.succ/2,{[+] ([*] .comb).comb}...9>=*).tail}

Cobalah online!

Sean
sumber
Anda dapat menggunakan [*](.comb).combsebagai gantinya([*] .comb).comb
Brad Gilbert b2gills
0

PowerShell Core , 91 101 93 byte

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

Cobalah online!

Tidak dikumpulkan sedikit ...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

Langkah pertama adalah untuk membagi integer menjadi digit - lakukan ini dengan memisahkan integer menjadi array string karakter . Setelah itu, masukkan operan, lalu evaluasi string sebagai perintah. Kemudian, ini soal melakukan siklus multi-tambah hingga inputnya satu digit.

iex adalah alias untuk Invoke-Command yang mengevaluasi string yang dilewatkan ke posisi param pertama.

Sunting: Seperti yang diminta oleh @AdmBorkBork , saya telah menambahkan header fungsi ke jumlah byte. Juga, saya melakukan sedikit matematika dan menyadari bahwa batas atas pada jumlah iterasi adalah < log log 10^6 < log 6 < 2, sehingga menghemat enam byte lagi.

Sunting x2: @AdmBorkBork menemukan cara yang lebih singkat untuk mengubah bilangan bulat menjadi ekspresi matematika, dan kemudian menyarankan untuk memasukkannya ke dalam iex. Ini menyimpan 8 byte. Terima kasih!

Jeff Freeman
sumber
Senang melihat PowerSheller lain di sekitar! Namun, saya pikir Anda perlu memasukkan definisi fungsi Function F($a){ }dalam jumlah byte Anda. Namun, Anda harus dapat menghemat menggunakan [char[]]bukan -split''-ne'', saya pikir.
AdmBorkBork
[char[]]1234=Ӓ, yang tidak valid; Saya mungkin bisa membuatnya bekerja, tetapi mungkin tidak jelas sekarang. Terima kasih untuk sarannya!
Jeff Freeman
Maaf saya tidak jelas - [char[]]"$o"dan |iexbukan iex( ).
AdmBorkBork
Tip ini mencukur 8% dari kode saya. Luar biasa. Terima kasih!
Jeff Freeman
0

Ruby , 57 byte

->n{("*+"*n).chars.reduce(-~n*n/2){|x,y|eval x.digits*y}}

Cobalah online!

Kirill L.
sumber
0

Java 8, 129 byte

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

Cobalah online.

Penjelasan:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result
Kevin Cruijssen
sumber
0

Julia 0,6 , 56 byte

f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k

Cobalah online!

Cukup mudah: hitung (n+1)n÷2untuk jumlah dari 1..n, periksa apakah itu nomor digit tunggal ( >9), jika tidak, coba lagi dengan k atur ke jumlah digit produk dari digit k, selain k k.

sundar - Pasang kembali Monica
sumber