Crazy Python solution - 79 characters
max([b[x] for x in range(9) for y in range(x) for z in range(y)
if x+y+z==12 and b[x]==b[y]==b[z]] + [0])
However, this assumes a different order for the board positions in b:
5 | 0 | 7
---+---+---
6 | 4 | 2
---+---+---
1 | 8 | 3
That is, b[5]
represents the top-left corner, and so on.
To minimize the above:
r=range
max([b[x]for x in r(9)for y in r(x)for z in r(y)if x+y+z==12and b[x]==b[y]==b[z]]+[0])
93 characters and a newline.
Update: Down to 79 characters and a newline using the bitwise AND trick:
r=range
max([b[x]&b[y]&b[z]for x in r(9)for y in r(x)for z in r(y)if x+y+z==12])
This is a variant of dmckee's solution, except that each pair of digits in the Compact Coding is now the base-9 digits of the ASCII characters.
The 77-char version, does not work on MSVC:
// "J)9\t8\r=,\0" == 82,45,63,10,62,14,67,48,00 in base 9.
char*k="J)9 8\r=,",c;f(int*b){return(c=*k++)?b[c/9]&b[c%9]&b[*k--%9]|f(b):0;}
This 83-char version, should work on every C compiler:
f(int*b){char*k="J)9 8\r=,",s=0,c;while(c=*k++)s|=b[c%9]&b[c/9]&b[*k%9];return s;}
(Note that the spaces between the 9 and 8 should be a tab. StackOverflow converts all tabs into spaces.)
Test case:
#include <stdio.h>
void check(int* b) {
int h0 = b[0]&b[1]&b[2];
int h1 = b[3]&b[4]&b[5];
int h2 = b[6]&b[7]&b[8];
int h3 = b[0]&b[3]&b[6];
int h4 = b[1]&b[4]&b[7];
int h5 = b[2]&b[5]&b[8];
int h6 = b[0]&b[4]&b[8];
int h7 = b[2]&b[4]&b[6];
int res = h0|h1|h2|h3|h4|h5|h6|h7;
int value = f(b);
if (value != res)
printf("Assuming f({%d,%d,%d, %d,%d,%d, %d,%d,%d}) == %d; got %d instead.\n",
b[0],b[1],b[2], b[3],b[4],b[5], b[6],b[7],b[8], res, value);
}
#define MAKEFOR(i) for(b[(i)]=0;b[(i)]<=2;++b[(i)])
int main() {
int b[9];
MAKEFOR(0)
MAKEFOR(1)
MAKEFOR(2)
MAKEFOR(3)
MAKEFOR(4)
MAKEFOR(5)
MAKEFOR(6)
MAKEFOR(7)
MAKEFOR(8)
check(b);
return 0;
}
Not the shortest Python solution, but I like how it introduces "DICE" into a game of tic-tac-toe:
W=lambda b:max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
69 chars for the simpler expression:
max([b[c/5-9]&b[c/5+c%5-9]&b[c/5-c%5-9]for c in map(ord,"DICE>3BQ")])
A function that returns 0, 1 or 2, using a regular expression, of course (the newline's only there to avoid the scrollbar):
sub V{$"='';$x='(1|2)';"@_"=~
/^(...)*$x\2\2|^..$x.\3.\3|$x..\4..\4|$x...\5...\5/?$^N:0}
It can be called as V(@b)
, for example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With