Jelly, 26 bytes
ṢŒrṪ4=$$Ðfx3ðœ-µẆm€6R¤;/µL
The input format is a little unusual; it's a string representing the board, but with Windows newlines (carriage return followed by newline). For example, XXO\r\nOXO\r\nOOX
. (Actually, any two-character padding string between the lines works, but Windows newlines are much more defensible than the other options.)
The basic idea is that we look for characters that appear 4 times in the input, but don't have three evenly spaced occurrences in the original string. With two or more characters of padding between the lines of a 3×3 grid, all horizontal, vertical, and diagonal lines are evenly spaced, but no other evenly spaced line can have three elements.
Explanation:
The ð
and µ
s are chain separators, which split the program into multiple parts that are each independent. I've replaced them with spaces below, to make things a bit clearer.
ṢŒrṪ4=$$Ðfx3 œ- Ẇm€6R¤;/ L
Ṣ sorted version of the input
Œr run-length-encode it
Ðf keep only elements where
Ṫ delete the last element, and it was
4= equal to 4
$$ parse Ṫ4= as a group
x3 repeat each element three times
Ẇ all sublists of the input
m€ take every nth element of each (€) sublist
6R for each n in 1..6
¤ parse 6R as a group
;/ flatten one level (m€ creates a nested structure)
œ- multiset difference
L length of that difference
In other words, we find the list of characters that appear exactly four times in the input, and make a list consisting of three copies of each of those; we find the list of all subsequences that are evenly spaced in the original string; and if we subtract the second from the first, we want the result to have length 1 (i.e. a player played four times but didn't win). Note that as we're on a 9×93×3 grid and every square is full, it's impossible for both players to have played four times. In Jelly, 1 is truthy, 0 is falsey, so we don't need to do anything special to convert the resulting list to a boolean. (The µL
is required, though, because otherwise both “XXX”
and “OOO”
would be possible truthy output values, and the question requires that all valid boards give the same output.)