Лабіринт шахової дошки


14

Шахові фігури (королі, королеви, граки, єпископи та лицарі) та пішаки знаходяться на дошці, але не на площі a1 чи h8 . Ваше завдання - подорожувати від порожнього квадрата a1 до порожнього квадрату h8 , проходячи лише через порожні квадрати. Правила руху такі:

  1. Ви можете переходити з будь-якого порожнього квадрата до будь-якого порожнього квадрата поруч (той самий ранг, наступний чи попередній файл; або той самий файл, наступний чи попередній ранг).
  2. Ви можете переходити з будь-якого порожнього квадрата до будь-якого порожнього квадрата по діагоналі поруч із ним (наступний чи попередній ранг, наступний чи попередній файл), за умови, що квадратні куточки містять або (a) дві пішаки, або (b) пішаки / шматки навпроти колір. (Два шматки, які не є пішаками, або шматок пішака та пішака одного кольору, є досить сильними, щоб перешкодити вашому просуванню через кут, але дві пішаки - ні; шматки / пішаки іншого кольору не працюють концертуйте, щоб перешкодити своєму шляху.) Наприклад, якщо ви на c4 і d5 порожній, ви можете перейти до нього, якщо c5 і d4 містять пішаків або містять шматки / пішаки протилежного кольору. Дивіться розділ "Прикладні діагоналі" нижче для зображень.

Вхідні дані

Опис дошки FEN Тобто: вхідним рядком буде рядок, що включає опис рангу 8 , косою рискою ( /), описом 7 рангу , косою рисою… та описом рангу 1 . Опис кожного рангу містить цифри та літери , що ведуться від файлу a до файлу h , де букви позначають шматки та пішаки (чорні p= пішак, n= лицар, b= єпископ, r= грак, q= королева, k= король, а білі одні з них з великої літери), а цифри позначають послідовне число порожніх квадратів. Наприклад, rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNце дошка після одного планового руху (пішака короля до e4) у шаховій грі.

a1 і h8 будуть порожніми на вході; тобто перша коса коса риса має цифру перед нею, а остання коса коса риса - після неї.

Вихідні дані

Truthy або falsey, що вказує на те, чи можливий успішний перехід до h8 .

Якщо вхід не є дійсним описом плати FEN (означає, що відповідає моєму поясненню вище), або якщо a1 або h8 зайнято, то вихід може бути будь-яким або нічого. (Іншими словами: ви можете припустити, що вхід відповідає вимогам, наведеним вище.)

Оцінка балів

Це кодовий гольф: виграє найменше байтів.

Приклад введення та виведення

Зауважте, що ваш код повинен працювати для всіх дійсних входів, а не лише для прикладів.

Додайте пробіл та wпісля кожного FEN, щоб візуалізувати його на http://www.dhtmlgoodies.com/scripts/chess-fen/chess-fen-3.html. (Зверніть увагу, що деякі інші онлайн-візуалізатори FEN не дозволять забороняти шахи на дошці, наприклад, з пішаком на рангу 1 або 8 , тому не можна використовувати для наших цілей.)

Приклади правди

  • 8/8/8/8/8/8/8/8 - порожня дошка
  • 1p1Q4/2p1Q3/2p1Q3/2p1Q3/2p1Q3/2p1Q3/Q1p1Q3/1q3q2- є шлях a1 , b2 , b3 , b4 , b5 , b6 , b7 , c8 , d7 , ( не e8 , це заблоковано, але) d6 , d5 , d4 , d3 , d2 , d1 , e1 , f2 , f3 , f4 , f5 , f6 , f7 , f8 , g8 , h8
  • 8/8/KKKKK3/K3K3/K1K1p3/Kp1K4/K1KK4/2KK4 - приклад, коли квадрат, заблокований в одній точці, повинен бути переданий пізніше (щоб переконатися, що ви не встановлюєте квадрати як непрохідні)
  • K1k1K1K1/1K1k1K1k/K1K1k1K1/1k1K1K1k/K1k1K1k1/1K1k1k1K/K1K1k1K1/1k1k1K1k- Є єдиний шлях через (просто слідкуйте за носом: на кожному кроці потрібно рухатись лише один квадрат, якщо тільки не зробити крок назад); це також приклад, коли квадрат блокується в одній точці, але необхідний пізніше

