แก้ปัญหาเวอร์ชันที่กำหนดไว้ 2048 โดยใช้จำนวนไบต์น้อยที่สุด


17

เขียนโปรแกรมที่สร้างลำดับการเคลื่อนที่ที่ชนะไปยังตัวแปรที่กำหนดขึ้นของเกม 2048 ลำดับนั้นควรอยู่ในรูปของสตริงตัวเลข 0-3 โดยมี 0: up, 1: right, 2: down, 3: ซ้าย. ตัวอย่างเช่นสตริง "1132" หมายถึงขวาซ้ายขวาลง โปรแกรมที่ชนะคือซอร์สโค้ดที่สั้นที่สุดที่จะถึงปี 2048!

กฎเพื่อกำหนด 2048: เกมเล่นบนตาราง 4x4 ในขั้นต้นที่มี 1 กระเบื้องที่มุมซ้ายบน การย้ายแต่ละครั้งประกอบด้วยคำสั่ง "ซ้าย", "ขวา", "ขึ้น" หรือ "ลง" คำสั่งทางซ้ายเลื่อนไทล์ทั้งหมดบนกริดไปทางซ้ายจากนั้นรวมและหาผลรวมเหมือนไทล์ที่เริ่มจากด้านซ้าย เช่นเดียวกันคำสั่งด้านขวาจะเลื่อนไทล์ไปทางขวาจากนั้นรวมเริ่มจากด้านขวา

แต่ละไทล์สามารถเข้าร่วมได้เพียงหนึ่งชุดเท่านั้นต่อการเคลื่อนไหว

หลังจากย้ายแล้วไทล์ 2 อันใหม่จะถูกสร้างขึ้นในคอลัมน์แรกจากด้านซ้ายพร้อมพื้นที่ว่างในพื้นที่ว่างแรกจากด้านบนในคอลัมน์นั้น

ตัวอย่างเช่นลำดับ "ขวาซ้ายซ้าย" นำไปสู่รัฐ

2___
____
____
____

2__2
____
____
____


2__4
____
____
____


24__
2___
____
____


2___
____
____
44__

คำสั่งด้านขวานำไปใช้กับแถว _ 2 2 2 ผลลัพธ์ใน _ _ 2 4 คำสั่งด้านขวานำไปใช้กับผลลัพธ์แถว 2 2 2 2 ใน _ _ 4 4

คำถามนี้ได้รับแรงบันดาลใจจากhttp://jmfork.github.io/2048/


2
ความท้าทายควรอยู่ในตัวเอง - จะเป็นเช่นไรหากลิงก์นั้นตาย
Doorknob

2
คำถามนี้ดูเหมือนจะไม่อยู่ในหัวข้อเนื่องจากเป็นคำถามที่เชื่อมโยงเท่านั้น
Doorknob

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

1
@QuadmasterXLII คุณอาจอธิบายในคำอธิบายของคุณถึงพฤติกรรมที่คาดไว้สำหรับหมายเลข 3 หมายเลข (เหมือนกัน)
Martin Ender

1
ที่ดี! ถอนการโหวตอย่างใกล้ชิด ฉันยังคงมีปัญหาอยู่ที่นี่: เนื่องจากเป็นสิ่งที่กำหนดได้ผู้คนจะไม่สามารถค้นหาผลลัพธ์ที่สั้นที่สุดแล้วเอาออกได้หรือไม่
Doorknob

คำตอบ:


26

Python, 740 ตัวอักษร (บีบอัด 665 ตัวอักษร)

รหัส :

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

(ผสมแท็บที่มีช่องว่างสำหรับย่อหน้าเพื่อบันทึกสองสามไบต์)

ฉันต้องดูดมันตอนเล่นกอล์ฟเพราะถ้าฉันบีบอัดโค้ดด้านบนเบส -64 เข้ารหัสมันและexecมันก็แค่ 665 ตัวอักษร สิ่งต่อไปนี้เทียบเท่ากับที่กล่าวมาข้างต้นไม่มีวิธีแก้ไขปัญหาแบบตายตัวหรือสิ่งใด:

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

ตอบ :

ใช้เวลา ~ 47 วินาที (ไม่รวม 17 วินาที) เพื่อค้นหาลำดับ 1111-move:

