Підключіть чотири валідатора


20

Вступ

Connect Four - це гра, в якій ви намагаєтеся отримати чотири поспіль: горизонтально, вертикально або по діагоналі. У цьому коді гольфу ми будемо намагатися знайти того, хто виграв, враховуючи ігрову дошку. Завжди буде один переможець і лише один переможець.


Завдання

Враховуючи дошку Connect Four, з’ясуйте, хто переможець: Xабо Y. Завжди буде один переможець і лише один переможець. Розмір дошки завжди буде 6 на 7, як, наприклад, на ігровій дошці на зображенні.

Наступна дошка, в даному випадку, Xчервона та Yсиня:

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

Ваш внесок буде:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOXOO
OOOXXOO
OOXYYYY

Ви можете відокремлювати рядки гри за новим рядком (наприклад, вище), без поділу, розділити рядки на масив чи список, або ви можете ввести матрицю символів.

Правильний вихід для цього прикладу:

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 / Snails 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-королеви), потім беремо всі 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
@Neil о так, ніколи не маю на увазі, я чомусь не вважав, що в сітці є інші осередки OXY, ніж відповідність. За допомогою етапу збігу тоді зберігається 3 байти.
Мартін Ендер

5

Javascript (ES6), 54 55

Редагуйте 1 байт, збережений спасибі @Arnauld

Я просто перевіряю, чи переможець X, оскільки завжди буде один переможець і лише один переможець

Введення - це рядок з будь-яким роздільником, як, наприклад, у відповіді @ 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

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

К (нг / к) , 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"-s? (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.