Ekleme-Çarpma Ekleme Dizisi


27

( İlgili )

Bir tamsayı verilirse n > 1,
1) Sayı aralığını oluşturun n, n-1, n-2, ... 3, 2, 1ve toplamı hesaplayın
2) Bu sayının tek tek rakamlarını alın ve ürünü hesaplayın
3) Bu sayının tek tek rakamlarını alın ve toplamı hesaplayın
4) 2. ve 3. adımları tekrarlayın. tek bir haneye ulaşmak. Sonuç bu rakamdır.

Dizinin ilk yirmi terimi aşağıdadır:

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

Not: Bu dizi OEIS'te DEĞİLDİR.

G / Ç ve Kurallar

  • Sayılar hızlı bir şekilde çok büyük olacaktır, bu nedenle çözümün 100.000'e kadar giriş numaralarını hatasız olarak kullanabilmesi gerekir (kodunuzun bunu geçebilmesi iyi olabilir).
  • Giriş ve çıkış herhangi bir uygun yöntemle verilebilir .
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine geri gönderebilirsiniz.
  • Standart boşluklar yasaktır.
  • Bu olduğundan, tüm normal golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

Örnekler

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0

3
OEIS'de olmayan bir dizi mücadelesi için +1
JAD

2
Her ne zaman n ≤ 100000 , 2. ve 3. adımlarda sadece iki iterasyon sonucu elde etmek için yeterlidir. Bundan faydalanabilir miyiz yoksa seçtiğimiz algoritma n'nin daha büyük değerleri için çalışmalı mı?
Dennis,

2
@Dennis Algoritma, herhangi bir değer için çalışmalıdır n. Gönderilen çözüm sadece çalışmak zorunda n = 100000.
AdmBorkBork

3
Numbers will get very large quicklyhayır öyle değil
l4m2

3
@ l4m2 Çıktı değil. Ancak 100000 + 99999 + ... + 1 = 5000050000 , tercih ettiğiniz dilin temsil etmekte zorlanabileceği veya olamayacağı 33 bitlik bir sayıdır.
Dennis,

Yanıtlar:


10

Python 2 , 77 72 71 62 60 bayt

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

2 baytlık golf oynamak için @xnor'a teşekkürler!

Çevrimiçi deneyin!


Ben sadece döngü için bir geçiş ama gelecek için bu numarayı hatırlamak gerekir.
Dennis,

Nerede repeat until you reach a single digit?
Titus

2
@Titus Sadece yerine n her zaman yeterli olan adımlar 2 ve 3'ün iterasyon. Aslında, 10000'den bu yana , üç tekrar yeterli olacaktır.
Dennis

Şimdi bahsettiğinize göre: Aslında, üç yineleme gerektiren en küçük girdi 236172; ve bu 1 milyonun altındaki tek kişi.
Titus,


8

05AB1E , 7 bayt

LOΔSPSO

Çevrimiçi deneyin!

Exlpanation

L         # push range [1 ... input]
 O        # sum range
  Δ       # loop until top of stack stops changing
   SP     # product of digits
     SO   # sum of digits

Neredeyse ASCII-sadece! : D
AdmBorkBork

@AdmBorkBork: Evet, çok yaygın değil: P
Emigna

4

Jöle , 8 bayt

RSDPDƲÐL

Çevrimiçi deneyin!

Tam program (sonucu içeren bir singleton dizisi döndürür, ancak parantez STDOUT'da görünmez).


Bu, henüz gördüğüm en "doğal görünümlü" Jelly cevabı. Sadece 2 ASCII olmayan karakter var
RedClover


Buradaki tartışmayı yapamayız lütfen, teşekkürler. : P TNB, gürültü yapılmadığı takdirde bunu tartışmak için alternatif bir yer olabilir. ;)
Outgolfer Erik,

4

MATL , 15 13 bayt

Ayın Dili Anısına :

