Apakah angka ini menghasilkan kombo 2048 yang bagus?

12

Terinspirasi oleh xkcd .

Tantangan Anda adalah menentukan apakah angka akan membuat kombinasi yang baik di game 2048 . Masukan Anda akan berupa angka, seperti:

8224

Dan hasilnya adalah apakah angka itu akan menjadi kombo 2048 yang baik, yang untuk input ini akan menjadi trueatau yesatau 1atau cara lain untuk menunjukkan hasil positif.

Bagi yang belum terbiasa dengan permainan, inilah penjelasan sederhana: kekuatan dari dua disusun pada grid, seperti ini: [2] [2]. Ubin dapat dipindahkan ke segala arah, dan jika dua ubin identik bertemu, mereka menjadi kekuatan berikutnya dari dua (jadi [2] [2]ketika dipindahkan ke kiri atau kanan menjadi [4]). Atau, Anda bisa mencoba permainannya di sini .

Apa yang dimaksud dengan "kombinasi 2048 yang baik"? Itu berarti angka apa pun yang, jika ada dalam game "2048", itu bisa digabungkan menjadi satu nomor tunggal. (Nol berarti ruang kosong , dan dapat diabaikan jika diperlukan.) Perhatikan bahwa angka bisa jadi beberapa digit! Namun, angka-angka tidak boleh berubah di antara gerakan. Berikut adalah beberapa contoh / kasus uji (dengan "Baik" menunjukkan kombinasi yang baik, dan "Buruk" yang berarti tidak baik):

  • Bagus: 8224 (8224 -> 844 -> 88 -> 16)
  • Bagus: 2222 (2222 -> 44 -> 8)
  • Bagus: 22048 (22048 -> 448 -> 88 -> 16)
  • Buruk: 20482 (tidak dapat mengombinasikan 2 bagian luar, Anda juga tidak dapat menggabungkan 2048 dan 2)
  • Bagus: 20482048 (20482048 -> 4096)
  • Buruk: 210241024 (210241024 -> 22048, tapi ini sekarang [2] [2048] dan tidak dapat digabungkan karena angka tidak dapat berubah di antara gerakan)
  • Bagus: 2048 (sudah satu nomor)
  • Buruk: 2047 (ini bukan kekuatan 2)
  • Buruk: 11 (tidak ada angka 1 di game)
  • Bagus: 000040000000 (nol adalah ruang kosong)

Aturan lain-lain:

  • Input dapat dari mana saja masuk akal, yaitu STDIN, argumen fungsi, file, dll.
  • Output juga bisa masuk akal, yaitu STDOUT, nilai pengembalian fungsi, file, dll.
  • Abaikan ukuran kisi - 22222222masih harus menampilkan true.
  • Jumlahnya tidak maksimal untuk angka apa, asalkan kekuatan dua. Oleh karena itu angka yang mungkin adalah kekuatan dua lebih besar dari 0.
  • Bagi mereka yang khawatir tentang nol yang menyebabkan ambiguitas, bukan itu masalahnya. Misalnya, 22048dapat diuraikan sebagai salah satu [2] [2048]atau [2] [2] [0] [4] [8]. Yang pertama tidak berfungsi, tetapi yang kedua tidak, jadi seharusnya hasilnya benar.
  • Ini adalah , jadi kode terpendek dalam byte akan menang!
Gagang pintu
sumber
2
dapatkah saya memiliki server yang menyediakan jawaban dan hanya mengunggah jawaban unduhan input darinya? total byte yang diunduh adalah1
Bryan Chen
4
@ Geobits 2048 sudah ambigu baik sebagai satu atau empat.
John Dvorak
3
Nol seharusnya tidak berarti ruang kosong; adalah 1024 nomor resmi atau tidak? Ruang kosong seharusnya tidak ambigu ... dan karenanya memiliki semuanya sama sekali tidak berkontribusi pada pertanyaan, menurut saya.
Tal
7
Contoh ketiga Anda menunjukkan 22048output goodtetapi itu tidak benar. Anda tidak dapat menggabungkan 2dengan 2048dan kisi adalah 4x4jika semua angka harus terpisah Anda akan mendapatkan 5 sel. jadi mungkin Anda harus menghapus 0? Juga contoh ke-5 Anda tampaknya tidak valid karena permainan berhenti pada 2048:)
Teun Pronk
2
@undergroundmonorail Saya bisa mengkonfirmasi ada 4096 ubin dalam permainan.
Kendall Frey

Jawaban:

0

GolfScript, 137 karakter

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

Masukan harus diberikan pada STDIN. Outputnya adalah 0/ 1untuk angka buruk / baik. Sebagian besar kode diperlukan untuk mengurai input yang mungkin.

Versi yang lebih pendek ini (113 karakter) melakukan tes pergeseran sederhana yang tidak akan berfungsi dengan benar untuk input seperti 224422.

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

Semua test case dapat diperiksa online .

Howard
sumber
3

Python: 457 422 karakter

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')

Fungsi f mendapat string angka dan menghasilkan 'baik' atau 'buruk'. Saya memilih untuk tidak menggunakan 0 sebagai spasi karena spasi tidak berarti dalam permainan dan mereka menciptakan ambiguitas ketika mengurai string (apakah 22048 baik atau buruk?). Ini hanya menggunakan angka hingga 2048, tetapi itu dapat diubah tanpa menambahkan karakter. Dengan biaya 10 karakter atau lebih saya juga dapat mencetak semua langkah menggabungkan angka. Dan saya menyadari bahwa kode ini belum cukup golf; jangan khawatir, suntingan akan datang.