Приклади Фальсі

  • 6Q1/5N2/4Q3/3N4/2Q5/1N6/2Q5/1N6 - будь-яка спроба шляху повинна пройти через дві діагонально розташовані одноколірні фігури
  • N1q1K1P1/1R1b1p1n/r1B1B1Q1/1p1Q1p1b/B1P1R1N1/1B1P1Q1R/k1k1K1q1/1K1R1P1r- єдиний шлях по діагоналі a8-h1 знаходиться на f2-g3 , але це вимагатиме проходження через e1-d2 або f2-e3 , які є і неможливими.
  • 4Q3/4q3/4Q3/5Q2/6Q1/3QqP2/2Q5/1Q6
  • 4q3/4Q3/4q3/5q2/6q1/3qQp2/2q5/1q6

Приклад діагоналей

Якщо проза вище була неясною, ось кілька картинок.

Прохідні діагоналі

пішаки одного кольору пішаки протилежних кольорів граки протилежних кольорів

Непрохідні діагоналі

грак і пішак такого ж кольору граки одного кольору


Вибачте, я не впевнений у правилах гольфу "Станадард": Що станеться, якщо ви вставите нелегальну струну? Чи може відбутися будь-яка поведінка?
alex berne

@alexberne Я вважаю, що це охоплює це: "ваш код повинен працювати для всіх дійсних даних".
Rainbolt

@alexberne, я редагував. Це зрозуміло зараз?
msh210

так дякую. Я новачок тут, тому це можуть бути звичні речі для гравців у гольф, але для мене це було незрозуміло :)
alex berne

Просто хотів сказати спасибі за чудову головоломку @ msh210. Я не розумію, чому немає більше відповідей.
Йофан

Відповіді:


6

VBA 668 666 633 622 548 510 489 435 331 322 319 315 байт

Function Z(F):Dim X(7,7):While Q<64:R=R+1:V=Asc(Mid(F,R))-48:If V>9 Then X(Q\8,Q Mod 8)=(3+(V\8=V/8))*Sgn(48-V):V=1
Q=Q-V*(V>0):Wend:X(7,0)=1:For W=0 To 2E3:Q=W Mod 8:P=W\8 Mod 8:For T=Q+(Q>0) To Q-(Q<7):For S=P+(P>0) To P-(P<7):If X(S,T)=0 Then X(S,T)=(1=X(P,Q))*(6>X(P,T)*X(S,Q))
Next S,T,W:Z=X(0,7):End Function

Читання вхідного рядка займає до 'Wend'. Приємний побічний ефект - це припиняє введення рядка, коли плата [X] повністю закодована, тому ви можете залишити опис в кінці.

У дошці кодування, пішаків - 2, інших шматок - 3, чорний колір - негативний. Пішаки розпізнаються по 'P' & 'p' з кодами символів, які поділяються на 8.

'X (7,0) = 1', задаючи a1 доступний, саме там починаються перевірки шляху. Це неодноразово сканує дошку, намагаючись додати доступні квадрати з квадратів, позначених як доступні (1). Діагональний доступ та заповнюваність перевіряються в логіці Calc IF +, яка колись жила у функції, але тепер сидить у вкладених петлях сусідів. Діагональна перевірка доступу покладається на добуток двох квадратів котячих куточків, що становить лише 6 або більше, якщо шматки однакового кольору, а принаймні один - шматок, а не пішак.

Дзвонити в електронну таблицю; повертає значення в X (0,7) - 1, якщо h8 доступний, і 0, якщо ні - яке Excel визнає правдою / хибністю. = ЯКЩО (Z (C2), "так", "ні")

введіть тут опис зображення

Можливо, я захопився викручуванням коду вниз, вгорі, тож ось коментована версія напівгольф:

Function MazeAssess(F)  'input string F (FEN)
Dim X(7, 7)             'size/clear the board; also, implicitly, Q = 0: R = 0
'Interpret string for 8 rows of chessboard
While Q < 64
    R = R + 1           ' next char
    V = Asc(Mid(F, R)) - 48  ' adjust so numerals are correct
    If V > 9 Then X(Q \ 8, Q Mod 8) = (3 + (V \ 8 = V / 8)) * Sgn(48 - V): V = 1 ' get piece type (2/3) and colour (+/-); set for single column step
    Q = Q - V * (V > 0) ' increment column (unless slash)
Wend
'Evaluate maze
X(7, 0) = 1             ' a1 is accessible
For W = 0 To 2000       ' 1920 = 30 passes x 8 rows x 8 columns, golfed to 2E3
    Q = W Mod 8         ' extracting column
    P = W \ 8 Mod 8     ' extracting row
    For T = Q + (Q > 0) To Q - (Q < 7)     ' loop on nearby columns Q-1 to Q+1 with edge awareness
        For S = P + (P > 0) To P - (P < 7) ' loop on nearby rows (as above)
            If X(S, T) = 0 Then X(S, T) = (1 = X(P, Q)) * (6 > X(P, T) * X(S, Q)) ' approve nearby empty squares if current square approved and access is possible
        Next 'S
    Next 'T
Next 'W
MazeAssess = X(0, 7)    ' report result for h8
End Function

Нотатки про хід виконання

Редагувати 1: Код зараз не такий, як 666-чортово :-D і втратив свої функції; Я знайшов досить короткий спосіб написати їх, щоб уникнути накладних витрат.

Редагування 2: Ще один великий ривок уперед, що ефективно закінчує роботу над видаленням функцій inc / dec, зітхання та використанням декількох глобалів. Я, нарешті, можу отримати розвішування цього ....

Змінилося кодування шматочків і квадратів. Не впливає на довжину коду.

Редагування 3: Повернення (підроблених) функцій, видалення всіх цих дратівливих Callбайтів та деяких інших налаштувань.

Редагування 4: Пробиваючи великі 500, woohoo - згладжував 3 циклів для 1.

Edit 5: Jiminy Cricket, ще одна велика крапля, коли я розгладив дві функції разом - моя діагональна перевірка доступу завжди проходить для сусідніх квадратів, тому ...

Редагувати 6: Святі ключки, ще одна масивна крапля. Помилка зовнішніх функцій і, таким чином, глобальних ... Я перейшов на менше половини початкової розміру розміщеної ....

Редагування 7: Додайте версію без вогків

Редагування 8: Переглянуто процес читання на кілька доларів більше

Редагувати 9: Вичавив пару виразів за останні кілька крапель крові

Правка 10: NextВиписка Compund проливає кілька байтів


Для інтересу, графіка дощок після аналізу доступності (кодові цифри застаріли, але ...) доступні квадрати - зелені, недоступні квадрати - білий та інші кольори - шматки або пішаки.

3 успішні дошки 3 заблоковані дошки

Пара дощок для викликів: h8 доступний для обох:

  • P1Pq2p1 / 1P1R1R1p / 1K2R1R1 / 1p1p1p2 / p1b1b1np / 1B1B1N1k / Q1P1P1N1 / 1r1r1n2 - 10 проходів для вирішення
  • P1P3r1 / 1P1R2r1 / 1N1R1N2 / 1P1P1P2 / 1n1p1ppp / 1B1B4 / 1b1pppp1 / 1P6 - звивистий шлях

1
Дуже приємно, і +1, але: (1) Ви впевнені, що 960 кроків достатньо? (2) Чи можете ви зберегти кілька байт, дивлячись на дошку догори дном? If V>9 Then X(7-P,C)=я б подумав (не те, що я знаю VBA) став If V>9 Then X(P,C)=.
msh210

