Розв’яжіть детерміновану версію 2048 року, використовуючи найменші байти


17

Напишіть програму, яка генерує виграшну послідовність рухів до детермінованого варіанту гри 2048. Послідовність повинна бути у вигляді рядка чисел 0-3, з 0: вгору, 1: вправо, 2: вниз, 3: зліва. Наприклад, рядок "1132" означає праворуч ліворуч вниз. Переможна програма - найкоротший вихідний код, який потрапляє до 2048 року!

Правила детермінованого 2048 року: Гра проводиться на сітці 4х4, спочатку містить 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
Виклики повинні бути самостійними - що робити, якщо посилання гине?
Дверна ручка

2
Це питання видається поза темою, оскільки воно, по суті, є "питанням лише для посилань".
Дверна ручка

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

1
@QuadmasterXLII ви можете уточнити у своєму описі очікувану поведінку протягом 3-х підрядних (однакових) номерів
Martin Ender

1
Чудово! Закриття голосування відкликано. У мене все ще виникає проблема: оскільки це детерміновано, чи не можуть люди просто знайти найкоротший результат, а потім просто вивести це?
Дверна ручка

Відповіді:


26

Пітон, 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

(Змішує вкладки з пробілами для відступу, щоб зберегти кілька байт)

Я, мабуть, смоктав при гольфінгу, тому що якщо я просто стискаю вищезгаданий код, його кодує base-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 переміщення:

22212302322131201202322222222212212032110123123101231231012231133222221232302103023212223232232123221012023231233220321320212332123123320231233121111232312231133123123223122321232220212213321113322210122223122223022320212332123123320232122222221232212023320231203121232232212322322222221221223232222222122122322222222213222332312223222002321223122323131320223222123123321213323123202122113323123232232123202323223221332232132123232021231233212313133321222323101121133222123232222201302312332113133321222323123122232322312312323122222202322123122202122323122321232220212213321113322210122223122223022320212332123123320232122222221232212023320231203121232232213223232233122302303233122323131332322232332123123231233232223322222221322213213203232332232321213232122320132213232330320212233202312332203222031321232021233212312332021313212211112312132321312102123122323321321031231302131332132322133213232123323322122221233233222023023331220222323232113123323223032131201123212121212121212121221212212122121221212212122121221212212122121221212212122121221212122121221212212122121212212121212212121212212121212212121212212122121212212122121221212212122121221212212122321232323232323323132211232323232323232323232323232321233233231212321232323232323232323232323132121212121212121212121212121212121232

За допомогою наступного остаточного положення та переміщення:

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

Загальні відомості: рішення має 309 байтів, і 418 байт, якщо gzipped та base64 закодовано. Таким чином, було б коротшою програмою просто розшифрувати це та роздрукувати, але це зовсім не весело .

Пояснення :

Ось пастбін з версією без гольфу, який друкує дошку після кожного ходу, дуже цікаво дивитися!

Це дуже простий 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

16 к :

Еврика! З 5-ступінчастою опорою замість 4 та наступними вагами:

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

Він майже набирає 32 тис., Закінчуючи:

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

Послідовність тут .

32 к :

Так, панове, ми досягли позначки 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

Пастебін 24 625-послідовності руху .


1
Це рішення є геніальним (я люблю вашу грубу силу + погляд вперед DFS), епічне пояснення і ваш пошук все більш високих сил двох є найвидатнішим. +1!
ПрограмістDan

Хороший! Використання евристики з глибиною спочатку, можливо, не дозволяє вам досягти оптимальних рішень (найкоротша послідовність переміщення). Може бути , ви можете включити в A * пошук :-)
Мау

дьоготь -xzvf a.tar; python a
TheDoctor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.