En az bayt kullanarak 2048'in deterministik bir versiyonunu çözün


17

Oyunun 2048'in deterministik varyantına kazanan bir hamle dizisi oluşturan bir program yazın. Bu dizi, 0: yukarı, 1: sağ, 2: aşağı, 3: ayrıldı. Örneğin, "1132" dizesi sağ sağ sol aşağı anlamına gelir. Kazanan program 2048'e ulaşan en kısa kaynak kodudur!

Deterministik 2048 kuralları: Oyun sol üst köşede, başlangıçta 1 kiremit içeren 4x4 ızgara üzerinde oynanır. Her hareket "sol", "sağ", "yukarı" veya "aşağı" komutlarından oluşur. Sol komut ızgaradaki tüm döşemeleri sola kaydırır, ardından soldan başlayarak döşemeleri birleştirir ve toplar. Benzer şekilde, sağ komutu kutucukları sağa kaydırır, sonra sağdan başlayarak birleştirir.

Her kutucuk hamle başına sadece bir kombinasyona katılabilir.

Bir hareketten sonra, soldan ilk sütunda boş bir alan, o sütunun en üstündeki ilk boş alanda yeni bir 2 döşeme oluşturulur.

Örneğin, "sağ sağ sol aşağı" dizisi durumlara yol açar

2___
____
____
____

2__2
____
____
____


2__4
____
____
____


24__
2___
____
____


2___
____
____
44__

Sağa uygulanan komut _ 2 2 2 _ _ 2 4 ile sonuçlanır. Sağa uygulanan komut 2 2 2 2 _ _ 4 4 ile sonuçlanır.

Bu sorudan http://jmfork.github.io/2048/


2
Zorluklar kendi içinde olmalıdır - ya bu bağlantı koparsa?
Kapı tokmağı

2
Bu soru konu dışı gibi görünmektedir, çünkü bu temelde bir "yalnızca bağlantı sorusu" dur.
Kapı tokmağı

2
$(".tile-container").addItem("<div class="tile tile-2048 tile-position-3-4">2048</div>");
TheDoctor

1
@QuadmasterXLII açıklamanızda 3 ardışık (özdeş) sayı için beklenen davranışı açıklığa kavuşturabilirsiniz
Martin Ender

1
Harika! Yakın oy geri çekildi. Burada hala bir sorunum var: deterministik olduğu için, insanlar en kısa çıktıyı bulamıyor ve sonra çıktısını bulamıyor mu?
Kapı tokmağı

Yanıtlar:


26

Python, 740 karakter (665 karakter sıkıştırılmış)

Kod :

R=range
G=lambda:[[0]*4for _ in R(4)]
J=[(0,4,1),(2,-1,-1),(1,4,1)]
H=[0,-1,1]
def M(P,d):
 C=G();g,z=[(0,-1),(1,0),(0,1),(-1,0)][d];Q=H[g];W=H[z]
 while 1:
    N=[r[:]for r in P]
    for x in R(*J[g]):
     for y in R(*J[z]):
        s=N[y][x];q,w=y-W,x-Q;d=N[q][w];a,b,c=(((0,s,d),(1,0,s+d))[s==d],(0,0,s or d))[s<1 or d<1];
        if 2-a-(C[y][x]+C[q][w]>0):N[y][x]=b;N[q][w]=c;C[q][w]+=a
    if N==P:break
    P=N
 return N
def F(N):
 for x in R(4):
    for y in R(4):
     if N[y][x]==0:N[y][x]=2;return N
def Z(P,i):
 X=[d for d in R(4)if M(P,d)!=P]
 return i==0and(sum((256,c)[c>0] for v in P for c in v)+P[3][3]*10+P[3][2]*9,-1)or max((Z(F(M(P,d)),i-1)[0],d)for d in X)if X else(-1,-1)
B=G()
B[0][0]=2
h=''
while B[3][3]!=2048:_,X=Z(B,4);h+=`X`;B=F(M(B,X))
print h

(Birkaç bayt kaydetmek için sekmeleri girinti için boşluklarla karıştırır)

Sadece yukarıdaki kodu sıkıştırırsam, base-64 kodlar ve execsadece 665 karakter olduğu için golf emdi gerekir . Aşağıdakiler tam olarak yukarıdakine eşdeğerdir, sabit kodlu bir çözüm veya herhangi bir şey yoktur:

