Шахматная доска лабиринт

14

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

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

вход

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

a1 и h8 будут пустыми на входе; т.е. первая косая черта имеет цифру перед ним, а последняя косая черта имеет цифру после нее.

Выход

Правда или ложь, указывающие, возможен ли успешный переход на 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

Пример диагоналей

В случае, если вышеприведенная проза была неясной, вот несколько фотографий.

Проходимые диагонали

пешки одного цвета пешки разных цветов грачи противоположных цветов

Непроходимые диагонали

ладья и пешка одного цвета грачи одного цвета

msh210
источник
Извините, я не уверен в правилах стандартного гольфа: что произойдет, если вы введете незаконную строку? Может ли какое-либо поведение происходить?
Алекс Берн
@alexberne Я считаю, что это покрывает это: «Ваш код должен работать для всех допустимых входных данных».
Рейнболт
@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). Диагональный доступ и занятость проверяются в IF + logic-calc, который когда-то жил в функции, но теперь находится во вложенных соседних циклах. Проверка диагонального доступа основывается на произведении двух углов кошачьих углов, которое составляет только 6 или более, если фигуры одного цвета и, по крайней мере, одна фигура, а не пешка.

Позвонить в электронную таблицу; возвращает значение в X (0,7) - 1, если h8 доступно, и 0, если нет - что Excel распознает как правдивое / ложное. = IF (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-devilish :-D и потерял свои функции; Я нашел достаточно короткий способ написать их, чтобы избежать накладных расходов.

Редактировать 2: Еще один большой шаг вперед, эффективно завершающий работу по удалению функций inc / dec, вздох и использование нескольких глобальных переменных. Я, возможно, наконец-то овладеваю этим ....

Кодировка фигур и квадратов изменилась. Не влияет на длину кода.

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

Редактировать 4: Прорываясь через большие 500, ух-ху - помешал 3 цикла For в 1.

Редактировать 5: Джимини Крикет, еще одно большое падение, когда я смешал две функции вместе - моя проверка диагонального доступа всегда проходит для соседних квадратов, так что ...

Редактировать 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 - извилистая дорожка
Joffan
источник
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 проходов доски.
Джоффан
@ Джоффан, ты можешь сбросить 3 байта, сжимая все экземпляры [some non-letter character] Toдо[some non-letter character]To
Тейлор Скотт
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
Да, и я мог бы сделать это во время моего следующего перерыва. Я проверил это на всех ваших примерах, а затем на некоторых. Должен ли я указать это каким-то образом?
синтаксис
Не знаю; Мне было просто интересно.
msh210