Насправді ця техніка економить ініціалізацію P, тому дякую за запитання :-). І так, я впевнений, що 15 проходів дошки достатньо; Я дуже багато перевіряв. Я насправді не зміг просунути його за 10 проходів, насправді, але 640 та 960 мають однакову кількість символів, тому я зіграю в безпеці. Але якщо я поклав дошку догори дном, вона МОЖАЛА б зробити більше 10 проходів, а може бути і більше 15 - якщо тільки я не обходив дошку догори дном, що матиме накладні витрати.
Джофан

@ msh210 1 додаткове спостереження - 15 циклів достатньо лише для аналізу всієї дошки, в гіршому випадку, але 10 циклів достатньо для отримання статусу h8, тому у мене справді великий запас. Причина полягає в тому, що пошук шляхів працює набагато швидше в напрямку оцінки, збільшуючи рядок № і стовпець № - доки шлях іде вгору або вправо, він буде завершений за один прохід. Якщо піти вліво або вниз, ви отримаєте лише один крок далі за пропуск.
Йофан

@ msh210 У рамках оновлення процесу читання - який вузько утримував об'єкт, щоб залишити коментар про закінчення рядка FEN - я додав запропонований вами скасування дошки - деякі дошки зараз приймають 15 пропусків (до 17), так функція збільшилася до 30 проходів дошки.
Йофан

@Joffan ви можете залишити 3 байт конденсації всіх примірників [some non-letter character] Toдо[some non-letter character]To
Taylor Scott

3

Matlab, 636 887 байт як збережене (включаючи відступи)

Це рішення не дуже гольф, але я хотів піти вперед і поставити його.

function[n] = h(x)
o=[];
for i=x
 b={blanks(str2num(i)),'K','k',i};o=[o b{~cellfun(@isempty,regexp(i,{'\d','[NBRQK]','[nbrqk]','p|P'}))}];
end
o=fliplr(reshape(o,8,8))
for i=1:64
 b=i-[-8,8,7,-1,-9,1,9,-7];
 if mod(i,8)==1
  b=b(1:5);
 elseif mod(i,8)==0
  b=b([1,2,6:8]);
 end
 b=b(b<65&b>0);c=o(b);dn=b(isspace(c)&ismember(b,i-[9,7,-9,-7]));
 for j=dn
  g=o(b(ismember(b,j-[-8,8,7,-1,-9,1,9,-7])));
  if ~isempty(regexp(g,'pk|kp|PK|KP|kk|KK'));c(b==j)='X';end;
 end
 Bc{i}=b(c==32);
end
n=Bc{1};
on=[];
while length(n)>length(on)
 on=n;
 for i=1:length(n)
  n=unique([n Bc{n(i)}]);
 end
end
any(n==64)
end

Читає рядок дошки, xяк зазначено вище, і перетворює її на більш повно представлену o, потім знаходить усі рухи (ребра графів) між пробілами, потім визначає, які переміщення можливі (не на заповнені пробіли), а потім визначає, які можливі рухи мають " ворота "з двох частин, щоб пройти між ними, а потім з'ясовує, чи ворота відкриті (пішаки, протилежних кольорів) або закриті (того ж кольору та включаючи пішака). Потім він проходить, щоб знайти місця, до яких можна дістатися шляхами від нижнього лівого квадрата, і якщо шлях може досягти місця 64, це дошка Так.


1
Класно. Ви перевірили це на моєму прикладі FEN в питанні, щоб переконатися, що він повертає правильний результат для кожного? Крім того, оскільки це питання з кодовим гольфом , ви дійсно повинні це гольфу. Якщо нічого іншого, ви можете позбутися відступу (або зробити це одним пробілом або вкладкою замість чотирьох пробілів)? та / або скинути пробіли навколо =s? (Я не знаю MATLAB: можливо, це неможливо.)
msh210

Так, і я можу зробити щось із цього під час наступної перерви. Я протестував це на всіх ваших прикладах, а потім на деяких. Чи варто це якимось чином зазначити?
sintax

Данно; Я просто поцікавився.
msh210
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.