Подключите четыре валидатора


20

Вступление

Connect Four - игра, в которой вы пытаетесь получить четыре подряд: по горизонтали, по вертикали или по диагонали. В этом коде гольф мы будем пытаться выяснить, кто выиграл, учитывая игровую доску. Всегда будет один победитель и только один победитель.


задача

Имея доску Connect Four, выясните, кто победитель: Xили Y. Всегда будет один победитель и только один победитель. Размер доски всегда будет 6 на 7, как показано на рисунке.

Для данной доски следующая доска в этом случае Xкрасная и Yсиняя:

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

Ваш вклад будет:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOXOO
OOOXXOO
OOXYYYY

Вы можете разделить строки игры по символу новой строки (как выше), без разделительного символа, разделить строки на массив или список, или вы можете ввести матрицу символов.

Правильный вывод для этого примера:

Y

Y имеет четыре подряд; Итак, Y - победитель. Итак, мы выводим Y.


Контрольные примеры

Входные данные:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOOOO
OOYYOOO
OYXXXXO

Выход:

X

Входные данные:

OOOOOOO
OOOOOOO
OOOOOOO
XXXXOOO
YXYYOOO
YXYYXYX

Выход:

X

Входные данные:

YXYYXOO
XYXXYOO
XXXYYOO
YYYXXOO
XXYYYYO
XXYYXXO

Выход:

Y

Входные данные:

OOOOOOO
OOOOOOO
OYOOOOO
OOYOOOO
OOOYOOO
OOOOYOO

Выход:

Y

Входные данные:

OOOOOOO
OOOOOOO
OYOOOOX
OOYOOOX
OOOXOOX
OXOXYOX

Выход:

X

счет

Наименьшее количество байтов побеждает!


Это идеальный вызов для PMA / Улитки codegolf.stackexchange.com/questions/47311/…
Джерри Иеремия,

2
Можно ли предположить, что у победителя всегда будет еще один токен, чем у проигравшего?
математик наркоман

1
@mathjunkie Я был неправ, ты не можешь предположить это.
Нил

3
@nfnneil должен ли вывод быть X или Y или мы можем выбрать два других последовательных вывода, чтобы указать победителя?
Мартин Эндер,

1
Можем ли мы использовать другие символы в качестве входных данных? Или ввести числовую матрицу?
Луис Мендо

Ответы:


2

Желе , 19 байт

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ

Попробуйте онлайн!

Суть этого ответа скопирована из моего ответа на этот очень похожий вопрос .

объяснение

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ
   ;  ; ;             Append {the input} and the following three values:
UŒD                     the antidiagonals of {the input};
    ŒD                  the diagonals of {the input};
       Z                the transposed {input}.
         ṡ 4          Find all length-4 substrings
          €             of each subarray within that.
            ;/        Flatten one level.
                Þ     Sort, with the following sort order:
               E        If all elements are the same, sort later.
              Ṣ         Tiebreak via lexicographical order.
                 ṪṪ   Take the last element of the last element.

Довольно просто: мы берем все строки, столбцы, диагонали и антидиагонали (как в валидаторе n-queens), затем берем все подстроки длины 4 из них, затем сортируем их таким образом, чтобы выигрышная строка 4 сортировалась в конец. (Нам нужен тай-брейк в случае, если есть OOOOдополнение к XXXXили YYYY.) Возьмите последний элемент последнего элемента, и это будет Xили по Yмере необходимости.


6

Сетчатка, 51 48 байт

Спасибо Мартину Эндеру за сохранение 3 байта

