この数字は2048の良いコンボになりますか?


12

xkcdに触発されました。

あなたの課題は、ゲーム2048で数字が良い組み合わせになるかどうかを判断することです。入力は次のような数字になります。

8224

そして、出力はその数は、この入力のためになる良い2048コンボ、になるだろうかどうだろうtrueyesまたは1または陽性の結果を示す任意の他の方法を。

ゲームに慣れていない人のために、簡単な説明があります[2] [2]。次のように、2のべき乗がグリッド上に配置されています。タイルは任意の方向に移動でき、2つの同一のタイルが出会うと、それらは次の2の累乗になります([2] [2]左または右に移動するとになります[4])。または、ここでゲームを試すことができます

「良い2048の組み合わせ」とはどういう意味ですか?これは、ゲーム内で「2048」であった場合、1つの数字に結合できる任意の数字を意味します。(ゼロは空のスペースを意味し、必要に応じて無視できます。)数字が複数の桁になる可能性があることに注意してください!ただし、数字は移動ごとに変更してはなりませ。次に、いくつかの例/テストケースを示します(「良い」は良い組み合わせを示し、「悪い」は良くないことを意味します)。

  • 良い:8224(8224-> 844-> 88-> 16)
  • 良い:2222(2222-> 44-> 8)
  • 良い:22048(22048-> 448-> 88-> 16)
  • 悪い:20482(外側の2を組み合わせることはできず、2048と2を組み合わせることもできません)
  • 良い:20482048(20482048-> 4096)
  • 悪い:210241024(210241024-> 22048ですが、これは[2] [2048]になり、数字は移動ごとに変更できないため、結合できません)
  • 良い:2048(すでに1つの番号です)
  • 悪い:2047(2のべき乗ではありません)
  • 悪い:11(ゲームに1はありません)
  • 良い:000040000000(ゼロは空のスペースです)

その他の規則:

  • 入力は、合理的な場所(STDIN、関数の引数、ファイルなど)から行うことができます。
  • 出力は、合理的な場所(STDOUT、関数の戻り値、ファイルなど)でもかまいません。
  • グリッドサイズを無視します- 22222222それでもtrueが出力されるはずです。
  • 2の累乗である限り、sの数に上限はありません。したがって、可能な数は0より大きい2の累乗です。
  • あいまいさの原因となるゼロが心配な場合は、そうではありません。たとえば、またはの22048いずれかとして解析できます。最初のものは機能しませんが、2番目のものは機能するため、trueを出力する必要があります。[2] [2048][2] [2] [0] [4] [8]
  • これはなので、バイト単位の最短コードが勝ちます!

2
サーバーが回答を提供し、そこから入力ダウンロード回答をアップロードすることはできますか?合計ダウンロードバイトは1
ブライアンチェン14年

4
@Geobits 2048は、すでに1つまたは4つの数字として曖昧です。
ジョンドヴォルザーク

3
ゼロは空のスペースを意味するものではありません。1024は合法的な番号ですか?私の意見では、空のスペースは明確でなければなりません。したがって、空のスペースを使用しても問題になりません。
タル14年

7
3番目の例は22048出力するはずですgoodが、そうではありません。あなたはコンバイン傾ける22048、グリッドがある4x4すべての数字は、あなたが5個の細胞を得るでしょう別々である必要があります。だから多分あなたは削除する必要があり0ますか?また、あなたの第五の例では、ゲームがで停止しますので、無効のようです2048:)
Teunプロンク

2
@undergroundmonorailゲーム内に4096個のタイルがあることを確認できます。
ケンドールフレイ

回答:


0

GolfScript、137文字

[0`]1$,4*,{2\)?`}%+:W;[]\]][]\{{:A;W{A 1=\?!},{[.A~@,>\@~+\].~!{0-.,/@+\0}*;}%~}%.}do+.{~}%,{{.-1%}%.&{[{.2$={+)}*}*]{1|(}%}%}*{,1=},!!

入力はSTDINで指定する必要があります。出力は、不良/良好な数値の場合は0/ 1です。可能な入力を解析するには、ほとんどのコードが必要です。

この短いバージョン(113文字)は、などの入力に対して正しく機能しない単純なシフトテストを実行します224422

[0`]1$,4*,{2\)?`}%+:W;[]\]][]\{{:A;W{A 1=\?!},{[.A~@,>\@~+\].~!{0-.,/@+\0}*;}%~}%.}do+{W{~[.:S]/[S.+]*}/,1=},!!

すべてのテストケースはオンラインで確認できます


3

Python:457 422文字

z=range
def c(n):
 for x in z(1,12): 
  if int(n)==2**x:return 1
 return 0
def p(s):
 if s=='':return[]
 for i in z(len(s),0,-1):
  if c(s[:i])>0and p(s[i:])!=1:return [int(s[:i])]+p(s[i:])
 return 1
def r(a):
 if len(a)==1:return 1
 i,t=1,a[:1]
 while i<len(a):
  if a[i]==t[-1]:t[-1]*=2
  else:t+=[a[i]]
  i+=1
 if len(t)==len(a):return 0
 return r(t) 