exec"""eJxVUl1vozAQfMa/wn2qnRjJcNzpDnf7QKS2qlRE+1IUy2oJkARdwl2hbT5+/a0NiXqSZXYH78zY
u0/QFe2qJrewKbaLqoi1lmYSLf909IU2LX1iETfkHjSTIhIBFywUfoALo8AhhtyBlhYMDKnqJX1g
mah4TOgMbhlXK3F01WOJxF06It8mRldGPcKdXhn1jJ+jIXS3bjY1DWLipaA7HRvrprNuMkM8m+wH
a5N7LEMlj1rwcAaPDvR6SPXB6L1Rb2IHB/9Z7P1HVSH6ZvTOqEIsRAmMoZ8eHTt3op9WnOseoDLW
KAIUuR12FbjwKjAK2ZslDf3CZ7NBYzobWK8lj0dZWKhRCko1/p5CQWxpCpDFi64ufhMvg5TQrn7/
6Fqauie8Yal9wC9XjeyNvtzS5dQSjVogz7Kh+o9sjv1oLF0OunKc1YmjOXXrAvBpTx4aJCvaivUf
W8bC7z9EyXV5LY2r/XR9cGFpw08+zfQ3g2sSyCEMzeSXbTce2RZ7xubshg0yXDSI44RhfDaSWxs5
rTd9zYbRIomdHJLgQVwQkjVcXpJhLJJB7AJCGf2MX0QOc5aIiKv1FF7zV5WAFUtEzjn52zXtO13/
AwRvylc=""".decode('base64').decode('zip')

Cevap :

1111-hareket sırasını bulmak için ~ 47 saniye (17 saniye hareketsiz) alır:

2221230232213120120232222222221221203211012312310123123101223113322222123230210302321222323223212322101202323123322032132021233212312332023123312111123231223113312312322312232123222021221332111332221012222312222302232021233212312332023212222222123221202332023120312123223221232232222222122122323222222212212232222222221322233231222322200232122312232313132022322212312332121332312320212211332312323223212320232322322133223213212323202123123321231313332122232310112113322212323222220130231233211313332122232312312223232231231232312222220232212312220212232312232123222021221332111332221012222312222302232021233212312332023212222222123221202332023120312123223221322323223312230230323312232313133232223233212312323123323222332222222132221321320323233223232121323212232013221323233032021223320231233220322203132123202123321231233202131321221111231213232131210212312232332132103123130213133213232213321323212332332212222123323322202302333121220222323232113123323221223032131201123212133123131222323313133313300123231332011222221223232331313313112312113230231121232332122323232321312323213212232313212323211330231231012

Aşağıdaki son tahta pozisyonu ve hamlesiyle:

   4    2   16    4
   2    8  128    8
   2    .    . 1024
   .    .    . 1024
Best move: s, with EV=25654

Diğer bilgiler: Çözelti gzip edilmiş 309 bayt ve gzipli ve base64 kodluysa 418 bayttır. Böylece, sadece kodunu çözmek ve yazdırmak için daha kısa bir program olurdu, ama bu hiç de eğlenceli değil .

Açıklama :

İşte her hareketten sonra tahtaya baskı yapan ungolfed versiyonun bir macunu , izlemek çok eğlenceli!

Çok basit bir kaba kuvvet AI. Her kart konumu için bir EV atar:

ev =   256 * number of spaces 
     + sum_of_values 
     + 10 * board_bottom_right 
     +  9 * board_bottom_2nd_right

Önce dört hamle önce derinlik araması yapar ve dört hamlede en yüksek EV'ye giden yolu seçer. Ev işlevi, tahtayı temizlemeye ve en değerli parçaları köşede tutmaya teşvik eder, bu da oldukça optimal olur. Oraya ulaşmak yeterli!

EV işlevini diğer tahta noktalarına daha yüksek bir değer verecek şekilde değiştirirseniz, aşağıdakine benzer:

1  1  1  1
1  1  1  1
1  1  9 10
1  9 10 11 

Bu işlev onu şu şekilde elde eder:

   2    8    4    2
  16   32   64   16
  64  128  512 1024
   2  256 2048 8192

16 k :

Eureka! 4 yerine 5 adımlı bir ileriye ve aşağıdaki ağırlığa sahip:

1  1  4  4 
1  1  4 10
1  1 14 16
1 16 18 20 

Neredeyse 32k oluyor ve bitiyor:

   2  128    4     2
  64  256  512     4
   4  128 1024  4096
  16 2048 8192 16384

Dizi burada .

32k :

Evet bayanlar ve baylar, 32k markasını vurduk. EV işlevi, kareleri bir sabitle çarpmak yerine, her kareyi aşağıdaki güçlere yükseltir ve ekler. xmeydanın dahil olmadığı anlamına gelir:

x x x 3
x x x 4 
x x 5 6
x 6 7 8

Yine de tüm değerleri bir kez toplar ve her boş kare için 256 ekler. Lookahead 32k'ye kadar 4'dü ve sonra 5'e kadar çıkmıştı, ama gerçekten fazla bir şey yapmıyor gibi görünüyor. Bitiş kartı:

   2  128    8     2
  64  256  512     4
   4  128 1024  2048
  16 4096 8192 32768

24.625-hamle dizisinin hamurundan .


1
Bu çözüm mükemmel (kaba kuvvetinizi + ileriye dönük DFS'yi seviyorum), destansı bir açıklama ve her zamankinden daha yüksek iki güç için arayışınız en mükemmel. 1!
ProgrammerDan

Güzel! Derinlikli bir sezgisel tarama kullanmak, öncelikle en uygun çözümlere (en kısa hareket sırası) ulaşmanızı engeller. Belki bir * arama :-) dahil edebilirsiniz
Mau

tar -xzvf atar; python a
TheDoctor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.