折りたたみ番号


23

10進数d kとして書かれた自然数n関数を定義しましょうdkdk1d1d0は次のとおりです。

等しい隣接する数字d iがある限りdidi1、その合計によってそれらを置き換えるdi+di1左から右へ。そのような数字があった場合は、同じ手順を繰り返します。

つまり、各反復で、隣接する等しい数字のすべてのペアを貪欲に取り、それらを同時に合計で置き換えます(重複する場合は左端のペアを使用します)。

例として9988を見てみましょう。

  1. 等しい最初の隣接する数字は2つの9
  2. したがって、それらを9 + 9=18に置き換えると、1888が得られます。1888
  3. 私たちはまだ最初の左右走査であり、まだ2つの8があったので、これらを最初に置き換える必要があります
  4. 我々が得るように、1816
  5. 何かが変わったので、別の繰り返しを行う必要があります
  6. しかし、そのような数字はないので、停止します

したがって、そのシーケンスの9988th数値は1816です。

チャレンジ

最初の200の用語は次のとおりです。

0,1,2,3,4,5,6,7,8,9,10,2,12,13,14,15,16,17,18,19,20,21,4,23,24,25,26,27,28,29,30,31,32,6,34,35,36,37,38,39,40,41,42,43,8,45,46,47,48,49,50,51,52,53,54,10,56,57,58,59,60,61,62,63,64,65,12,67,68,69,70,71,72,73,74,75,76,14,78,79,80,81,82,83,84,85,86,87,16,89,90,91,92,93,94,95,96,97,98,18,10,101,102,103,104,105,106,107,108,109,20,21,4,23,24,25,26,27,28,29,120,121,14,123,124,125,126,127,128,129,130,131,132,16,134,135,136,137,138,139,140,141,142,143,18,145,146,147,148,149,150,151,152,153,154,20,156,157,158,159,160,161,162,163,164,165,4,167,168,169,170,171,172,173,174,175,176,24,178,179,180,181,182,183,184,185,186,187,26,189,190,191,192,193,194,195,196,197,198,28

あなたの仕事は、そのシーケンスを生成することです

  • n指定すると、そのシーケンスのnth数値を返します。
  • n指定すると、そのシーケンスの最初のn数値を返します
  • または、シーケンスを無期限に生成します。

0または1インデックス作成のいずれかを使用するように提出を選択できますが、どちらを指定してください。

テストケース

上記の用語を使用することもできますが、ここにいくつかの大きな用語を示します。

222 -> 42
1633 -> 4
4488 -> 816
15519 -> 2019
19988 -> 2816
99999 -> 18189
119988 -> 21816
100001 -> 101
999999 -> 181818

回答:




5

ゼリー、11バイト

DŒg+2/€FVµ¡

これは不必要に遅く、完全なプログラムです。

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

代替バージョン、12バイト

DŒg+2/€FVµƬṪ

1バイト長くなりますが、はるかに高速です。プログラムまたは関数として機能します。

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

使い方

DŒg+2/€FVµƬṪ  Main link. Argument: n (integer)

         µ    Combine the previous links into a chain. Begin a new one.
D               Decimal; yield n's digit array in base 10.
 Œg             Group adjacent, identical digits into subarrays.
   +2/€         Map non-overlapping, pairwise sum over the subarrays.
                If there is an odd number of digits in a subarray, the
                last digit will remain untouched.
       F        Flatten; dump all sums and digits into a single array.
        V       Eval; turn the result into an integer.
          Ƭ   Execute the chain 'til the results are no longer unique.
              Return all unique results.
           Ṫ  Tail; extract the last result.

11バイトバージョンでも同じことが行われますが、固定ポイントに達するまでリンクを呼び出すのではなく、入力nに対してn回リンクを呼び出します。


3
1バイトを節約できれば不要ではありません:-)
ルイスメンドー

4

Haskell、70バイト

until((==)=<<f)f
f(a:b:c)|a==b=show(2*read[a])++f c|1<2=a:f(b:c)
f a=a

