[Question]
  [
# Introduction
Connect Four is a game where you attempt to get four in a row: horizontally, vertically, or diagonally. In this code golf, we will be trying to find who won, given a game board. There will always be one winner, and only one winner.
---
# Task
Given a Connect Four board, figure out who the winner is: `X` or `Y`. There will always be one winner, and only one winner. The board size will always be 6 by 7 like how the game board is in the in picture.
Given a board the following board, in this instance, `X` is red and `Y` is blue:
[![enter image description here](https://i.stack.imgur.com/wc0rt.png)](https://i.stack.imgur.com/wc0rt.png)
Your input would be:
```
OOOOOOO
OOOOOOO
OOOOOOO
OOOOXOO
OOOXXOO
OOXYYYY
```
You can separate rows of the game by newline character (like above), no dividing character, divide the rows into an array or list, or you can input a matrix of characters. 
Correct output for this example:
```
Y
```
Y has four in a row; so, Y is the winner. So, we output Y.
---
# Test cases
Input:
```
OOOOOOO
OOOOOOO
OOOOOOO
OOOOOOO
OOYYOOO
OYXXXXO
```
Output:
```
X
```
---
Input:
```
OOOOOOO
OOOOOOO
OOOOOOO
XXXXOOO
YXYYOOO
YXYYXYX
```
Output:
```
X
```
---
Input:
```
YXYYXOO
XYXXYOO
XXXYYOO
YYYXXOO
XXYYYYO
XXYYXXO
```
Output:
```
Y
```
---
Input:
```
OOOOOOO
OOOOOOO
OYOOOOO
OOYOOOO
OOOYOOO
OOOOYOO
```
Output:
```
Y
```
---
Input:
```
OOOOOOO
OOOOOOO
OYOOOOX
OOYOOOX
OOOXOOX
OXOXYOX
```
Output:
```
X
```
# Scoring
Least number of bytes wins!
  
[Answer]
# Retina, ~~51~~ 48 bytes
 *Thanks to Martin Ender for saving 3 bytes* 
```
M`X((.{6}X){3}|(.{8}X){3}|(.{7}X){3}|XXX)
T`d`YX
```
[Try it Online!](https://tio.run/nexus/retina#fc4xCsMwDAXQPfcI2GC6NDS5QaeipcP/kMFDbpH47K4sJQQCqZdnf76E@/DO9ZMRwmN9FcT1WTa9Tud1LNgQ52EeYvfNSyZqJUiIJBBgU2lSY8v1qYGpQSd@0lWdQ5M27urO2/6p94W24W8fLlz72N5HupO2Xg5/)
Takes input as a comma-separated list of rows
[Answer]
# Javascript (ES6), 54 ~~55~~
*Edit* 1 byte saved thanks @Arnauld
I just check if X is the winner, as *There will always be one winner, and only one winner*
Input is a string with any separator, like in @Arnauld's answer
```
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)))
```
[Answer]
## JavaScript (ES6), ~~77~~ ~~76~~ 69 bytes
*Saved 7 bytes thanks to Neil*
Takes input as a *something*-separated string, where *something* is basically any character.
```
b=>[...'XXXXYYYY'].find((c,i)=>b.match(`(${c}.{${(i%4+6)%9}}){3}`+c))
```
### Test cases
```
let f =
b=>[...'XXXXYYYY'].find((c,i)=>b.match(`(${c}.{${(i%4+6)%9}}){3}`+c))
console.log(f("OOOOOOO,OOOOOOO,OOOOOOO,OOOOOOO,OOYYOOO,OYXXXXO"))
console.log(f("OOOOOOO,OOOOOOO,OOOOOOO,XXXXOOO,YXYYOOO,YXYYXYX"))
console.log(f("YXYYXOO,XYXXYOO,XXXYYOO,YYYXXOO,XXYYYYO,XXYYXXO"))
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~25~~ 22 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
ŒgL⁼¥Ðf
;UŒD€;Z;$ç€4FṀ
```
Takes a list of strings (or list of list of characters) formed of `X`, `Y`, and `O` (would also work with replacements such that the space has a lower ordinal than both counters).
**[Try it online!](https://tio.run/nexus/jelly#@390UrrPo8Y9h5YenpDGZR16dJLLo6Y11lHWKoeXAxkmbg93Nvz//z9a3R8C1HUIsiIjIyGsyAgg8FePBQA)** or run an [augmented version](https://tio.run/nexus/jelly#@390UrrPo8Y9h5YenpDGZR16dJLLo6Y11lHWKoeXAxkmbg93Nvx/uHvL4fb//yMjIiMj/P25IiIjIiJBNJAC0ZFAYbA4kAsUANNAAQA) that takes a multiline string.
### How?
```
Œ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.
```
[Answer]
# [Python 2](https://docs.python.org/2/), 143 bytes
```
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]))]
```
Takes a list of strings or a list of list of chars. Hard-coded for **6** rows by **7** columns, as the specification guarantees.
**[Try it online!](https://tio.run/nexus/python2#VY1BCsMgEEX3OYW4UVtTCJQuAjlDtlMGF1m0ZQQnQXTR09tYKaEfBh5v@PwSJuItJ226PGHEcewH91yjiIJYBNdtkTjJO0hc@K3rKVCnK7FSF78S64Tk0Pf0bVFtxYVfD@3PgzHV@cPdmkm70aFt2WCzzY2NcaWgnFuk/SPYAZqD4ws/ghlAug8)**
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), 45 bytes
```
{"YX"@|//{&/'(x;+x),x@'/:|:\!4}''+'4'4''~2!x}
```
[Try it online!](https://ngn.bitbucket.io/k#eJxLs6pWioxQcqjR169W01fXqLDWrtDUqXBQ17eqsYpRNKlVV9dWNwFC9TojxYpaLq5iKyVrpRglfwiwxkZHQOgICB0RCQRKXGkKxbg1R4K1AfmRUBpkBpCOAOr2jyCgOQLGj4CJRyC5hJDmCIKaAcdDUV4=)
Takes a matrix of characters and returns one of X or Y. If simplified I/O is allowed (0, 1, 2 for X, O, Y for input and boolean for output), I can remove `2!` from preprocessing and `"YX"@` from postprocessing, giving **38 bytes**.
### How it works
```
{"YX"@|//{&/'(x;+x),x@'/:|:\!4}''+'4'4''~2!x}   x: matrix of chars
~2!x       for each char, convert X to 1 and O/Y to 0
+'4'4''    extract all 4x4 sub-matrices using size-4 windows
{...}''    for each submatrix...
|:\!4        (0 1 2 3;3 2 1 0)
x@'/:        for each row of above, extract one element from each row of x
             which gives the diagonal and the antidiagonal of x
(x;+x),      prepend x and transpose of x
&/'          reduce each by boolean AND
             x -> vertical test, +x -> horizontal test
|//        repeat reducing by boolean OR until only one value remains
"YX"@      convert 1 to X and 0 to Y
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 19 bytes
```
UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ
```
[Try it online!](https://tio.run/nexus/jelly#@x96dJKLNQhHWT/cufBR0xoTa/2HOxe5Hp73cOcqIPr//3@0UmREZGSEv7@SDpeCUkRkREQkjA1kwtiRQCVwNUBhoAScDZRQigUA "Jelly – TIO Nexus")
The core of this answer is copied from [my answer to this very similar question](https://codegolf.stackexchange.com/a/112362/62131).
## Explanation
```
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.
```
Fairly simple: we take all rows, columns, diagonals, and antidiagonals (just as in the n-queens validator), then take all length-4 substrings of those, then sort them in such a way that the winning line of 4 sorts to the end. (We need the tiebreak in case there's an `OOOO` in addition to the `XXXX` or `YYYY`.) Take the last element of the last element, and that'll be `X` or `Y` as required.
[Answer]
# PHP, 71 Bytes
```
echo preg_match('#X(XXX|(.{8}X){3}|(.{7}X){3}|(.{9}X){3})#',$argn)?X:Y;
```
[Online Version](http://sandbox.onlinephpfunctions.com/code/6ec61d461581b06d0369684b3c8be380a3382740)
[Answer]
# [Python 2](https://docs.python.org/2/), ~~201~~ ~~143~~ ~~129~~ ~~128~~ 107 Bytes
I decided to add horizontal, vertical, and diagonal together into one list and then add increment then look for X for times in it. And since there will always be a winner, I can assume Y won if X doesn't. This codes takes a matrix of all the different pieces and empty places.
```
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)]))]
```
[Try it online!](https://tio.run/##PYvNCsIwEIRfJexpt1UpIgqCz@A1EnOI@Le22YRSD/XlY9Kic/q@YSaOwzPIOrWHc@qcv1yd8ns4aTBORgQN1YYFYPUKLOjoHnrlFIv6cMTKU@3riQw0UOFuybkxbGtosvPE5cLl0jt53HBLlsim2LMMqkWW@B6QKBk4zoFFIZ0zkS4yd0V@9N/lJdgv "Python 2 – Try It Online")
Credits
* From 129 to 107 bytes by [ASCII-only](https://codegolf.stackexchange.com/users/39244/ascii-only).
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), ~~66~~ ~~65~~ ~~58~~ 54 bytes
I just check if X is the winner, as `There will always be one winner, and only one winner`. Thanks to [edc65](https://codegolf.stackexchange.com/a/117207/80745).
Input is a string with `no dividing character`. Thanks to [Arnauld](https://codegolf.stackexchange.com/a/117199/80745).
```
param($b)'YX'[1-in(0,5,6,7|%{$b-match"X(.{$_}X){3}"})]
```
[Try it online!](https://tio.run/##fVBfC8IgEH/3U8hwqeCiiAqCoG/Q60lEbGUsWLXWosD52dfpqpeoEz3u9@dOrjzfTXXNTVG0bE/n1LZlWqVHwTLJNfDVMDmcxECN1URNm9iyLDmm9TaPQPQt2ziQduQiJ9etI2QhCFGCA1d8@Te0Di9gLLn86wkarw0enwC/FTwaPQFAFfbSQexlGjEPYoGlT585@nuO/p1//i1ooMvQXfAHp6GHSNrQmFpCMZh5lGZbm52iLDun1Q6XzDYdVZnrragR6OHuOzYQERMvLjGXTwM5ezsi4ton "PowerShell – Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), ~~105~~ ~~90~~ ~~81~~ 80 bytes
Regex based. Lines are space separated. Saved 9 bytes thanks to @Lynn.
Saved 1 byte by utilizing the fact that there is a guaranteed match. So if there's no win for X then there must be a win for Y.
```
lambda x:re.findall('X(XXX'+'|(.{%d}X){3}'*3%(6,7,8)+')',x)and'X'or'Y'
import re
```
[Try it online!](https://tio.run/##jZDNCoMwEITvfYpcyiateBHaUvAZvM5CLxaVClYleLC0Prtdk/4dpJjLF7LMZGbbW3dp6mgs4tNYpddzlqr@aPOwKOssrSpN0ABoSw8d3tfZAHOPBtpEa70L9sHBbMlQ0Ju0zgjUWGJalde2sZ2y@djasu50oSnxR80RnvAEyyGj4liJl1ktsvBkdmTJi@RlgSUWTiBkeIuJYMxZuNEkkV/YSyeNktCuAFx@z2@K/0X4U@D9zu@5XJZb4GUB5bcqhOwz@SkyPgE "Python 3 – Try It Online")
[Answer]
# [Zsh](https://www.zsh.org/), ~~207 ...~~ 158 bytes
*Version history: 4 iterations for ~25 bytes first week; then 3 more iterations for ~25 bytes 6 months later, 1 more for 1 byte 11 months later.*
```
t(){a=($^a-$^@_);for s l (${w:^^argv}){s+=$l;i=;repeat $#s a[++i]+=$s[i+1];}}
w=(+)
t $@
for s;w[++j]=${(l:j:)}_
t $@
t ${(Oa)@}
[[ $a = *XXXX* ]]&&<<<X||<<<Y
```
~~([first](https://tio.run/##hVFdb5swFH33r7gCmkARadpHAlM2bX3loS9Y09o6wQRL1EYGgjbk355dQ1OtH9uuhI449557ju1fbXUaKlFz0JwVUAvJN1Aowo@shpZ3EEXgeJZ2CN9XCiIJzl2l@rqAHQfvOgaHtJUou1PnB2OpNLRQg@@N3jjE9/dMH47GBG2YevViYdu@L9L1RoRh4rntJgjYd/EDuy3CxpAh9cOAsBQXbK8urh5MQDrwtjPDkImQebsGtwwoTx8bLWRXwoU3CtM@vlHCvGv0MxZsDUmSxIb0Rgfbxondyxzr0sQhNXGUm5MLd3ut6hqvY5DQKfjKd/0BpiOqJw5PSnMQslQx2bMOPi1uIEngW3ZLviimi5ig1a11iuYin7VmP59pZkg6F7EKDLNMX9WS9NLePwNBCiX5KYdsrn8gpRNSe5IMXJtnZ7PANfm7fBpGpPkst5jT/E/5DaEzbcdxO51ldh4o0hOPv0hMOLuvVivUvbOlL2nPPD337T73o6jTaP6smfr5hHmGWTAq@mCeNX4vuLZx1ut3/Bmn4w0C31fzrtcSchAlDJo1jZAHEK1c4u3v96qXHS/ss39g8j@zyaSsRdPgiiPXrVASVAlsp46c/AY "Zsh – Try It Online"))
([second](https://tio.run/##hVHRbpswFH33V1wBTaCIlPaRwJRNW1/z0Besql2dYIIlakeGBG3I355em6ba1m67Ejri3HvuObZ/ds1paETLQXNWQSskX0KlCD@yFjreQ5KAF1jaI3zbKEgkeHeNOrQVbDgE1xl4pGtE3Z/6MBprpaGDFsJgDMYhe3xkenc0JuriImhnM9sOQ1GkSxHHeeB3yyhi9@IBux3C0pChCOOIsAIXrK4urr6biPQQrCaGIZMggwuIc1oO93EsHoqnvRayr@EiGIXpnv6QwLRkDNcsWhmS57lNF4weto2X@Zcl1qXJYmqypDQnH@62WrUt3sMgoVfwlW8OO3CO6pnDs9IchKxVRrash0@zG8hz@La@JV8U01VG0OrWOiVTkc9asx@vNDOkmIpYBYaZF7/VnBykvXgGglRK8lMJ66n@gZQ6pPYka/Btno3NAtfk73I3jEjLSW6xpOWv8htCJ9qO43Y6yew8UKQdj79IOJzcF4sF6t7Z0re0Z56e@3af/1FUN1q@aly/dFiuMQtGRR/Mk@L3hqmNk6bv@DO64w0C31fz/qAllCBqGDTb74XcgejkHG9/u1UH2fPKPvsHJv8zcyZ1K/Z7XHHkuhNKgqqBbdSRkxc "Zsh – Try It Online"))
([third](https://tio.run/##hVJdb9owFH33r7gKKSRFodDHfExs2vrKQ19sVe1qEgcspTZyAtGG8tvZtUOqdqWbETrKufecc33l3/X21G5lJcAIXkAllUig0EQceAW1aCCKwPMt7RGRbzVECrz7rd5XBawF@IsYPFJvZdmcmiA8ltpADRUE/rGNn5642Ry6sJ5mfjUe21oQyGyeyOk09Ud1Eob8QT5itUZIOtJmwTQkPEP18ubq5mcXkgb8Zc9wZCJkZLYgLiZpH9DoMXveGamaEq78o@zq578k0JscgxUPlx1J09Q/2p@H5c6LR9cUz3UXT1kXR7Q7jeA@N7qqcAmtgkbDd7Heb8Al6hcBL9oIkKrUMcl5A1/Gt5Cm8GN1R75pboqYYNSdTYr6Q74aw3@dad6RrD/EKnCYSfbuTMhe2a1zkKTQSpworPrzD2TMIbM3WcHIzrO2s8CCfC53zYiM9nKLlNG38lvCetq2ozvrZbYfGNKOx08kHPbps9kMdR9i2eu0A8@GuvUbXRrVtdKzxtWpQ7rCWajT0KGXDlo6eNBL13bXo1BIviH0TRd950I/WdpZbcRBmFr0LszuZI7/V5zblcznH/gBnUsr8Y0Z0eyNQkdZQmv4bifVBmStJvgC8lzvVSMK@/QuhPwvzIWUldzt0MKOK7UCXQJf64MgfwA "Zsh – Try It Online"))
([fourth](https://tio.run/##hVLRbtowFH33V1wlKSSNQqGPIZnYtPWVh77YqtrVEAcspTZyAtGG8u3s2iFVu9LNCB3l3HvOub7y73p7areyEmAEL6CSSsyh0EQceAW1aCBJwAss7RGx3mpIFHj3W72vClgJCGYpeKTeyrI5NWFUagM1VBAGxzZ9euJmc@iiOs6DajSytTCU@XQu4zgL/HoeRfxBPmK1RiBtHsYR4TlqFzdXNz@7iDQQLHqGI5MgI/MZcSHz9gFtHvPnnZGqKeEqOMqufv5LAr3JMVzyaNGRLMuCo/15WO681L@meK67NGZdmtDu5MP92uiqwg20ChoN38VqvwGXqF8EvGgjQKpSp2TNG/gyuoUsgx/LO/JNc1OkBKPubFLSH/LVGP7rTPOO5P0hVoHDjPN3Z0z2yq6cgySFVuJEYdmffyBjDpm9yRJ8O8/KzgIz8rncNSMy2sstUkbfym8J62nbju6sl9l@YEg7Hj@RcNinTyYT1H2IZa/TDjwb6tbPvzSqa6VnjatTh3SJs1CnoUMvHbR08KCXru2uR6GQfEPomy76zoV@srSz2oiDMLXoXZjdyRT/rzi1K5lOP/ADOpdW4hszotkbhY6yhNbw3U6qDchajfEFrNd6rxpR2Kd3IeR/YS6krORuhxZ2XKkV6BL4Sh8E@QM "Zsh – Try It Online"))
([fifth](https://tio.run/##hVJNb@IwFLz7VzxBCkkjaOgRkhUr7VbaE4debCG6NcQBV6kdOQnRbstvZ58dUvWDdp@UjDx@M/Ns@W@5OzY7mQswgqeQSyVmkGoi9jyHUlQwGkHPs3SPiM1Ow0hB73an6zyFtQBvMoUeKXcyq46VH2TaQAk5@N5TM72742a7PwRlmHj5YGD3fF8m0UyGYez1y1kQ8KVc4W6JQJrEDwPCE9TOry6ufh8CUoE3bxmOzAgZFzBrlmH4sEruCyNVlcGFt5zgurx/J4DW4slf8GB@IMsleBwSuKRYl7BaDQZxHNPnZ/yzYx9uN0bnOR6@UVBp@CHW9RZcoH4U8KiNAKkyPSUbXsG3wTXEMfxc3JBfqqirKcGcGxszaot8N4b/OdH8QJK2iFVg4DB5U0NSK3vbHCQ8kFQrcaSwaOsLZMwhsydaQN9OtNbcpDAhn8tdMyKjrdwiZfS1/Jqwlrbt6M5ame0HhrTjcYmEwzZ9PB6j7kMse5m241m3b/3650Z1rfSkcfvUIV3gLNRpaNdLOy3tPOi5Y7vjUUgl3xL6qou@caGfXNpJbcRemFK0LszeSYTfC0b2SqLoA9@hc2kkvjIjqtoodJQZNIYXhVRbkKUa4hvYbHStKpHax3cm5H9hLiTLZVGghR1XagU6A77We0H@AQ "Zsh – Try It Online"))
([sixth](https://tio.run/##hVLBbuIwEL37K0aQhaQRNO0xJBWVdivtiUMvthCtDHHAKLWRkxDtUr6dHTukard0dyR4ypt582ZG/l1uTs1GFgKM4BkUUokJZJqIPS@gFBWMRtDzLN0jYrXRMFLQe9zoushgKcC7iaFHyo3Mq1PlB7k2UEIBvndo4qcnbtb7Y1CGqVcMBjbn@zKNJjIME69fToKAz@UCsyUCaVI/DAhPUTu9/nb9fAxIBd60ZTgyI2ScwaSZh@F2kXoHv4i3cXB8/qsSWu3Bn/FgeiTzOXgcUriiGFewWAwGSZLQ11f8Z6c@PK6MLgrculFQafgulvUanJN@EfCijQCpch2TFa/gbnALSQI/Zg/kp9rVVUzQ58HajNog98bwX2eaH0naBrEKNBymH2JIamXPzEHClmRaiROFWRv/QMYcMrvRDPp2oqXmJoMb8rXcFSMy2sotUkbfy28Ja2lbjt1ZK7P1wJB2PH4i4bB1H4/HqPtky96m7XjW5W2//qVRXSk9a1yeOqQznIU6De1qaaelXQ96aW23HoVM8jWh76rohy70i6Od1UbshSlF24XZm0T4e8PIniSKPvEdui6NxFdmRFUbhR1lDo3hu51Ua5ClGuIbWK10rSqR2cd3weR/Zs4kL@Ruhy3suFIr0Dnwpd4L8gc "Zsh – Try It Online"))
([seventh](https://tio.run/##hVJNa@MwEL3rVwyJcewah7RHfyxZ2C3sKYdeJEJSFFtOFFQpyHbMbprfnpXkuLQ03R2wHp6Z996M0J96d@l2XDDQjJYguGQplAqxIxVQswbiGEaeTY8QK3YKYgmjp51qRQkbBt59AiNU73jVXJogPNE88NY09tbz5zCtlIYaBATeqUvWa6q3x3NYR7knfN/WgoDns5RHUeaN6zQM6ZKvTLU2kJ5RlwdRiBrw5sgJpd0yivar3DsFItkn4fm5L5rjFCxoOD@j5RI8CjncYRN3sFr5fpZl@PXVnOQyhqdCKyHMep2ERsEPtmm34MTVC4MXpRlwWakEFbSBb/4DZBn8XDyiX/LQNgkyPo/WJu4Dfdea/r6m6RnlfSDLMIaT/ENMUCvtfVLgsEelkuyCYdHHP5AQh8RutICxnWijqC7hHn1Nd80GCe7pFjHB7@kPiPRp227USU@z/UBM2uXNr0k47N2n06nhfbIlb9MOeTLUrd741qiuFV85ro4d4oWZBTsOHnrxwMWDBr61tlsPQ8npFuF3XfiDCv7i0q5szY5M16xXIfZOZuZ7w5m9ktnsU35Ap9Jx88o0a1otjSKvoNP0cOByC7yWE/MGikK1smGlfXw3TP5n5kwqwQ8HI2HH5UqCqoBu1JGhvw "Zsh – Try It Online"))~~
([eigth](https://tio.run/##hVLBbuIwEL37K0YQQVIEgh4TUlFpt9KeOPRiC0FliANGqR05CdEuzbezY4dUrUp3R4qfMjPvvRnLf4rDpT7ITIARPIFMKhFBook48QwKUcJ4DD3PpntE7A4axgp6zwddZQlsBXizEHqkOMi0vJR@cOax72342NssXoIo1QYKyMD3znW42XCzPzXBuRjFXhbJODIiF7wEr18AX41Gco2FYiVHs3XUNKSO/VFAsLwgTieqsee4jr2zn4XHMGhe2iIeZ3/Jg0VDVivwOMRwRzHuYL0eDObzOX17w5Nd@vC8MzrLcLtaQanhh9hWe3Di@lXAqzYCpEp1SHY41sPgHuZz@Ll8Ir9UXpUhQZ8nazNugzwaw39f07whcRvEMtBwGH@KIamUvU4OEo4k0UpcKCzb@Acy5pDZjZbQtxNtNTcJzMj3dNeMyGhLt0gZ/Ui/J6xN23ZUZy3N9gPDtMvjLyYctu6TyQR5X2zZ@7RdnnV1q9e/NaprpVeOq1OHdImzUMehXS/tuLTToLfWdutRSCTfE/qhi35Sod9c2pVtxEmYQrQqzN7JFL93nNormU6/5Dt0KrXEV2ZEWRmFijKF2vA8l2oPslBDfAO7na5UKRL7@G6Y/M/MmaSZzHOUsONKrUCnwLf6JMhf "Zsh – Try It Online"))
In the footer, I print both the input board and the array we build from it to stderr. Scroll down to debug to see them. The array we build is a lot longer now, since `t` does a cartesian product with input board on *every* call. (Hey, it shortened the code by a few bytes.)
There's a lot to cover here, so I moved the (sixth edition) comments to [an annotated gist](https://gist.github.com/xPMo/e549b802c408e0b8e93cacecb3c5ed9b).
(tl;dr: concatenate transpositions of the original array, but make sure to keep them separated)
[Answer]
# [Ruby](https://www.ruby-lang.org/), 84 bytes
Takes the board as a single continuous string with no separators. Finds a non-O character 
that's in a connect-4 and returns it.
```
->b{b[(0..41).find{|i|b[i]!=?O&&[1,6,7,8].any?{|j|(1..3).all?{|n|b[i+j*n]==b[i]}}}]}
```
[Try it online!](https://tio.run/##fY9NboMwEEb3nMKVIn5SahUlaruhHIHtjKgVBQUSImRVAVQh4Ox07ClZhc7m2Z439udbl/dzGX/NL5/5kGf@q5T7KJBlpU/DWI15VqmnOEldN4vCt/A9/FDyqPtkGK@jH0m5C@Sxrmmrjfp83WoVx2ZomiY1zT@Xqi7EuWgbR3x3bSPKbHOQ7c33hBd6XqCcQp/mlEs8IjCBCUjl/OczES0RqNJV33aJCOwbAoJjafo0j@wZQdDbNgfYGMyH9@M9x3KOS58WKz78@SD420SgD6ewkh/5PrS@CWJJWX8B "Ruby – Try It Online")
[Answer]
# [K (ngn/k)](https://bitbucket.org/ngn/k), ~~58 55~~ 56 bytes
```
{"XY"@|/&/'88<x ./:/:,/{x+/:/:+3+[4#1-+!3 3;]\&4}'+!6 7}
```
[Try it online!](https://tio.run/##jY5NDoIwEIX3nqJUA5qKjYEoaV14A7YzARLcYAwGE8ICgnh1bAuYuPBnNt/0dd7My93iXPR9JloKSI93bnMnCA412XDBxZq3NdMN81jkz7cuszziySS2/c5h1o7su74S7SJqHqXISC3TWy6XaXa6XGUtG1mukm5WRZTQmIZDkc9ENERQFVJJgSa/zGZUEWEwawLCu9mIelhtxsGkpwkq2ejqqQTD4TJ@uYyvuJOO079q/jHDaNYMwRBClWyM3T8B "K (ngn/k) – Try It Online")
`{` `}` function with argument `x`
`+!6 7` all possible pairs of 0..5 and 0..6
`{` `}'` for each of them do
`4#1-+!3 3` are 4 of the 8 ortho-diagonal directions: `(1 1;1 0;1 -1;0 1)`
`3+[` `]\&4` start with a list of four zeroes (`&4`) and make 3 steps in each of the directions
`x+/:/:` start from each possible position and take the steps in each possible direction
`,/` concatenate. at this point we have a matrix of 4-lists of coordinate pairs, some of them extending beyond the board
`x ./:/:` look up the corresponding cells from `x`
`88<` which of them are `"Y"`-s? (88 is the ascii code of `"X"`)
`&/'` which 4-lists consist only of `"Y"`-s? (and-reduce-each)
`|/` is there at least one such? (or-reduce)
`"XY"@` if false return `"X"`, if true return `"Y"`
[Answer]
# [J](http://jsoftware.com/), 42 bytes
```
1 e.[:,4 4(*/"1@,|:,,{~3 0+3 5*/i.@4);._3]
```
[Try it online!](https://tio.run/##jZAxb8IwEIV3/4onhiZOzeGQdHGJFFGpEyJSJ59Q1KEKKl06lA3EXw9nu1RMUEv2Zz@/dz75a5xQtkXjkMHAwsmcEl7eVq9jiYE2ztSo82I2KVtzdMYcThXsY4WnYrajttbP9F71o1brJSE4@@BatBZlLhsny5G07pNP7YefPRrC8PH53eYNNg5bZJ3n7GFHYplrVSKapBWrujRukDmSvYxO/S8dvUL2KR3o2UvaXqWjGtxSm1Mq2BWLHHU5ihCZ3ra33ua/ji86X@5D1Tudx5D/TQd2PtLL1wn1eAY "J – Try It Online")
Takes input as a matrix of integers where 0 is blank, 1 is X, and 2 is Y. Returns 1 if X wins, 0 if Y wins.
[Answer]
# [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~29~~ ~~26~~ 25 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
í‚εεÐм«NFÁ]€ø`IIø)J»γ4ùSà
```
Input as a character-matrix.
Uses the legacy version for -1 byte, since min/max also works on characters. In the new version of 05AB1E, the trailing `à` (maximum) should have been `{θ` instead (sort, keep last item).
[Try it online](https://tio.run/##MzBNTDJM/f//8NpHDbPObT239fCEC3sOrfZzO9wY@6hpzeEdCZ6eh3doeh3afW6zyeGdwYcX/P8fHa0UqaSjoBQBIiLhBJjrDyFidRSikeQjUJVjKIrAYhyyokgsNkXgNikSC4FHEbJxsbEA) or [verify all test cases](https://tio.run/##MzBNTDJM/V@mFFCUWlJSqVtQlJlXkpqikJlXUFpipaCkU2nLpeSYXFKamIMQO7Tt0MJHTWuCXQ6tBMr6l5ZAxO2V/h9e@6hh1rmt57YennBhz6HVfm6HG2OBKg/vSDi07tC6wzs0vQ7tPrfZ5PDO4MML/ivphQGNsv8freQPATF5eBmRkRBGZAQQ@CvpKODTB1YDYkRGQPWBGBGRESB9YCZYFdCsSKjySDAjEigDkQIKAIUgDNz2RSKcB5eKhKsBsvDpi4DpAzP8IyCMCH@gmyKUYgE).
**Explanation:**
```
í                 # Reverse each row of the (implicit) input-list
 ‚                # Pair it with the (implicit) input-list
  ε               # Map over both matrices:
   ε              #  Map over each row:
    Ð             #   Triplicate the current row
     м            #   Remove all these characters, leaving a list of empty strings of the
                  #   same size as the row
      «           #   Merge this list of empty strings to the row
       NF         #   Loop the (0-based) row-index amount of times:
         Á        #    And rotate the row with appended empty strings towards the right
  ]               # Close the nested maps and inner loop
   €              # For both mapped matrices:
    ø             #  Zip/transpose; swapping rows/columns
                  # (we now have a list of all diagonals and anti-diagonals)
     `            # Push both lists of lists separated to the stack
      I           # Push the input again
       Iø         # And push the input, zipped/transposed
         )        # Wrap everyone on the stack into a list
                  # (we now have a list of all diagonals, anti-diagonals, rows, and columns)
          J       # Join each inner-most list of characters together to a string
           »      # Join each inner list together to a string; and then join these strings
                  # with newline delimiter
            γ     # Split everything into parts with equal adjacent characters
             4ù   # Only keep the parts of length 4
               S  # Flatten it to a list of characters
                à # And get the maximum character of this list
                  # (after which it is output implicitly as result)
```
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~114~~ 112 bytes
Using a [bitboard approach](https://stackoverflow.com/questions/7044670/how-to-determine-game-end-in-tic-tac-toe/7046415#7046415) to check for 4 in a row.  
Input: a 2D list of integers, where `0` represents empty cell, `1` is `X`, and `2` is `Y`.  
Output: a positive integer if X wins, or `0` if Y wins.
```
lambda L:(b:=sum(sum(zip(*(L+[[0]*7])),())[i]%2<<i for i in range(49)))*any((r:=b&b<<i)&r<<i*2for i in(1,6,7,8))
```
[Try it online!](https://tio.run/##dU5BTsMwELz7FSshGm/IoS2oLVb7g0q5cLAVIuS0DrWUupGbUgLi7cF2CFzISvbYszM7W7fN4WTuV7XtStjAc1fJY7GXsGW0YJvz5Uj9@dA1jen2LsumebzMEROKmOn8dr5eayhPFjRoA1aaV0UfHhExlqal1LJNMSmcBifW3fF8kNJZskiWyQqxux50peDJXhQjcHY7ZNlnlEZsmkQ8YrMkEhGbf2W7POTsfI429aWh2DMvf8kLzAnUVpuGlvSMSAYl3IB6b6wEo65QaaNAlo2yoN6UbaE4Sbvv0r7IOAoRUHBXKRkVhrZDwXuDRy446R9e4CaIXugVRDg68O7riID/J4jfVQZeDH0/aMTAfwweUx6Qp24D/g0 "Python 3.8 (pre-release) – Try It Online")
## Explanation
The bitboard's layout is as follow (the missing positions in the last row is padded with 0):
```
0  8 16 24 32 40 48
1  9 17 25 33 41 49
2 10 18 26 34 42 50
3 11 19 27 35 43 51
4 12 20 28 36 44 52
5 13 21 29 37 45 53
6 14 22 30 38 46 54
```
This is the core of the function: given the bitboard `b` representing X's occupancies, check if X is winning:
```
any(
    # shift the board by i, 2i, 3i, 4i and and all of them together
    # if there's a set bit in the result (aka result != 0), then there is a 4-in-a-row
    (r:=b&b<<i)&r<<i*2 
    # do this for all 4 directions
    # 1: vertical, 7: horizontal, 6 and 8: diagonal
    for i in(1,6,7,8)
)
```
This part contructs the bitboard `b` for X:
```
b:=sum(
    sum(zip(*
        (L+[[0]*7]) # append a row of 0 at the bottom of L
    ),())           # flatten L into a list, with the index correspond
                    #   to the correct position in the bitboard layout
    [i]%2<<i        # set the ith bit to 1 if the new list has X (=1) at that index      
    for i in range(49)
) # sum all the set bits together to create the bitboard
```
]