2221230232213120120232222222221221203211012312310123123101223113322222123230210302321222323223212322101202323123322032132021233212312332023123312111123231223113312312322312232123222021221332111332221012222312222302232021233212312332023212222222123221202332023120312123223221232232222222122122323222222212212232222222221322233231222322200232122312232313132022322212312332121332312320212211332312323223212320232322322133223213212323202123123321231313332122232310112113322212323222220130231233211313332122232312312223232231231232312222220232212312220212232312232123222021221332111332221012222312222302232021233212312332023212222222123221202332023120312123223221322323223312230230323312232313133232223233212312323123323222332222222132221321320323233223232121323212232013221323233032021223320231233220322203132123202123321231233202131321221111231213232131210212312232332132103123130213133213232213321323212332332212222123323322202302333121220222323232113123323221223032131201123212133123131222323313133313300123231332011222221223232331313313112312113230231121232332122323232321312323213212232313212323211330231231012

ด้วยตำแหน่งกระดานสุดท้ายและย้ายต่อไปนี้:

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

เรื่องไม่สำคัญ: การแก้ปัญหาคือ 309 ไบต์ gzipped และ 418 ไบต์ถ้า gzipped และ base64- เข้ารหัส ดังนั้นมันจะเป็นโปรแกรมที่สั้นกว่าที่จะถอดรหัสและพิมพ์มันออกมา แต่มันก็ไม่สนุกเลย

คำอธิบาย :

นี่คือpastebin ของเวอร์ชั่นที่ไม่ได้ลงมือทำซึ่งจะพิมพ์กระดานออกมาหลังจากการเคลื่อนไหวแต่ละครั้งสนุกมาก ๆ !

มันเป็น AI ที่ดุร้ายอย่างง่าย ๆ กำหนด EV สำหรับตำแหน่งกระดานแต่ละตำแหน่ง:

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

มันทำการค้นหาสี่ครั้งแรกที่มีความลึกก่อนจะเดินหน้าและเลือกเส้นทางที่นำไปสู่ ​​EV สูงสุดในการเคลื่อนไหวสี่ครั้ง ฟังก์ชั่น ev สนับสนุนให้ทำความสะอาดบอร์ดและเก็บชิ้นส่วนที่มีค่ามากที่สุดไว้ที่มุมซึ่งท้ายที่สุดแล้วก็เหมาะสมที่สุด ก็เพียงพอแล้วที่จะไปถึงที่นั่น!

หากคุณปรับเปลี่ยนฟังก์ชั่น EV เพื่อวางค่าที่สูงขึ้นบนสปอตบอร์ดอื่น ๆ เช่น:

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

ฟังก์ชั่นนั้นทำให้ได้มาถึง:

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

16k :

ยูเรก้า! ด้วย lookahead 5 ขั้นตอนแทนที่จะเป็น 4 และน้ำหนักต่อไปนี้:

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

เกือบจะเป็น 32k แล้วสิ้นสุดใน:

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

ลำดับเป็นที่นี่

32k :

ใช่สุภาพสตรีและสุภาพบุรุษเราได้ทำเครื่องหมาย 32k แล้ว ฟังก์ชั่น EV แทนที่จะเป็นสี่เหลี่ยมจัตุรัสคูณด้วยค่าคงที่ยกแต่ละตารางเป็นกำลังต่อไปนี้และเพิ่มพวกเขา xหมายถึงสี่เหลี่ยมไม่เกี่ยวข้อง:

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

มันยังคงรวมค่าทั้งหมดครั้งเดียวและเพิ่ม 256 สำหรับแต่ละช่องว่าง Lookahead เป็น 4 ตลอดทางจนถึง 32k และจากนั้นก็ชนได้ถึง 5 แต่ดูเหมือนจะไม่ได้ทำอะไรมากนัก จบบอร์ด:

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

Pastebin ของลำดับ


1
โซลูชันนี้ยอดเยี่ยม (ฉันชอบแรงเดรัจฉานของคุณ + DFS มองไปข้างหน้า) คำอธิบายที่ยิ่งใหญ่และการแสวงหาพลังที่เหนือกว่าของทั้งสองนั้นยอดเยี่ยมที่สุด +1!
ProgrammerDan

ทำได้ดีนี่! การใช้ฮิวริสติกที่มีความลึกเป็นอันดับแรกอาจทำให้คุณไม่สามารถเข้าถึงโซลูชันที่ดีที่สุด (ลำดับการเคลื่อนที่ที่สั้นที่สุด) บางทีคุณอาจรวม A * search :-)
Mau

tar -xzvf a.tar; python a
TheDoctor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.