2048のような配列シフト


80

2048ゲームで行われているように配列をシフトしたいとします。配列に2つの等しい連続した要素がある場合、それらをvalue要素の2倍にマージします。Shiftは、連続する等しい要素のすべてのペアが合計で置き換えられ、ペアが交差しない新しい配列を返す必要があります。シフトは1回だけ実行されるため、結果の値を再度マージする必要はありません。例えば、ので、我々は3つの連続で同じ要素を持っている場合、我々は右端のものを合計しなければならないことに注意してください[2, 2, 2]になるべき[2, 4]ではありません[4, 2]

タスクは、配列を取り、シフトされた配列を返す最短の関数を書くことです。

すべての整数が厳密に正であると仮定できます。

例:

[] -> []
[2, 2, 4, 4] -> [4, 8]
[2, 2, 2, 4, 4, 8] -> [2, 4, 8, 8]
[2, 2, 2, 2] -> [4, 4]
[4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
[1024, 1024, 512, 512, 256, 256] -> [2048, 1024, 512]
[3, 3, 3, 1, 1, 7, 5, 5, 5, 5] -> [3, 6, 2, 7, 10, 10]

また、reduceを使用したソリューションにも非常に興味があります:)


11
これは非常に良い最初の挑戦です。サイトへようこそ!
DJMcMayhem

1
入力は必ずしもソートされておらず、数値はゼロより大きいため、数値に対する唯一の制限です。最大の値を標準のint32境界に収めることができると思います。空の配列は結果として空の配列を与えます。参加いただきありがとうございます:)
greenwolf

3
まだ不明であると投票する人々にとって、課題は本質的にこれに要約されます:正の整数の配列があると仮定します。最初から最後までウォークスルーします。現在の要素が次の要素と等しい場合、両方の合計で置き換え、置換の要素移動し、その要素と次の要素に対してこのチェックを再度実行します。配列の先頭に達するまで繰り返します。
user2428118

1
@Titus「3つの連続した等しい要素がある場合、右端の要素を合計する必要があることに注意してください。たとえば、[2、2、2]は[4、2]ではなく[2、4]になります。」
マーティンエンダー

1
空の配列に対する裁定は残念です。私自身を含むいくつかの回答が無効になっています。
デニス

回答:



19

Haskell、47 57 50バイト

e#l|a:b<-l,e==a= -2*a:b|1<2=e:l
map abs.foldr(#)[]

使用reduce(またはfoldHaskellで呼ばれるように、ここでは右折りfoldr)。使用例:map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8]

編集:ソートされていない配列でも機能するように+10バイト。マージされた数値は、2番目のマージを防ぐために負の値として挿入されます。それらはファイナルで修正され map absます。


ネガのトリックは本当に素晴らしいです!
xnor

14

Brain-Flak158 96

{({}<>)<>}<>{(({}<>)<><(({})<<>({}<>)>)>)({}[{}]<(())>){((<{}{}>))}{}{{}(<({}{})>)}{}({}<>)<>}<>

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

説明:

1リストを逆にします(すべてを他のスタックに移動しますが、それは問題ではありません)

{({}<>)<>}<>
{        }   #keep moving numbers until you hit the 0s from an empty stack
 ({}<>)      #pop a number and push it on the other stack
       <>    #go back to the original stack
          <> #after everything has moved, switch stacks

2このスタックに何もなくなるまで、手順3〜6を実行します。

{                                                                                         }

3上の2つの要素を複製します(2 3-> 2 3 2 3)

(({}<>)<><(({})<<>({}<>)>)>)

(({}<>)<>                   #put the top number on the other stack and back on the very top
         <(({})             #put the next number on top after:
               <<>({}<>)>   #copying the original top number back to the first stack
                         )>)

4上位2つが等しい場合は先頭に1を置き、それ以外の場合は0を置きます(wikiから)

({}[{}]<(())>){((<{}{}>))}{}

5上の2つが等しかった場合(上の0以外)、次の2つを追加して結果をプッシュします

{{}(<({}{})>)}{}
{            }   #skip this if there is a 0 on top
 {}              #pop the 1
   (<      >)    #push a 0 after:
     ({}{})      #pop 2 numbers, add them together and push them back on 
              {} #pop off the 0

6一番上の要素を他のスタックに移動します

({}<>)<>