入力は文字列として取得されます。

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


これまでのところ何も保存されませんが、同じ長さで2番目の句を|x<-b:c=a:f xまたはで置き換えることができます。f(a:c)=a:f cどちらかが実際に改善につながる場合に備えて:)
flawr

4

JavaScript、48 47 46バイト

文字列としての入出力。nthシーケンスの項を返します。

f=s=>s-(s=s.replace(/(.)\1/g,x=>x/5.5))?f(s):s

オンラインで試す

  • Arnauldのおかげで1バイト節約
  • tshのおかげで1バイト節約

1
x[0]*2->x/5.5
tsh

ありがとう、@ tsh。そのことを考えていなかっただろう。
シャギー

3

Perl 6、37バイト

{($_,{S:g[(\d)$0]=2*$0}...*==*)[*-1]}

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

これは、引数としてnを指定すると、シーケンスのn番目の項を生成する関数です。

($_, { ... } ... * == *)は、括弧で囲まれた式(単純な正規表現の置換)によって生成され、、* == *つまりシーケンスの最後の2つの数値が等しいときに停止する、入力番号に対する連続した変更のシーケンスです。次に、[*-1]戻り値としてそのシーケンスの最後の要素のみを受け取ります。


番号の置換は常に少ないため==**-1を削除してwith を置換することでバイトを節約できます。33バイト$_nn
ジョーキング

3

網膜、16バイト

+`(.)\1
$.(2*$1*

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

+`

入力が変化しなくなるまで繰り返します。

(.)\1

隣接する数字のペアを置換...

$.(2*$1*

... 2桁の数字。($1*の文字列を生成し$1 _2*し、それ$.(を複製し、長さを取ります。実際、Retinaエンジンはそれよりも賢く、ちょうど2倍になり$1ます。)


3

C#(.NETコア)231203200196、192のバイト

編集:機能は185バイトに加えて18になりました using System.Linq;

BMO(1> 0がtrueと改行削除に等しい)とMr. XCoder(f =!fステートメント)に感謝します!

EDIT2:最小182バイト+ 18 using System.Linq、いくつかのゴルフのヒントを共有くれたdanaに感謝します。

EDIT3:int []-> varの無知の具体化、短絡の除去&&->&、ToArrayの変更-> ToListに感謝します!(178バイト+ 18を使用)

EDIT4:無知の実施形態は、割り当てを変更することにより4バイトを落としました。ダミーは数える必要があります!再度ありがとう:D

p=>{var f=1>0;while(f){var t=p.Select(n=>n-48).ToList();p="";f=!f;for(var j=0;j<t.Count;j++){if(j<t.Count-1&t[j]==t[1+j]){p+=t[j]+t[++j];f=!f;continue;}p+=t[j];}};return p;};

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






2

05AB1E、11 バイト

Δγε2ôSO}˜J

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

Δ             # Continue until the (implicit) input no longer changes:
 γ            #  Split the integer in chunks of the same adjacent digits
              #   i.e. 199999889 → [1,99999,88,9]
  ε     }     #  Map each to:
   2ô         #   Split it into parts of size 2
              #    i.e. 99999 → [99,99,9]
     S       #   Split each part into digits
              #    i.e. [99,99,9] → [[9,9],[9,9],[9]]
       O      #   And take the sum of each part
              #    i.e. [[9,9],[9,9],[9]] → [18,18,9]
         ˜    #  Flatten the list
              #   i.e. [[1],[18,18,9],[16],[9]] → [1,18,18,9,16,9]
          J   #  Join everything together
              #   i.e. [1,18,18,9,16,9] → 118189169
              # (And output the result implicitly at the end)
              #  i.e. output = 28189169

2

Wolfram言語108バイト

