Count Mills in Nine Men's Morris

JavaScript (ES6), 276 228 125 117 105 bytes

a=>btoa`i·yø!9%z)ª»-ºü1j;ÝÈ%¥·¡ªÜ"·ç¹Ê1`.replace(/.../g,b=>(a[b[0]]+a[b[1]]+a[b[2]])/3&1||'').length

(the above contains some unprintable ascii characters that won't show up here, so here's a version without the btoa that can be copied and run)

a=>'abcdefghijklmnopqrstuvwxajvdksglpbehqtwimrfnucox'.replace(/.../g,b=>(a[b[0]]+a[b[1]]+a[b[2]])/3&1||'').length

Breaks a reference string into letter triplets that match up with mill group keys. Input is in the form of an object, where keys are the letters a-x, starting from the bottom left and ending in the top right, moving left-to-right first. Values are 1 for white, -1 for black, and 0 for blank.

Example

{b:1,d:-1,e:1,f:-1,i:1,k:-1,l:-1,m:1,n:-1,r:1,u:-1} => 2
{j:1,d:-1,k:-1,l:-1,b:1,e:1,i:1,m:1,r:1,f:-1,n:-1,u:-1,o:1} => 2
{a:-1,j:-1,v:-1,k:-1,l:-1,h:1,e:1,b:1} => 3
{} => 0
{k:-1,j:-1,l:1} => 0
{k:-1,j:-1,l:1} => 1
{a:-1,j:-1,v:-1,d:-1,k:-1,s:-1,g:-1,l:-1,p:-1,i:1,m:1,r:1,f:1,n:1,u:1,c:1,o:1,x:1} => 8

These examples are taken from OP's examples, converted to the letter-key and number-value object. The first is from the example image, while the others are from the example set.


APL (Dyalog Classic), 26 25 bytes

-1 thanks to FrownyFrog

≢{|∊(+/⍵⍪↓⍵),⊢/4 2⍴+⌿⍵}∩≢

Try it online!

The argument is a 3x3x3 array of 1(black), ¯1(white), and 0(empty). The first dimension is along the concentric squares' nesting depth. The other two dimensions are along the vertical and horizontal axis.

000---------001---------002
 |           |           |
 |  100-----101-----102  |
 |   |       |       |   |
 |   |  200-201-202  |   |
 |   |   |       |   |   |
010-110-210     212-112-012
 |   |   |       |   |   |
 |   |  220-221-222  |   |
 |   |       |       |   |
 |  120-----121-----122  |
 |           |           |
020---------021---------022

We have a mill whenever summation along any axis yields a 3 or ¯3, except we must discard the four corners when summing along the first axis.

{} is a function with implicit argument

↓⍵ is split - in our case it turns a 3x3x3 cube into a 3x3 matrix of nested length-3 vectors

⍵⍪↓⍵ takes the original cube and glues the 3x3 matrix of 3-vectors below it, so we get a 4x3x3 mixed array of scalars and vectors

+/ sums along the last axis; this has the combined effect of summing the original cube along the last axis (+/⍵) and summing it along the middle axis due to the split we did (+/↓⍵)

Now we must take care of the special case for the first axis.

+⌿⍵ sums along the first axis, returning a 3x3 matrix

4 2⍴ but we must not count the corners, so we reshape it to a 4x2 matrix like this:

ABC      AB
DEF  ->  CD
GHI      EF
         GH  ("I" disappears)

now we are only interested in the last column (BDFH), so we use the idiom ⊢/

, concatenates BDFH to the matrix we obtained before for the 2nd&3rd axis (BDFH and the matrix both happen to have a leading dimension of 4)

flattens everything we obtained so far into a single vector

| takes the absolute values

{ }∩≢ filters only the threes - the length (≢) of the input is always 3

counts them


Mathematica, 217 131 Bytes

While I'm sure this is not particularly competitive, here's an entry for you.

Count[Total/@{{a1,d1,g1},{b2,d2,f2},{c3,d3,e3},{a4,b4,c4},{e4,f4,g4},{c5,d5,e5},{b6,d6,f6},{a7,d7,g7},{a1,a4,a7},{b2,b4,b6},{c3,c4,c5},{d1,d2,d3},{d5,d6,d7},{e3,e4,e5},{f2,f4,f6},{g1,g4,g7}}/.#/.{"w"->1,"b"->2},3|6]&

Input example:

{a4 -> "w", b2 -> "b", b4 -> "b", c4 -> "b", d1 -> "w", d2 -> "w", e3 -> "w", e4 -> "w", e5 -> "w", f2 -> "b", f4 -> "b", f6 -> "b", g4 -> "w"}

Allowing single-character coordinate names trivially golfs off 51 characters, making this a 166 byte solution. Naming the players 1 and 2 rather than "w" and "b" golfs off 17 further characters.

So we get

Count[Total/@{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,a,j,v,d,k,s,g,l,p,b,e,h,q,t,w,r,i,m,f,u,n,c,o,x}~Partition~3,3|6]/.#&