:`sV!UpV!Utnq

Çevrimiçi deneyin!

Bir sayının rakamlarını almak için, sayıyı bir dizgeye dönüştürmek V, sonra onu !dönüştürmek ve bu dikey vektörü tekrar sayısal bir sayıya dönüştürmekten daha basit bir yol olduğunu sanmıyorum U.

Oluşturan 1'in kendisi sayesinde 2 bayt kurtarıldı ! Örtülü sonu, yani kaldırabileceğimi ]ve öğelerin sayısını karşılaştırmak yerine, 1bu değeri düşürüp doğrudan bir boole olarak kullanabileceğimi unuttum .

Yani, açıklama şöyle gider:

                 % 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 ... MATL, Luis Mendo.


3

JavaScript (ES6), 60 bayt

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

Çevrimiçi deneyin!

Yorumlananlar

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

Alternatif sürüm, 59 bayt (yarışmaz)

Sadece n <236172 için çalışan özyinelemeli olmayan bir sürüm . (İstenen aralığı kapsar ancak geçerli bir genel algoritma olarak nitelendirilmez.)

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

Çevrimiçi deneyin!


Ana sürümünüz N> = 77534568790 olduğunda kırılıyor. N = 7753456879; kesme noktasının tam olarak nerede olduğundan emin değilim. Requirment N = 100.000 kadar idare sadece çünkü Tabii ki, bu ben yazdım neden .... emin değilim bu yüzden, önemli değildir
Ross Presser

1
@RossPresser Kaba bir tahmin olarak, bunun yerine işe yaradığını söyleyebilirim Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld


2

Stax , 14 13 10 bayt

ñu┌↕a√äJ²┐

Koş ve hata ayıkla

Yapması oldukça eğlenceliydi. Sonunda karşılaştırma yapmanın daha özlü bir yolu olup olmadığını merak ediyorum.

açıklama

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

Ovs sayesinde -1 bayt

Scrooble sayesinde -3 bayt


2

R , 152 130 109 bayt

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

Çevrimiçi deneyin!

@Giuseppe, alışkın olmadığım çeşitli R şeylerine sahip 21 42 bayt bulundu , bir rakamın rakamlarını dize ve geriye zorlamadan ve daha az byte ile zorlamadan!

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

options(scipen=9) bir ilk ürün aşama 8e + 05 olarak 80000, R, baskılar olarak sona erer, çünkü eski fonksiyonu için 9854 durumu için gerekli oldu.


Ah, anlıyorum. Bilimsel gösterim çıkışı. İyi yakalama!
AdmBorkBork

1
Sonunda dolaştı scipen: Çevrimiçi deneyin ! Not max(0,log10(x))çünkü eğer olduğunu x=0, sonra log10(0)=-Infbir hata neden olur.
Giuseppe,

1

Pyth , 11 bayt

usj*FjGTTsS

Burada dene!

usj * FjGTTsS - Tam program. N = giriş.
          S - Menzili Verim [1, N] ⋂ ℤ.
         s - Topla.
u - Ardışık iki yineleme aynı sonucu vermezse, yapın (var: G):
   * FjGT - Dijital ürün.
 sj T - Dijital toplam.

1

Kömür , 18 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

≔Σ…·¹Nθ

Tamsayıları girişe kadar toplayın.

 W›θ⁹≔ΣΠθθ

Sonuç 9'dan büyük olsa da, rakam ürününün rakamlarının toplamını alın.

Iθ

Sonuç dizgeye yayınlanır ve örtük olarak yazdırılır.


1

Gaia , 8 bayt

┅⟨Σ₸∨Π⟩°

Çevrimiçi deneyin!

Eski açıklama (Gaia'nın IMO: P hatası olan bir hatayı düzeltmeden önce):

┅⟨ΣΠ⟩ ° - Tam program. N = giriş.
Range - Menzil. [1, N] ⋂ ℤ yığınına bastırın.
 ⟩⟩ ° - İki ardışık yineleme aynı sonucu vermese de, şunları yapın:
  Sum - Toplam (veya bir tam sayıya uygulandığında dijital toplam).
   Π - Dijital ürün.

Dennis sayesinde 1 byte kurtarıldı .


┅⟨ΣΠ⟩°bir bayt kaydeder.
Dennis,

Bu değerler için işe yaramazsa dijital toplam 0'dır, aynen4
Jo King

@JoKing Sabit, bunu tespit ettiğiniz için teşekkür ederiz. Ne yazık ki, Gaia'da, bir nedenden dolayı 0sonuçların rakamlarını almak []:(
Mr. Xcoder

1

F #, 175 bayt

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

Çevrimiçi deneyin!

İşlev için tek uyarı giriş değerinin tür olması gerektiğidir uint64.

Ungolfed biraz şunun gibi:

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

İşlev d n, sayıyı nbileşen basamaklarına dönüştürür . Önce bir dizgeye dönüştürülür, ardından dizedeki her karakteri alır. Her karakter daha sonra bir dizgeye dönüştürülmelidir, aksi takdirde karakterler "gerçek" değerleri yerine ASCII değerlerine dönüştürülür.

c nFonksiyonu, ana işlevi nbaşlangıç değeri olarak. Bu fonksiyonda rçalışan değerimiz. whileDöngü aşağıdakileri yapar:

  • rBileşen rakamlarına ( d r) dönüştürün .
  • Tüm bu rakamların ürününü al. Bu, Seq.reduce( a) sıralı değerde ( ) ve sıradaki ( ) sıradaki değerde bir işlev alan xve bu durumda ürünü döndürür. İlk değer, dizideki ilk öğedir.
  • Bu ürün değerini bileşen basamaklarına ( d) dönüştürün.
  • Daha önceki rakamları toplayın ve bunu atayın r.

1

Befunge, 136 bayt

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

Sen edebilirsiniz burada deneyin .

Tüm tercümanlar yeterince büyük hücre boyutuna sahip olmasa da, hemen hemen herkes için küçük sayılarla çalışır. Daha fazla sayıda için BefunExecn gibi bir tercümana ihtiyacınız olabilir .


1

Gol> <> , 35 33 bayt

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

Çevrimiçi deneyin!

Jo King tarafından -2 bayt.

İşlevlerin ve örtülü sonsuz döngülerin yoğun kullanımı.

Örnek tam program & Nasıl çalışır?

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


1

Japt, 16 14 13 bayt

_ì ×ìx}gN®õ x

Dene


açıklama

                  :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

Güzel, bunu kendim çözmeye çalıştım ama iyi bir çözüm bulamadım, bu yüzden sizinkileri görmek ilginç.
Nit

Teşekkürler, @Nit. Yine de daha kısa bir yol olmalı.
Shaggy,

@Nit, anladım! Yine de, orada daha kısa bir yol olması gerektiğine ikna oldum.
Shaggy


0

PHP 7, 89 bayt

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

Pipe ile çalıştırın -rveya çevrimiçi deneyin .

  • PHP her zaman dize olarak girdi alır, bu yüzden +int için cast kullanmak zorunda~ istediğim gibi çalışmak .
  • Ön artış işe yaramaz: nereye koyduğum önemli değil, her iki operayı da etkiler.
  • Ancak: Tek hanenin yinelemeden önce veya sonra gerçekleşmesi önemli değildir (ek yinelemeler bir şeyi değiştirmez); bu yüzden for()yerine kullanabilirimdo ... while() .
  • İşlev adının satır içi atanması için PHP 7 veya üstü gerekir.
    Daha eski PHP bir bayt daha gerektirir: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    ( str_splitBir değişkene atanmamak , başka bir baytı boşa harcar.)



0

PowerShell Çekirdek , 91 101 93 bayt

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

Çevrimiçi deneyin!

Ungolfed biraz ...

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

İlk adımlar tamsayıları sayılara bölmekti - bunu tamsayıları bir dizgeye bölerek yaptım. karakterler. Daha sonra operand'ı yerleştirin ve sonra dizeyi komut olarak değerlendirin. Ardından, giriş bir basamak olana kadar çoklu-ekleme döngüsünü yapmak önemlidir.

iexInvoke-Commandilk param konumuna geçirilen bir ipi değerlendiren bir diğer isimdir.

Düzenleme: @AdmBorkBork tarafından istendiği gibi , bayt sayısına bir işlev başlığı ekledik. Ayrıca, biraz matematik yaptım ve yineleme sayısına bağlı bir üst sınır olduğunu fark ettim < log log 10^6 < log 6 < 2, böylece altı bayt daha tasarruf ettim.

Düzenleme x2: @AdmBorkBork , tam sayıyı bir matematik ifadesine dönüştürmenin daha kısa ve öz bir yolunu buldu ve sonra onu boruya eklemeyi önerdi iex. Bu 8 bayt kurtardı. Teşekkür ederim!


Etrafında başka bir PowerSheller görmek güzel! Ancak, işlev tanımını Function F($a){ }bayt sayınıza eklemeniz gerektiğini düşünüyorum . Ancak, [char[]]bunun yerine bazılarını kullanabilmeniz gerektiğini -split''-ne''düşünüyorum.
AdmBorkBork

[char[]]1234=Ӓ, geçersiz; İşe yarayabilirim, ama şimdi belli değil. Önerin için teşekkürler!
Jeff Freeman,

Üzgünüm, net değildim - [char[]]"$o"ve |iexdeğil iex( ).
AdmBorkBork

Bu ipucu kodumun% 8'ini tıraş etti. Muhteşem. Teşekkürler!
Jeff Freeman



0

Java 8, 129 bayt

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

Çevrimiçi deneyin.

Açıklama:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.