ToExpression[""<>ToString/@Total/@Flatten[Partition[#,UpTo@2]&/@Split@IntegerDigits@#,1]]&~FixedPoint~#&

説明

IntegerDigits 入力番号をその数字のリストに変換します。

Split 連続する繰り返し数字をグループ化します。

Partition[#, UpTo@2]&/@ 同様の数字の実行を、最大で長さ2のリストに分割します。

Flatten[...,1] 時折過度にネストされたブレースを削除します。たとえば、{{2,2}}は{2,2}になります

Total/@ペアの数字の合計を合計します。分離された数字を合計する必要はありません。

ToString 合計(および分離された数字)を文字列に変換します。

""<> リスト内のすべての文字列を結合します。

ToExpression 結果を整数に変換します。

...~FixedPoint~#& 結果が変化しなくなるまで関数を適用します。


2

C#(Visual C#Interactive Compiler)、フラグ付き/u:System.Text.RegularExpressions.Regex、70バイト

s=>{for(;s[0]!=(s[0]=Replace(s[0],@"(.)\1",m=>m.Value[0]*2-96+"")););}

入力を変更して出力します。入力用に1つの文字列を含むリストを受け取ります。

23バイト全部をゴルフしてくれた@danaに感謝します!

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


95 + 34-33 + 1、コマンドライン引数に必要な追加スペース、iirc
ASCIIのみ

再帰的な匿名関数を最初に定義する必要があり、その定義はバイトカウントに含まれます。
無知の具現化

ああ、それは再帰的だ
ASCIIのみの

1
いいね!もう少し下げることができると思う
無知の体現

C#だと考えるとかなり良いスコアです:)
ダナ

1

クリーン、118バイト

import StdEnv,Data.List
$[a,b:t]|a==b=[1,(a*2)rem 10]%(1-a/5,1)++ $t=[a: $[b:t]]
$l=l

limit o iterate$o map digitToInt

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

最初の繰り返し値(limititerate折りたたみプロセスの単一ステップを実行するラムダのアプリケーションの無限リスト)から)します。入力として取得されます[Char]


1

84 83 80バイト

func[n][if parse s: form n[to some change[copy d skip d](2 * do d)to end][f s]s]

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

nthシーケンスの項を返します。

説明:

Red[]
f: func [ n ] [
    if parse s: form n [  ; parse the input converted to a string
        to some change [  ; find and change one or more
            copy d skip   ; digit (in fact any character, no predefined character classes)
            d             ; followed by itself
        ] (2 * do d)      ; with its doubled numeric value 
        to end            ; go to the end of the string
    ] [ f s ]             ; call the function with the altered string if parse returned true
    s                     ; finally return the string 
]


1

C#(Visual C#Interactive Compiler)、111バイト

s=>{var t=s;do{s=t;t="";for(int i=0;i<s.Length;)t+=s[i]%48*(s[i++]!=(s+0)[i]?1:2*++i/i);}while(t!=s);return t;}

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

ゴルフをするための@ASCIIOnlyへの大きなクレジット〜30;)最初は両方の更新を同時に投稿していましたが、ある時点で彼は明らかに町に行きました!

-2 @EmbodimentOfIgnoranceに感謝!

少ないコード...

// s is the input as a string
s=>{
  // t is another string used
  // to hold intermediate results
  var t=s;
  // the algorithm repeatedly
  // processes s and saves the
  // result to t
  do{
    // copy the last result to s
    // and blank out t
    s=t;
    t="";
    // iterate over s
    for(int i=0;i<s.Length;)
      // append either 1 or 2 times
      // the current digit to t
      t+=s[i]%48*
        // compare the current digit
        // to the next digit. to prevent
        // an out-of-bounds exception,
        // append a 0 to s which either
        // gets ignored or collapses
        // to 0
        (s[i++]!=(s+0)[i]
          // if they are different, then
          // the multiplier is 1
          ?1
          // if they are the same, then
          // the multiplier is 2, and we
          // have to increment i
          :2*++i/i);
  }
  // continue this until the input
  // and output are the same
  while(t!=s);
  return t;
}



@ASCIIOnly-グッドムーブ:) (s[i++]-48)*2=>s[i++]*2-96
ダナ


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