Tal
sumber
Anda dapat menggunakan trik spasi dan tab untuk menyimpan beberapa karakter di lekukan. Penurunan harga SO akan mematahkannya.
gcq
Saya pikir itu tidak berfungsi pada Python 3.x. Ada cukup banyak yang bisa saya lakukan, tetapi tidak yakin saya bisa bersaing dengan jawaban Haskell :)
Tal
Ya, saya lupa tentang itu.
gcq
2

Haskell: 285 254 253 237 230 227

penggunaan - hanya memuatnya ke ghci, dan meneruskan string ke h.

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

Kode:

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)

Komentar: iadalah cek jika angka berkekuatan 2, ini akan dikalahkan oleh bahasa dengan sedikit twiddling. %secara rekursif menghasilkan semua parses yang merupakan daftar kekuatan 2 atau 0. petak cruntuh. ltes secara rekursif jika ubin dilipat ke kiri atau bagus. gmenguji apakah ubin dilipat ke kiri atau kanan. Tidak ada batasan angka pada ubin - mis. h ((show (2^200))++(show (2^200)))Mengembalikan true untuk 2 ubin bertanda "1606938044258990275541962092341162602522202993782792835301376".

Diedit untuk memperbaiki bug yang tidak benar-benar runtuh "88222288888" di sebelah kanan, tetapi juga menemukan lebih banyak peluang bermain golf.

bazzargh
sumber
2

Perl, 175-336 byte

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}

Menjaga hal-hal penting tetap utuh:

$_=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

ooh .. 1 .. bagus ..

2

oooh ... 2 ... bagus ...

22

oooh ... 22 ... 4 ... bagus ...

42

ooh .. tidak ada ..

422

ooh .. 422 .. 44 .. 8 .. bagus ..

322

oh tidak ada.

336

oh tidak ada.

4224

ooh .. tidak ada ..

4228

ooh .. 4228 .. 448 .. 88 .. 16 .. bagus ..

16022481602248

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

[ 64 dan 256 menyebabkan beberapa ambiguitas yang tidak dapat diselesaikan dengan baik sehingga pencocokan serakah tidak dapat mengatasi ... tetapi ini adalah jumlah byte yang bagus . ]

2048

oooh ... 2048 ... bagus ...

pengguna130144
sumber
1

Delphi 572 582 karakter

Kode yang diedit, batas ditetapkan ke 2 ^ 30 sehingga tidak akan melebihi nilai MaxInt dalam Delphi.

Golf

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.

Tidak disatukan

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.

EDIT

Jadi saya jadi penasaran dan bertanya-tanya berapa banyak dari kombinasi ini yang cocok dengan teka-teki dan menjalankan tes itu.

Bagi yang lain yang juga penasaran, buat tes juga;)

Tapi ok inilah hasilnya:
20736 combinations were tested and 1166 were great combinations

Saya harus mengatakan kombinasi dengan 3 atau lebih nol dilewati (merek merasakan kan?)
Kombinasi hampir unik, yang berarti kombinasi 2248, 8224, 8422dan 4228semua dihitung sebagai kombinasi yang hebat.

Teun Pronk
sumber
1

Mathematica - 218 byte

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}]&

Versi tidak disatukan:

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

The Internal\PartitionRagged` sihir diambil dari pertanyaan ini .

Solusi ini menangani ukuran grid sembarang dan jumlah besar sembarang.

Ini adalah versi 195 byte yang berfungsi seperti gim sebenarnya dengan hanya hingga 4 ubin (begitu f[22222222]juga 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}]&

di mana saya telah diganti

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

dengan

ReplaceList[
  IntegerDigits[n], 
  {a__, b___, c___, d___} :> FromDigits /@ {{a}, {b}, {c}, {d}}
]
Martin Ender
sumber
Hanya ingin tahu apakah ini memiliki bug yang sama dengan kode saya - DeleteCasessepertinya ia menghilangkan pasangan paling kiri, jadi f[88222288888]apakah akan gagal?
bazzargh
@ Bazzargh tidak, DeleteCaseshanya menghapus nol dan angka yang bukan kekuatan dua. Runtuhnya pasangan yang sebenarnya dilakukan oleh aturan //. {a___, x_, x_, b___} :> {a, 2 x, b}, yang bekerja untuk nomor itu dan sebaliknya. Saya sebenarnya tidak sepenuhnya yakin tentang urutan Mathematica menerapkan penggantian itu, tetapi berhasil.
Martin Ender
1

Haskell - 260 263

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

fadalah fungsinya. Contoh:

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

Penjelasan kecil:
pmengembalikan semua cara untuk membagi daftar.
qmemfilter yang terdiri dari hanya kekuatan 2 (tidak termasuk 1 tetapi termasuk 0).
cmencoba meruntuhkan string.
rberalih collapsion kanan dan kiri hingga hanya ada 1 elemen yang tersisa, atau string tidak dapat dicairkan.

mniip
sumber
Bagus. Ada bug di cdalamnya, coba "222244442222" - itu mengembalikan true, tapi itu tidak bisa diciutkan dalam permainan. Perlu diulang (2*x):c s.
bazzargh
@bazzargh diperbaiki
mniip