def f(s):
 if p(s)==1or r(p(s))==0:print('bad')
 else:print('good')

関数f(s)は数字の文字列を取得し、それに応じて「良い」または「悪い」を出力します。0はスペースとして使用しないことを選択しました。スペースはゲームでは意味がなく、文字列を解析するときにあいまいさが生じるからです(22048が良いのか悪いのか)。これは2048までの数字のみを使用しますが、文字を追加せずに変更できます。10文字程度のコストで、数字を結合するすべてのステップを印刷することもできます。そして、このコードはまだ十分ではありません。心配しないで、編集中です。


スペースとタブトリックを使用して、インデントの一部の文字を保存できます。だからマークダウンはそれを壊します。
gcq 14年

Python 3.xでは動作しないと思います。できることはたくさんありますが、そのHaskellの答えに対抗できるかどうかはわかりません:)
タル

うん、私はそれを忘れていました。
gcq 2014年

2

ハスケル: 285 254 253 237 230 227

使用法-ghciにロードし、文字列をhに渡します。

*Main> h "210241024"
False
*Main> h (replicate 1024 '2') -- very long string
True
*Main> h (replicate 1023 '2') -- odd one out
False

コード:

t=i 0
i n=mod n 2<1&&(n<3||i(div n 2))
a%[]|i a=[[a]]|t=[];a%(b:c)=[a:d|d<-b%c,i a]++(a*10+b)%c
c(0:a)=c a;c(a:b:d)|a==b=(a+a):c d|t=a:c(b:d);c a=a
l a=c a/=a&&(g.c)a
g[a]=t;g a=l a||(l.reverse)a
h b=any g$0%(map(read.(:[]))b)

解説:i数値が2のべき乗であるかどうかをチェックします。これは、少しいじる言語によって無視されます。%2または0の累乗のリストであるすべての解析を再帰的に生成しますc。タイルを折りたたみます。lタイルが折り畳み可能かどうかを再帰的にテストします。gタイルが左または右に折りたたみ可能かどうかをテストします。タイルの数に制限はありません。たとえば、h ((show (2^200))++(show (2^200)))「1606938044258990275541962092341162602522202993782792835301376」とマークされた2つのタイルに対してtrueを返します。

右側の「88222288888」が正しく折りたたまれなかったが、ゴルフの機会が増えたというバグを修正するために編集されました。


2

Perl、175-336バイト