M`X((.{6}X){3}|(.{8}X){3}|(.{7}X){3}|XXX)
T`d`YX

Попробуйте онлайн!

Принимает ввод как разделенный запятыми список строк


Вы можете сохранить несколько байтов, используя этап сопоставления и сократив его (.{7}X){3}|XXXдо (.{7}X|X)\4\4: tio.run/nexus/retina#fc4xCsMwDAXQPfcI2GC6NDS5QaeipcP/…
Martin Ender,

1
@MartinEnder Я не понимаю, как вы можете использовать \4- вы хотите повторить эффект .{7}, а не совпадающую строку. (И балансирование групп, вероятно, будет слишком длинным.)
Нил

1
@ Нейл, да, неважно, почему-то я не учел, что в сетке есть и другие ячейки OXY. использование стадии совпадения сохраняет 3 байта.
Мартин Эндер

5

Javascript (ES6), 54 55

Редактировать 1 байт спасен благодаря @Arnauld

Я просто проверяю, является ли Х победителем, так как всегда будет один победитель и только один победитель

Ввод - это строка с любым разделителем, как в ответе @ Арнаулда

F=    
b=>'YX'[+[0,6,7,8].some(x=>b.match(`X(.{${x}}X){3}`))]

;['OOOOOOO OOOOOOO OOXOOOO OOXOOOO OOXOOOO OOXOYYY'
 ,'OOOOOOO OOOOOOO OOXOOOO OOYXOOO OOYOXOO OOYYOXY'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,OOOOOOO,OOYYOOO,OYXXXXO'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,XXXXOOO,YXYYOOO,YXYYXYX'
 ,'YXYYXOO,XYXXYOO,XXXYYOO,YYYXXOO,XXYYYYO,XXYYXXO']
.forEach(s => console.log(s,F(s)))


@ Arnauld правильно, спасибо
edc65

4

Желе , 25 22 байта

ŒgL⁼¥Ðf
;UŒD€;Z;$ç€4FṀ

Принимает список строк (или список списка символов), сформированный из X, Yи O(также будет работать с заменами, так что у пробела есть более низкий порядковый номер, чем у обоих счетчиков).

Попробуйте онлайн! или запустить расширенную версию, которая принимает многострочную строку.

Как?

ŒgL⁼¥Ðf - Link 1, runs of given length: list A, length B  e.g. "XYYYXXO", 4
Œg      - group runs of equal elements of A                     ["X","YYY","XX","O"]
     Ðf - filter keep:
    ¥   -     last two links as a dyad:
  L     -         length                                         1   3     2    1
   ⁼    -         equal to B?         (none kept in this case->) 0   0     0    0

;UŒD€;Z;$ç€4FṀ - Main link: list of list of chars (or list of stings) I
 U             - reverse each row of I
;              - I concatenated with that
  ŒD€          - positive diagonals of €ach (positive and negative diagonals)
        $      - last two links as a monad:
      Z        -     transpose of I (i.e. the columns)
       ;       -     concatenated with I (columns + rows)
     ;         - concatenate (all the required directional slices)
         ç€4   - call the last link (1) as a dyad for €ach with right argument = 4
            F  - flatten the result
             Ṁ - take the maximum ('Y'>'X'>'O') - this has the bonus effect of returning:
                               'Y' or 'X' for a winning board; and
                               'O' or '' for a (valid) game in progress.

4

JavaScript (ES6), 77 76 69 байт

Сохранено 7 байтов благодаря Нейлу

Принимает ввод как разделенную чем-то строку, где что-то - это в основном любой символ.

b=>[...'XXXXYYYY'].find((c,i)=>b.match(`(${c}.{${(i%4+6)%9}}){3}`+c))

Контрольные примеры


Почему бы не использовать b.match()? Следует сэкономить на RegExpзвонке.
Нил

@Neil Я полностью забыл, что match()делал неявное преобразование в RegExp. Благодарность!
Арно

3

Python 2 , 143 байта

m=input()
u=[r[::-1]for r in m]
print"YX"[any(any('X'*4in''.join(t[i][j-i]for i in range(j+1))for j in range(6))for t in(m[::-1],m,u,u[::-1]))]

Принимает список строк или список символов. Жестко запрограммирован для 6 строк на 7 столбцов, в соответствии со спецификацией.

Попробуйте онлайн!



2

Python 2 , 201 143 129 128 107 байт

Я решил добавить горизонталь, вертикаль и диагональ вместе в один список, а затем добавить приращение, а затем искать X раз в нем. И поскольку всегда будет победитель, я могу предположить, что Y выиграл, если X не победит. Этот код принимает матрицу всех различных частей и пустых мест.

lambda m:"YX"[any("X"*4in"".join(a)for a in zip(*m)+m+zip(*["0"*(7-i)+m[i]+"00"*i+m[i]for i in range(6)]))]

Попробуйте онлайн!

кредиты

  • От 129 до 107 байтов только ASCII .

Это вполне приемлемо для самостоятельного ответа.
Джонатан Аллан

Не глядя слишком много на него, кажется , есть бесполезные пробельные в: i:] for, i, r, r] forи 1 for.
Yytsi

@TuukkaX Спасибо за вклад, обновлено.
Нил

Кроме того, *(len(m)-1)может быть *~-len(m). Как это устроено.
Yytsi

] forИ 1 forвсе еще там.
Yytsi

1

K (нгн / к) , 58 55 байт

{"XY"@|/&/'88<x ./:/:,/{x+/:/:+3+[4#1-+!3 3]\&4}'+!6 7}

Попробуйте онлайн!

{ } функция с аргументом x

+!6 7 все возможные пары 0..5 и 0..6

{ }' для каждого из них сделать

4#1-+!3 3 4 из 8 ортодиагональных направлений: (1 1;1 0;1 -1;0 1)

3+[ ]\&4начать со списка из четырех нулей ( &4) и сделать 3 шага в каждом из направлений

x+/:/: начать с каждой возможной позиции и предпринять шаги в каждом возможном направлении

,/конкатенации. на данный момент у нас есть матрица из 4-х списков координатных пар, некоторые из которых простираются за пределы доски

x ./:/: найдите соответствующие ячейки из x

88<кто из них "Y"-с? (88 является кодом ASCII "X")

&/'какие 4-списки состоят только из "Y"-s? (и-снижения-каждый)

|/есть хотя бы один такой? (Или-уменьшение)

"XY"@если ложный возврат "X", если истинный возврат"Y"


1

Zsh , 207 ... 159 байт

История версий: 4 итерации по ~ 25 байт в первую неделю; затем еще 3 итерации для ~ 25 байтов 6 месяцев спустя.

t(){a=($^a-$^@_);for s l (${w:^^argv})s+=$l&&for ((i=0;i++<$#s;))a[i]+=$s[i];}
w=(+)
t $@
for s;w[++j]=${(l:j:)}_
t $@
t ${(Oa)@}
[[ $a = *XXXX* ]]&&<<<X||<<<Y

( первый ) ( второй ) ( третий ) ( четвертый) ) ( пятый ) ( шестой ) Попробуйте онлайн!

В нижнем колонтитуле я печатаю как плату ввода, так и массив, который мы строим, из него в stderr. Прокрутите вниз, чтобы отладить, чтобы увидеть их. Массив, который мы строим, теперь стал намного длиннее, так как tделает декартово произведение с платой ввода при каждом вызове. (Эй, он сократил код на несколько байтов.)

Здесь есть что рассказать, поэтому я переместил (шестое издание) комментарии в аннотированную суть .

(tl; dr: объединить транспонирование исходного массива, но убедитесь, что они разделены)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.