Giải quyết một phiên bản xác định của năm 2048 bằng cách sử dụng ít byte nhất


17

Viết chương trình tạo ra một chuỗi các bước di chuyển chiến thắng đến biến thể xác định của trò chơi 2048. Chuỗi này phải ở dạng một chuỗi các số 0-3, với 0: lên, 1: phải, 2: xuống, 3: trái. Ví dụ: chuỗi "1132" có nghĩa là phải từ trái sang phải. Chương trình chiến thắng là mã nguồn ngắn nhất đến năm 2048!

Các quy tắc để xác định 2048: Trò chơi được chơi trên lưới 4 x 4 ban đầu chứa 1 ô ở góc trên bên trái. Mỗi di chuyển bao gồm lệnh "trái", "phải", "lên" hoặc "xuống". Lệnh bên trái trượt tất cả các ô trên lưới sang bên trái, sau đó kết hợp và tính tổng như các ô bắt đầu từ bên trái. Tương tự như vậy, lệnh bên phải trượt gạch sang phải, sau đó kết hợp bắt đầu từ bên phải.

Mỗi ô chỉ có thể tham gia vào một kết hợp cho mỗi lần di chuyển.

Sau khi di chuyển, một ô 2 mới được tạo trong cột đầu tiên từ bên trái với một không gian có sẵn, trong không gian có sẵn đầu tiên từ trên cùng trong cột đó.

Ví dụ: chuỗi "phải từ trái sang phải" dẫn đến các trạng thái

2___
____
____
____

2__2
____
____
____


2__4
____
____
____


24__
2___
____
____


2___
____
____
44__

Quyền được áp dụng cho hàng _ 2 2 2 kết quả trong _ _ 2 4 Lệnh được áp dụng cho hàng 2 2 2 2 kết quả trong _ _ 4 4

Câu hỏi này lấy cảm hứng từ http://jmfork.github.io/2048/


2
Những thách thức nên được khép kín - điều gì xảy ra nếu liên kết đó chết?
tay nắm cửa

2
Câu hỏi này dường như lạc đề vì về cơ bản nó là "câu hỏi chỉ liên kết".
Doorknob

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

1
@QuadmasterXLII bạn có thể làm rõ trong mô tả của mình về hành vi dự kiến ​​cho 3 số liên tiếp (giống hệt nhau)
Martin Ender

1
Tuyệt quá! Đóng phiếu rút lại. Tôi vẫn có một vấn đề ở đây: vì nó mang tính quyết định, mọi người không thể tìm thấy đầu ra ngắn nhất và sau đó chỉ là đầu ra sao?
Doorknob

Câu trả lời:


26

Python, 740 ký tự (nén 665 ký tự)

Mã số :

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

(Trộn các tab với khoảng trắng để thụt lề để lưu một vài byte)

Tôi chắc chắn đã chơi golf vì nếu tôi chỉ nén mã ở trên, mã 64 cơ sở mã hóa và execnó chỉ có 665 ký tự. Sau đây là chính xác tương đương với ở trên, không có giải pháp mã hóa cứng hoặc bất cứ điều gì:

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

Trả lời :

Mất ~ 47 giây (17 giây chưa được xử lý) để tìm chuỗi di chuyển 1111:

222123023221312012023222222222122120321101231231012312310122311332222212323021030232122232322321232210120232312332203213202123321231233202312331211112323122311331231232231223212322202122133211133222101222231222230223202123321231233202321222222212322120233202312031212322322123223222222212212232322222221221223222222222132223323122232220023212231223231313202232221231233212133231232021221133231232322321232023232232213322321321232320212312332123131333212223231011211332221232322222013023123321131333212223231231222323223123123231222222023221231222021223231223212322202122133211133222101222231222230223202123321231233202321222222212322120233202312031212322322132232322331223023032331223231313323222323321231232312332322233222222213222132132032323322323212132321223201322132323303202122332023123322032220313212320212332123123320213132122111123121323213121021231221133

Với vị trí bảng cuối cùng sau đây và di chuyển:

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

Thông tin bên lề: giải pháp là 309 byte được nén và 418 byte nếu được nén và mã hóa base64. Do đó, nó sẽ là một chương trình ngắn hơn để chỉ giải mã nó và in ra, nhưng điều đó không vui chút nào .

Giải thích :

Đây là một pastebin của phiên bản không có bản in ra bảng sau mỗi lần di chuyển, rất thú vị để xem!

Đó là một AI vũ phu rất đơn giản. Nó chỉ định EV cho từng vị trí bảng:

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

Nó thực hiện tìm kiếm theo chiều sâu bốn bước di chuyển về phía trước và chọn con đường dẫn đến EV cao nhất trong bốn lần di chuyển. Chức năng ev khuyến khích nó làm sạch bảng và giữ các phần có giá trị cao nhất trong góc, kết thúc là khá tối ưu. Thế là đủ để đến đó!

Nếu bạn sửa đổi chức năng EV để đặt giá trị cao hơn trên các vị trí bảng khác, đại loại như:

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

Hàm đó có được nó đến tận:

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

16k :

Eureka! Với giao diện 5 bước thay vì 4 và các trọng số sau:

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

Nó gần như được 32k, kết thúc vào:

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

Trình tự ở đây .

32k :

Vâng, thưa quý vị và các bạn, chúng tôi đã đạt mốc 32k. Hàm EV, thay vì nhân các ô vuông với một hằng số, tăng mỗi ô vuông thành các lũy thừa sau và thêm chúng. xcó nghĩa là hình vuông không liên quan:

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

Nó vẫn tính tổng tất cả các giá trị một lần và thêm 256 cho mỗi ô vuông trống. Lookahead có giá trị lên tới 32 nghìn, và sau đó nó tăng lên 5, nhưng dường như nó không thực sự làm được gì nhiều. Ban cuối:

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

Pastebin của chuỗi di chuyển 24.625 .


1
Giải pháp này rất tuyệt vời (Tôi yêu sức mạnh vũ phu của bạn + DFS nhìn về phía trước), lời giải thích sử thi và nhiệm vụ của bạn cho sức mạnh cao hơn bao giờ hết của hai người là tuyệt vời nhất. +1!
Lập trình viên

Đẹp quá Sử dụng một heuristic với độ sâu trước tiên có thể ngăn bạn đạt được các giải pháp tối ưu (trình tự di chuyển ngắn nhất). Có lẽ bạn có thể kết hợp tìm kiếm A * :-)
Mau

tar -xzvf a.tar; trăn a
TheDoctor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.