Add-Multiply-Addシーケンス


27

関連

整数が与えられた場合n > 1
1)数値の範囲を構成しn, n-1, n-2, ... 3, 2, 1、合計を計算します
2)その数値
の個々の桁を取り、製品を計算します3)その数値の個々の桁を取り、合計を計算し
ます4)手順2と3を繰り返します1桁に達します。その数字が結果です。

シーケンスの最初の20の用語は次のとおりです。

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

注:このシーケンスはOEISにはありません。

I / Oとルール

  • 数値はすぐに非常に大きくなるため、ソリューションは最大10万個の入力数値をエラーなしで処理できる必要があります(コードがそれを超えて処理できる場合は問題ありません)。
  • 入力と出力は、任意の便利な方法で指定できます。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

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

3
OEISにないシーケンスチャレンジに対して+1
JAD

2
たびのn≤100000はステップ2と3の2つだけの反復が、結果を取得するのに十分です。それを利用できますか、または選択したアルゴリズムがnのより大きな値に対して機能する必要がありますか?
デニス

2
@Dennisアルゴリズムはの任意の値に対して機能するはずですn。投稿されたソリューションは、最大で動作する必要がありn = 100000ます。
AdmBorkBork

3
Numbers will get very large quicklyいいえ、ありません
-l4m2

3
@ l4m2出力ではありません。しかし、100000 + 99999 + ... + 1 = 5000050000は33ビットの数値であり、選択する言語で問題が発生する場合と発生しない場合があります。
デニス

回答:


10

パイソン277の 72 71 62 60バイト

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

2バイトのゴルフをしてくれた@xnorに感謝します!

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


私はちょうどループのために切り替えたが、私は将来のためにそのトリックを覚えておく必要があります。
デニス

どこrepeat until you reach a single digitですか?
タイタス

2
@Titus私は単にステップ2と3のn回の反復を実行するだけで十分です。実際、n≤100000なので、3回の反復で十分です。
デニス

あなたがそれについて言及したので:実際、3回の反復を必要とする最小の入力は236172;です。そして、それは100万人以下です。
タイタス



4

ゼリー、8バイト

RSDPDƲÐL

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

完全なプログラム(結果を含むシングルトン配列を返しますが、ブラケットはSTDOUTに表示されません)。


これは私が今まで見た中で最も「自然に見える」ゼリーの答えです。非ASCII文字は2つしかありません
-RedClover


ええと、ここで議論をしないでください、ありがとう。:P TNBは、ノイズが発生しない場合、これを議論するための代替場所になる可能性があります。;)
エリック・ザ・アウトゴルファー

4

MATL15 13バイト

今月言語へのオマージュ:

:`sV!UpV!Utnq

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

数字を文字列に変換してからV転置し!、この垂直ベクトルを数値に戻すよりも、数字の数字を取得する簡単な方法はないと思いますU

Creator 1自身のおかげで2バイト節約できました!暗黙の終わりを忘れました。つまり、を削除でき]、要素の数と比較する代わりに1単純にその値をデクリメントしてブール値として直接使用できます。

したがって、説明は次のようになります。

                 % 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

1MATLの ...、ルイスメンドー。


3

JavaScript(ES6)、60バイト

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

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

コメント済み

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

代替バージョン、59バイト(非競合)

n <236172に対してのみ機能する非再帰バージョン。(要求された範囲をカバーしますが、有効な汎用アルゴリズムとしての資格はありません。)

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

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


N> = 77534568790の場合、メインバージョンは破損します。N= 7753456879の場合は動作します。ブレークポイントがどこにあるか正確にはわかりません。もちろん、これは問題のrequirment、私は....これを書いた理由は、私はよく分からないので、のみN = 100,000まで処理することではありませんので、
ロス押え

1
@RossPresser大まかな見積もりとして、私はそれがむしろ最大で動作すると言うでしょうNumber.MAX_SAFE_INTEGER ** 0.5 ~= 94906265
アーナウルド


2

スタックス14 13 10 バイト

ñu┌↕a√äJ²┐

実行してデバッグする

作るのはとても楽しかったです。最後に比較を行うためのより簡潔な方法があるのだろうか。

説明

|+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により-1バイト

Scroobleのおかげで-3バイト


2

R152130109バイト

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

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

@Giuseppeは、私がまだ慣れていないさまざまなRのもので21 42バイトを見つけました。また、文字列を強制的に戻さずに、より少ないバイトで数字の桁を取得する方法もありました!

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

options(scipen=9) 最初の製品ステージが80000になり、Rが8e + 05として印刷されるため、古い機能の9854の場合にが必要でした。


ああ、なるほど。科学表記法の出力。良いキャッチ!
AdmBorkBork

1
最終的に回避scipenオンラインで試してみてください!注意しmax(0,log10(x))ている場合のでありx=0、その後、log10(0)=-Infエラーが発生しています。
ジュゼッペ

1

Pyth、11バイト

usj*FjGTTsS

ここで試してみてください!

usj * FjGTTsS –完全なプログラム。N =入力。
          S –範囲。収量[1、N]ℤℤ。
         s –合計。
u – 2つの連続した反復が同じ結果をもたらすことはありませんが、do(var:G):
   * FjGT –デジタル製品。
 sj T –デジタル合計。

1

、18バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔Σ…·¹Nθ

入力までの整数を合計します。

 W›θ⁹≔ΣΠθθ

結果が9より大きい間、数字の積の数字の合計を取ります。

Iθ

結果を文字列にキャストし、暗黙的に印刷します。


1

ガイア、8バイト

┅⟨Σ₸∨Π⟩°

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

古い説明(ガイアのせいIMO:Pであるバグを修正する前):

┅⟨ΣΠ⟩°–完全なプログラム。N =入力。
┅–範囲。[1、N]⋂ℤをスタックにプッシュします。
 ⟨⟩°– 2回の連続した繰り返しで同じ結果が得られない場合は、次のようにします。
  Σ–合計(または整数に適用される場合はデジタル合計)。
   Π–デジタル製品。

Dennisのおかげで1バイト節約されました。


┅⟨ΣΠ⟩°バイトを保存します。
デニス

値では動作しません。これは、デジタルサムは次のように、0であっ4
ジョー・キング

@JoKing修正、それを見つけてくれてありがとう。残念ながら、ガイアで0[]、何らかの理由で結果の数字を取得しています:(
Mr. Xcoder

1

F#、175バイト

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

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

関数の唯一の注意点は、入力値はtypeでなければならないということですuint64

ゴルフを付けていないのは、次のようなものです。

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

この関数d nは、数値nをそのコンポーネントの数字に変換します。最初に文字列に変換し、次に文字列内の各文字を取得します。次に、各文字を文字列に変換し直す必要があります。変換しないと、文字は「実際の」値ではなくASCII値に変換されます。

c n関数はで、主な機能であるn初期値として。この関数にrは、実行中の値があります。whileループは、次のことを行います。

  • rコンポーネントの数字(d r)に変換します。
  • これらすべての数字の積を取得します。これはSeq.reduce、累積値(a)とシーケンス内の次の値()を持つ関数を使用しx、この場合は製品を返します。初期値は、シーケンスの最初の要素です。
  • この製品の値をコンポーネントの数字(d)に変換します。
  • 前の数字を合計し、これをに割り当てrます。

1

Befunge、136バイト

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

ここで試してみることができます

すべてのインタープリターが十分な大きさのセルサイズを持っているわけではありませんが、ほとんどの人にとって小さな数値で動作します。多くのn場合、BefunExecのようなインタープリターが必要になる場合があります。


1

Gol> <>35 33バイト

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

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

ジョー・キングによる-2バイト。

関数と暗黙的な無限ループの広範な使用。

完全なプログラムの例と仕組み

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バイト

_ì ×ìx}gN®õ x

それを試してみてください


説明

                  :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

きちんとした、私は自分でこれを解決しようとしましたが、良い解決策を見つけられなかったので、あなたのものを見るのは面白いです。
NIT

ありがとう、@ Nit。しかし、もっと短い方法があります。
シャギー

@Nit、わかった!それでも、もっと短い方法が必要だと確信しています。
シャギー


0

PHP 7、89バイト

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

-rまたはでパイプとして実行、オンラインで試してください

  • PHPは常に文字列として入力を受け取るため、使用する必要があります +応じ~て動作するにはintにキャストする必要があります。
  • 事前インクリメントは機能しません。どこに配置しても、両方のオペランドに影響します。
  • しかし、反復の前後に1桁の数字が発生するかどうかは関係ありません(追加の反復は問題になりません)。だから私は使用できますfor()代わりにdo ... while()
  • 関数名のインライン割り当てには、PHP 7以降が必要です。
    古いPHPではもう1バイト必要ですfor($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    str_split変数にまったく割り当てないと、別のバイトが無駄になります)。



0

PowerShellコア91 101 93バイト

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

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

少しゴルフをしていません...

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

最初のステップは、整数を数字に分割することでした-整数を文字列の配列に分割することでこれを行いました。その後、オペランドを挿入し、コマンドとして文字列を評価します。次に、入力が1桁になるまで複数加算サイクルを実行するだけです。

iex はのエイリアスです Invoke-Command最初のparam位置に渡された文字列を評価。

編集:@AdmBorkBorkの要求どおりて、バイトカウントに関数ヘッダーを追加しました。また、少し計算して、反復回数の上限が< log log 10^6 < log 6 < 2ので、さらに6バイト節約できました。

x2の編集: @AdmBorkBorkは、整数を数式に変換するより簡潔な方法を見つけ、それをにパイプすることを提案しましたiex。これにより8バイト節約されました。ありがとうございました!


別のPowerShellerを見ることができてうれしいです!ただし、Function F($a){ }バイトカウントに関数定義を含める必要があると思います。ただし、の[char[]]代わりに一部を使用して保存できるはず-split''-ne''です。
AdmBorkBork

[char[]]1234=Ӓ、これは無効です。私はそれを機能させることができるかもしれませんが、今は明らかではないかもしれません。提案をありがとう!
ジェフフリーマン

申し訳ありませんが、私は明確ではなかった- [char[]]"$o"とでは|iexなくiex( )
AdmBorkBork

このヒントにより、コードの8%が削られました。驚くばかり。ありがとう!
ジェフフリーマン



0

Java 8、129バイト

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

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

説明:

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

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