while(<>){chomp;$n="nothing";$\=("."x(1+/^[2048]+$/+/^((\d+)0*\2)+$/+((sprintf"%b",
$_)!~/1.*1/)))."\n";($o=$\)=~y/.\n/oh/;print$o;$m=length;for$i(1..$m){$a=$_;$r=
qr((\d*[2468])0*\2)0*/;($b=substr$a,0,$i,"")=~s/$r/$2+$2/ge;@n=$"="$b$a";push@n,$"while$"
=~s/$r/$2+$2/ge;($"%2&&next)||($">>=1)while$">1;$n="nice";(print)for@n;last}print$n}

必要なものだけをそのままにしておく:

$_=shift;$m=length;for$i(1..$m){$a=$_;$r=qr/((\d*[2468])0*\2)0*/;($b=substr$a,0,$i,"")=~
s/$r/$2*2/ge;$"="$b$a";1while$"=~s/$r/$2*2/ge;($"%2&&next)||($">>=1)while$">1;exit}die;

1

ああ.. 1 ...すてきな..

2

ああ... 2 ...いい...

22

ああ... 22 ... 4 ...いい...

42

ああ..何もない..

422

ooh .. 422 .. 44 .. 8 .. nice ..

322

ああ。何もない。

336

ああ。何もない。

4224

ああ..何もない..

4228

ooh .. 4228 .. 448 .. 88 .. 16 .. nice ..

16022481602248

ooh .. 1604481602248 .. 16088160448 .. 1601616088 .. 3216016 .. 3232 .. 64 .. nice ..

[ 64と256は、貪欲なマッチングでは対処できない解決不能なあいまいさをもたらしますが、これらは素晴らしいバイトカウントです。]

2048

ああ... 2048 ...いい...


1

デルファイ 572 582文字

編集されたコード、制限は2 ^ 30に設定されているため、DelphiのMaxInt値を超えません。

ゴルフ

uses SysUtils,Classes;var t,j,c:integer;s,n:string;L:TStringList;function p(x:string):boolean;var r,i:int64;begin if x='0'then exit(1>0);i:=2;r:=StrToInt(x);while i<r do i:=i*2;p:=i=r;end;begin read(s);t:=0;L:=TStringList.Create;j:=1;while j<=Length(s)do begin for c:=9downto 1do begin n:=copy(s,j,c);if p(n)then break;end;if n>'0'then L.Add(n);j:=j+Length(n);end;for j:=0to L.Count-1do t:=t+StrToInt(L[j]);j:=0;repeat if j=L.Count-1then break;if L[j]=L[j+1]then begin L[j]:=IntToStr(StrToInt(L[j])*2);L.Delete(j+1);j:=0;end else inc(j);until L.Count=1;write(strtoint(L[0])=t);end.

非ゴルフ

uses
  SysUtils,
  Classes;

var
  t,j,c:integer;
  s,n:string;
  L:TStringList;
  function p(x:string):boolean;
  var
    r,i:int64;
  begin
    if x='0'then exit(1>0);
    i:=2;r:=StrToInt(x);
    while i<r do
      i:=i*2;
    p:=i=r;
  end;
begin
    read(s);
    t:=0;L:=TStringList.Create;
    j:=1;
    while j<=Length(s)do
    begin
      for c:=9downto 1do
      begin
        n:=copy(s,j,c);
        if p(n)then break;
      end;
      if n>'0'then L.Add(n);
      j:=j+Length(n);
    end;
    for j:=0to L.Count-1do
      t:=t+StrToInt(L[j]);
    j:=0;
    repeat
      if j=L.Count-1then break;
      if L[j]=L[j+1]then
      begin
        L[j]:=IntToStr(StrToInt(L[j])*2);
        L.Delete(j+1);j:=0
      end
      else
        inc(j);
    until L.Count=1;
    write(strtoint(L[0])=t);
end.

編集

それで、私はこれらの組み合わせのどれがパズルに合うか不思議に思って、それをテストしました。

また好奇心others盛な他の人のために、テストを行います;)

ただし、結果は次のとおりです。
20736 combinations were tested and 1166 were great combinations

私は(作るには右感じる?)3つの以上のゼロで組み合わせがスキップされたと言わなければならない
組み合わせが組み合わせを意味し、ほとんどユニークで224882248422および4228すべての偉大な組み合わせとしてカウントしました。


1

Mathematica-218バイト

f=MemberQ[DeleteCases[Map[FromDigits,l~Internal`PartitionRagged~#&/@Join@@Permutations/@IntegerPartitions@Length[l=IntegerDigits@#],{2}],{___,x_,___}/;!IntegerQ[2~Log~x]||x<2]//.{a___,x_,x_,b___}:>{a,2x,b},{_Integer}]&

ゴルフされていないバージョン:

f[n_] := MemberQ[
  DeleteCases[
      Map[
        FromDigits, 
        Internal`PartitionRagged[l, #] & /@ 
          Join @@ Permutations /@ IntegerPartitions[Length[l = IntegerDigits[n]]], 
        {2}
      ],
      {___, x_, ___} /; x < 2 || ! IntegerQ[2~Log~x]
    ]
  ] //. {a___, x_, x_, b___} :> {a, 2 x, b}, 
  {_Integer}
]

Internal\PartitionRagged`の魔法をから取得され、この質問

このソリューションは、任意のグリッドサイズと任意の大きな数値を処理します。

これは、最大4タイルのみで実際のゲームのように機能する195バイトバージョンです(そうf[22222222]ですFalse)。

f=MemberQ[(d=DeleteCases)[d[ReplaceList[IntegerDigits@#,{a__,b___,c___,d___}:>FromDigits/@{{a},{b},{c},{d}}],0,2],{___,x_,___}/;!IntegerQ[2~Log~x]||x<2]//.{a___,x_,x_,b___}:>{a,2x,b},{_Integer}]&

私が交換した場所

Map[
  FromDigits, 
  Internal`PartitionRagged[l, #] & /@ 
    Apply[
      Join, 
      Permutations /@ IntegerPartitions[Length[l = IntegerDigits@#]]
    ], 
  {2}
]

ReplaceList[
  IntegerDigits[n], 
  {a__, b___, c___, d___} :> FromDigits /@ {{a}, {b}, {c}, {d}}
]

これに私のコードと同じバグがあるかどうか疑問に思っています- DeleteCases左端のペアを削除するように見えるので、f[88222288888]失敗しますか?
バザーグ14年

@bazzarghいいえ、DeleteCases2の累乗ではないゼロと数字を削除します。ペアの実際の折りたたみは//. {a___, x_, x_, b___} :> {a, 2 x, b}、その番号とその逆に対して機能するルールによって行われます。実際、Mathematicaがそれらの置換を適用する順序については完全にはわかりませんが、動作します。
マーティンエンダー14年

1

ハスケル-260263

import Data.Bits
p[x]=[[[x]]]
p(x:s)=do r@(h:t)<-p s;[[x]:r,(x:h):t]
q=filter(and.map(\n->(n::Integer)/=1&&n.&.(-n)==n)).map(filter(/=0)).map(map read).p
c(x:y:s)
 |x==y=2*x:c s
 |True=x:(c$y:s)
c x=x
r[x]=True
r l=c l/=l&&(r(c l)||r(c$reverse l))
f=or.map r.q

f関数です。例:

> f"22228"
True
> f"20482044"
False

簡単な説明:
pリストを分割するすべての方法を返します。
q2のべき乗のみで構成されるものをフィルタリングします(1を除き、0を含む)。
c文字列を折りたたみます。
r残りの要素が1つになるまで、または文字列が折りたたみ不可能になるまで、左右の折りたたみを繰り返します。


いいね cただし、バグがあります。「222244442222」を試してください-これはtrueを返しますが、ゲームでは折り畳みできません。で再帰する必要があり(2*x):c sます。
バザーグ14年

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