7他のスタックに切り替えて暗黙的に印刷する

<>

plsは言語名の後にカンマを追加します。それ以外の場合、リーダーボードtyが壊れます:P
ASCIIのみ

9

PHP、116バイト

<?$r=[];for($c=count($a=$_GET[a]);$c-=$x;)array_unshift($r,(1+($x=$a[--$c]==$a[$c-1]))*$a[$c]);echo json_encode($r);

または

<?$r=[];for($c=count($a=$_GET[a]);$c--;)$r[]=$a[$c]==$a[$c-1]?2*$a[$c--]:$a[$c];echo json_encode(array_reverse($r));

出力がprint_r'json_encode`の代わりに配列にできる場合は-4バイト

正規表現でこれを解決するための176バイト

echo preg_replace_callback("#(\d+)(,\\1)+#",function($m){if(($c=substr_count($m[0],$m[1]))%2)$r=$m[1];$r.=str_repeat(",".$m[1]*2,$c/2);return trim($r,",");},join(",",$_GET[a]));

1
結果は常にソートされるわけではないため、ソートは使用できません。[4、4、2、8、8、2]-> [
8、2、16、2

@Crypto新しいテストケースが追加された直後です。ソートの使用が大丈夫になる前に
ヨルグヒュルサーマン

for($i=count($a=$argv);--$i;)$b[]=($a[$i]==$a[$i-1])?2*$a[$i--]:$a[$i];print_r(array_reverse($b));同じ考えだが短い
暗号

@Crypto文字列表現または配列としての出力についてはわかりません。テストケースのために[]$r=[];はあなたの助けをありがとう
ヨルグHülsermann16年


8

網膜、32

\d+
$*
r`\b\1 (1+)\b
$1$1
1+
$.&

r3行目では、右から左への正規表現マッチングがアクティブになります。そしてこれは、\1参照する(1+)キャプチャグループの前に参照が来る必要があることを意味します。

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


ナイス..右から左に一致するオプションは非常に便利です!.Net正規表現またはRetina機能の一部ですか?
ダダ

入力フォーマットとして改行区切りを使用して、私はちょうど26で鉱山を投稿しようとしていました:retina.tryitonline.net / ...主な節約はそこから生じ、音訳を使用して2番目の置換を取り除きます。
マーティンエンダー

@Dadaこれは.NET機能です(そして、任意の長さの後読みを可能にするために内部で使用されます)。Retinaには、独自の正規表現機能はまだありません(ただし、独自の置換機能がいくつかあります)。
マーティンエンダー

1
@MartinEnder OKありがとう!.NET正規表現は本当に素晴らしいです!je深いperlコーダーが発見
ダダ

@MartinEnder Iあなたのソリューションは、別の答えを保証するのに十分なほど異なっています
デジタルトラウマ

8

Perl、41バイト

+1を含む -p

STDINに入力シーケンスを与えます。

shift2048.pl <<< "2 2 2 4 4 8 2"

shift2048.pl

#!/usr/bin/perl -p
s/.*\K\b(\d+) \1\b/2*$1.A/e&&redo;y/A//d

8

Python、61バイト

def f(l):b=l[-2:-1]==l[-1:];return l and f(l[:~b])+[l[-1]<<b]

ブール bの最後の二つの要素が、彼らは、その後の乗数を付加した場合の長さ1または0の最後の要素のリストに安全だ方法で同じであることを確認することで崩壊するかどうかをチェック1等しいまたは2等しくないため。リストの再帰的な結果に追加され、その多くの要素が最後から切り取られます。1バイトのDennisに感謝します!


[l[-1]<<b]バイトを保存します。
デニス

l[-2:-1]ある[l[-2]]
mbomb007

2
サイズ0および1のリストで機能する必要があります。
xnor16年

7

Perl、43 + 1(-p)= 44バイト

トン・ホスペルは41バイトの答えを思いつきました、チェックしてください!

-4 @Ton Hospelに感謝します!

編集:追加\bそれはのような入力に失敗したことのないよう、24 4出力があったであろうその上28

$_=reverse reverse=~s/(\b\d+) \1\b/$1*2/rge

-pフラグ付きで実行:

perl -pe '$_=reverse reverse=~s/(\b\d+) \1\b/$1*2/rge' <<< "2 2 2 4 4"


reverse右折に2回 使用する以外の方法はありません(ちょうどs/(\d+) \1/$1*2/ge左折、つまりの代わりに2 2 2なり4 2ます2 4)。おかげで、14バイトが失われましたreverse...それでも、別の(より良い)方法が必要だと思います(結局perlです!)、それを見つけたら教えてください!


reverse reverse少し長いようです。私は、Perlには専門家だが、あなたはへのショートカットを作ることができる方法がありますreverse(何もない場合は、[AB]を使用してはeval)?
チョイス

素敵なセクサー。除外することができます($_)
Ton Hospel

@TonHospelありがとう。実際、reverse次のようなドキュメントはreverse引数なしで呼び出すことはできません(例では可能ですが、プロトタイプは1つしかありませreverse LISTん:)。したがって$_、デフォルト引数であることを忘れました;)
ダダ

LIST空にすることができます...
トンHospel

実際、@ TonHospelですが、通常、オペレーターが$_デフォルトの引数として使用する場合、ドキュメントはパラメーターのないプロトタイプ(printまたはlenght...など)を指定します。または多分それは私が持っている間違った印象です。
ダダ

7

JavaScript(ES6)、68バイト

f=a=>a.reduceRight((p,c)=>(t=p[0],p.splice(0,c==t,c==t?c+t:c),p),[])
    
console.log([
  [],
  [2, 2, 4, 4],
  [2, 2, 2, 4, 4, 8],
  [2, 2, 2, 2],
  [4, 4, 2, 8, 8, 2],
  [1024, 1024, 512, 512, 256, 256],
  [3, 3, 3, 1, 1, 7, 5, 5, 5, 5],
].map(f))


2
悪くはありませんが、実行されたスニペットによると:[1024, 1024, 512, 512, 256, 256]として解決され[2048, 512, 1024]てい[2048, 1024, 512]ますか?
-WallyWest

7

5.10、61 50バイト(49フラグの+ 1)

11バイトを節約してくれたTon Hospelに感謝します!

-aフラグ付きの正規表現なしのソリューション:

@a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"

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


素敵な代替方法。哀れな配列は、ほとんどの場合、perlの文字列を失います。それでも、コードをゴルフ@a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50バイト)に少し近づけることができます
トンホスペル

@TonHospel実際、私は文字列ベースのソリューションを避ける傾向があります(Perlがそれ以上のことができることを示すためだけです!)。とにかく勝つためにプレーしません:Dゴルフのヒントをありがとう!
ポールピカード

7

JavaScript(ES6)、68 65 58 57 65 64バイト

@ l4m2のおかげで1バイト節約

このような入力が予期されることが明確になったため、未ソートの配列が修正されました。

f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]

console.log(f([2, 2, 4, 4]));
console.log(f([2, 2, 2, 4, 4, 8]));
console.log(f([2, 2, 2, 2]));
console.log(f([4, 2, 2]));


1
あなたが行った編集を提案しようとしていました:)
ETHproductions

a=>(a.reverse()+'').replace(/(.),\1/g,(c,i)=>i*2).split`,`.reverse()
l4m2

@ l4m2これは1桁の入力では機能し[1024, 1024, 512, 512, 256, 256]ますが、失敗します(このテストケースは後で追加された可能性があると思います)。
アーナルド

@Arnauldまああなたも​​失敗します
...-l4m2

f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]
l4m2

6

05AB1E、26バイト

D¥__X¸«DgL*ê¥X¸«£vy2ôO})í˜

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

一般化された手順

  1. 引き算で減らして、連続する要素が異なる場所を見つけます
  2. 連続する要素の長さを見つけるために、それらの場所のインデックスを減算することにより縮小します
  3. 入力をこれらの長さのチャンクに分割します
  4. チャンクをペアに分割する
  5. 各ペアを合計する
  6. 合計したチャンクを逆順にする
  7. 1次元リストにフラット化

5

Mathematica、53バイト

Join@@(Reverse[Plus@@@#~Partition~UpTo@2]&/@Split@#)&

説明

Split@#

入力を同一の要素の実行で構成されるサブリストに分割します。すなわちに{2, 2, 2, 4, 8, 8}なり{{2, 2, 2}, {4}, {8, 8}}ます。

#~Partition~UpTo@2

各サブリストを最大で2のパーティション長に分割します。つまり、に{{2, 2, 2}, {4}, {8, 8}}なり{{{2, 2}, {2}}, {{4}}, {{8, 8}}}ます。

Plus@@@

各パーティションを合計します。すなわちに{{{2, 2}, {2}}, {{4}}, {{8, 8}}}なり{{4, 2}, {4}, {16}}ます。

Reverse

MathematicaのPartitionコマンドは左から右に行くので結果を逆にしますが、パーティションを別の方向にしたいのです。すなわちに{{4, 2}, {4}, {16}}なり{{2, 4}, {4}, {16}}ます。

Join@@

結果を平坦化します。すなわちに{{2, 4}, {4}, {16}}なり{2, 4, 4, 16}ます。


こんにちはJHM!答えてくれてありがとう。私はMathematicaをあまりよく理解していないので、何が起こっているのかについて少し説明を加えていただけますか?
isaacg

Plus@@@であるTr/@と私はあなたが括弧を避けることができると思うし、Join@@あなたが使用している場合##&@@の結果にReverse(ただし、それをテストしていません)。
マーティンエンダー

5

Java 7、133バイト

Object f(java.util.ArrayList<Long>a){for(int i=a.size();i-->1;)if(a.get(i)==a.get(i-1)){a.remove(i--);a.set(i,a.get(i)*2);}return a;}

入力はArrayListであり、逆方向にループし、必要に応じて削除して2倍にします。

Object f(java.util.ArrayList<Long>a){
    for(int i=a.size();i-->1;)
        if(a.get(i)==a.get(i-1)){
            a.remove(i--);
            a.set(i,a.get(i)*2);
        }
    return a;
}

Long3行目の参照をと比較してい==ます。検討してくださいa.get(i)-a.get(i-1)==0
ヤコブ

4

Perl、37バイト

+4を含む -0n

入力をSTDINの個別の行として実行します。

perl -M5.010 shift2048.pl
2
2
2
4
4
8
2
^D

shift2048.pl:

#!/usr/bin/perl -0n
s/\b(\d+
)(\1|)$//&&do$0|say$1+$2


4

PHP、86 100 99 94バイト

for($r=[];$v=+($p=array_pop)($a=&$argv);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);

PHP 7.0が必要です。コマンドライン引数から値を取得します。

で実行する-nr、オンラインで試してください


2
[2、2、2]は[2,4]ではなく[4,2]を返します
暗号

for($r=[];$v=($p=array_pop)($a=&$_GET[a]);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);1バイト短い
ヨルグヒュルサーマン

3

ジュリア205バイト

t(x)=Val{x}
s(x)=t(x)()
f^::t(1)=f
^{y}(f,::t(y))=x->f(((f^s(y-1))(x)))
g()=[]
g{a}(::t(a))=[a]
g{a}(::t(a),B...)=[a;g(B...)]
g{a}(::t(a),::t(a),B...)=[2a;g(B...)]
K(A)=g(s.(A)...)
H(A)=(K^s(length(A)))(A)

呼び出される関数は H

例えば H([1,2,2,4,8,2,])

これはjuliaでこれを行う最短の方法ではありません。しかし、それはとてもクールなので、とにかく共有したいと思いました。

  • t(a) は値のタイプで、値(a)を表します。
  • s(a) その値型のインスタンスです
  • gは、(値型を使用して)差分値とそのパラメーターの数をディスパッチする関数です。そしてそれはクールです
  • Kちょうど包むgように

余分なクールな部分:

f^::t(1)=f
^{y}(f,::t(y))=x->f(((f^s(y-1))(x)))

これは、^関数に適用する演算子を定義します。だからそれK^s(2)(X)は同じK(K(X)) ようHに呼び出しKているだけですK十分な時間を確かにネストされたケースを折りたたむに-倍の束

これははるかに短く行うことができますが、この方法はとても楽しいです。


3

PowerShell v2 +、81バイト

param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count..0]

入力を明示的な配列として受け取り$n、それを逆にし$n[$n.count..0]-join要素をコンマと一緒に指定します。次に-replace、最初の要素aと一致する数字ペアを正規表現*2で囲み、括弧で囲みます。結果パイプ(入力のためにどの@(2,2,4,4)ように見えるであろう(4*2),(2*2)とオーバー)iex(ショートInvoke-Expressionとに類似しeval、実際の数値に乗算を変換)。結果の配列を$bに格納し、それを括弧でカプセル化してパイプラインに配置し、で逆に$b[$b.count..0]ます。結果の要素をパイプラインに残し、出力は暗黙的です。


テストケース

NB-- PowerShellでは、空の配列を「返す」という概念は意味$nullがありません-スコープを離れるとすぐに変換されるため、何も返さないのと同等です。これは最初の例で行われていることです(いくつかのひどく冗長なエラーの後)。さらに、ここでの出力は、文字列化された配列のデフォルトのセパレーターであるため、スペースで区切られています。

PS C:\Tools\Scripts\golfing> @(),@(2,2,4,4),@(2,2,2,4,4,8),@(2,2,2,2),@(4,4,2,8,8,2),@(1024,1024,512,512,256,256),@(3,3,3,1,1,7,5,5,5,5)|%{"$_ --> "+(.\2048-like-array-shift.ps1 $_)}
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At C:\Tools\Scripts\golfing\2048-like-array-shift.ps1:7 char:67
+   param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count. ...
+                                                                   ~~~
    + CategoryInfo          : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

Cannot index into a null array.
At C:\Tools\Scripts\golfing\2048-like-array-shift.ps1:7 char:13
+   param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count. ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

 --> 
2 2 4 4 --> 4 8
2 2 2 4 4 8 --> 2 4 8 8
2 2 2 2 --> 4 4
4 4 2 8 8 2 --> 8 2 16 2
1024 1024 512 512 256 256 --> 2048 1024 512
3 3 3 1 1 7 5 5 5 5 --> 3 6 2 7 10 10

3

Javascript-103バイト

v=a=>{l=a.length-1;for(i=0;i<l;i++)a[l-i]==a[l-1-i]?(a[l-i-1]=a[l-i]*2,a.splice(l-i,1)):a=a;return a}


これは機能しません。テスト[2,2,4,4]利回り[2,2,4,4]
コナーオブライエン

1
うん。ノードv6.2.1
コナーオブライエン

私の悪い..私は同じファイル内の別のJSコードでそれを実行していましたが、グローバル変数が混同されました。
Alexis_A

3

Brain-Flak、60バイト

{({}<>)<>}<>{(({}<>)<>[({})]){((<{}>))}{}{({}<>{})(<>)}{}}<>

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

説明:

{({}<>)<>}<>   Reverse stack

{   While input exists
  (
    ({}<>)   Push copy of last element to the other stack
    <>[({})] And subtract a copy of the next element
  )   Push the difference
  {   If the difference is not 0
    ((<{}>)) Push two zeroes
  }{}  Pop a zero
  {   If the next element is not zero, i.e the identical element
    ({}<>{})  Add the element to the copy of the previous element
    (<>)      Push a zero
  }{}    Pop the zero
}<>  End loop and switch to output stack


2

ジュリア、73 82バイト

f(l)=l==[]?[]:foldr((x,y)->y[]==x?vcat(2x,y[2:end]):vcat(x,y),[l[end]],l[1:end-1])

右折を使用してリストを後ろから前に作成します(左折を使用し、リストの最初と最後を逆にすることもできます)。

現在のリストの先頭が先頭に追加する次の要素と等しくない場合は、先頭に追加します。

それ以外の場合は、リストの先頭(残酷な音)を削除し、要素に2を追加します。

f([3,3,3,1,1,7,5,5,5,5]) 
returns a new list:
[3,6,2,7,10,10]

2

ラケット166バイト

(λ(l)(let g((l(reverse l))(o '()))(cond[(null? l)o][(=(length l)1)(cons(car l)o)]
[(=(car l)(second l))(g(drop l 2)(cons(* 2(car l))o))][(g(cdr l)(cons(car l)o))])))

ゴルフをしていない:

(define f
  (λ (lst)
    (let loop ((lst (reverse lst)) 
               (nl '()))
      (cond                            ; conditions: 
        [(null? lst)                   ; original list empty, return new list;
               nl]
        [(= (length lst) 1)            ; single item left, add it to new list
              (cons (first lst) nl)]
        [(= (first lst) (second lst))  ; first & second items equal, add double to new list
              (loop (drop lst 2) 
                    (cons (* 2 (first lst)) nl))]
        [else                          ; else just move first item to new list
              (loop (drop lst 1) 
                    (cons (first lst) nl))]  
        ))))

テスト:

(f '[])
(f '[2 2 4 4]) 
(f '[2 2 2 4 4 8]) 
(f '[2 2 2 2]) 
(f '[4 4 2 8 8 2])
(f '[1024 1024 512 512 256 256]) 
(f '[3 3 3 1 1 7 5 5 5 5])
(f '[3 3 3 1 1 7 5 5 5 5 5])

出力:

'()
'(4 8)
'(2 4 8 8)
'(4 4)
'(8 2 16 2)
'(2048 1024 512)
'(3 6 2 7 10 10)
'(3 6 2 7 5 10 10)

1

Japt、12バイト

ò¦ ®ò2n)mxÃc

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

開梱と仕組み

Uò!= mZ{Zò2n)mx} c

Uò!=    Partition the input array where two adjacent values are different
        i.e. Split into arrays of equal values
mZ{     Map the following function...
Zò2n)     Split into arrays of length 2, counting from the end
          e.g. [2,2,2,2,2] => [[2], [2,2], [2,2]]
mx        Map `Array.sum` over it
}
c       Flatten the result

Jonathan AllanのJellyソリューションからアイデアを得ました


0

Mathematica、51バイト

Abs[#//.{Longest@a___,x_/;x>0,x_,b___}:>{a,-2x,b}]&

{Longest@a___,x_/;x>0,x_,b___}2つの連続する同一の正数を含むリストに一致し、これら2つの数をに変換し-2xます。Longest可能な限り遅く一致するように強制します。

プロセスはステップバイステップで説明されます:

   {3, 3, 3, 1, 1, 7, 5, 5, 5, 5}
-> {3, 3, 3, 1, 1, 7, 5, 5, -10}
-> {3, 3, 3, 1, 1, 7, -10, -10}
-> {3, 3, 3, -2, 7, -10, -10}
-> {3, -6, -2, 7, -10, -10}
-> {3, 6, 2, 7, 10, 10}

0

Vim、28バイト

G@='?\v(\d+)\n\1<C-@>DJ@"<C-A>-@=<C-@>'<CR>

正規表現が後方に一致する連続番号を検索し、それらを一緒に追加するマクロ。

入力配列は、行ごとに1つの数値である必要があります。この形式はストロークを節約しますが、それは素晴らしいことですが、本当の理由は正規表現の一致を回避することです。文字列が与えられると、重複する2番目のペアではなく、最初のペアのみに一致222する/22場合。2つのペアが異なる行で始まる場合、オーバーラップルールは異なります。このチャレンジでは[2, 2, 2]がになる[2, 4]ため、重複するペアを一致させることが重要です。

注:チャレンジでは、1つのパスのみが要求されました。そのため、が必要:set nowrapscanです。:set wrapscan私は書かれたこのソリューションは、常にそれをしないでしょうが、複数のパスでジョブを終了したバージョンを作ることができます。

  • <C-@>:通常、コマンドラインで、コマンド<CR>を実行せずにリテラルを入力するには、でエスケープする必要があり<C-V>ます。ただし、<C-@>エスケープせずに入力すると、<C-J>/ として扱われます。これは、マクロを実行したとき<NL>と同じように<CR>なりますが、入力しているときではありません。読んでみてください:help NL-used-for-Nul
  • @=:今回は、入力に一致するペアがない可能性があるため、記録されたマクロを簡単に使用できません。マクロの実行中にそれが発生した場合、検索に失敗するとマクロは失敗します。ただし、(暗黙の最初の)記録パス中に発生すると、残りの通常モードのコマンドが実行され、ファイルが破損します。欠点は@=、再帰呼び出しで1バイトを失うことです。時には@@再帰呼び出しとして使用できますが@"、この場合は4バイト前から実行されます。
  • DJ@"<C-A>-DJ行を削除し、レジスタに番号(改行なし)を入れます<C-A>。そのため、番号引数のマクロとして実行できます。私はする必要があり-、その後ので、私のようなケースでは二試合を得ることはありません[4, 2, 2]

0

Perl6、92バイト

{my @b;loop ($_=@^a-1;$_>=0;--$_) {@b.unshift($_&&@a[$_]==@a[$_-1]??2*@a[$_--]!!@a[$_])};@b}

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