2 ms·
$ printf '%s\n' {a..f}{a..f}{a..f}{a..f}|head aaaa aaab aaac aaad aaae aaaf aaba aabb aabc aabd $ printf '%s\n' {a
by internet_points 1y ago
$ printf '%s\n' {a..f}{a..f}{a..f}{a..f}|head
aaaa
aaab
aaac
aaad
aaae
aaaf
aaba
aabb
aabc
aabd
$ printf '%s\n' {a..f}{a..f}{a..f}{a..f}|wc -l
1296
So say you've guessed acab and gotten two black pins, then you know nothing is in the right position, so you can `grep -v acab` but also that two of your pins should be used somewhere `grep -E 'a.*[cab]|c.*[ab]|b.*[ca]'` (hope I got that right?)
$ printf '%s\n' {a..f}{a..f}{a..f}{a..f}|grep -v acab | grep -E 'a.*[cab]|c.*[ab]|b.*[ca]'|wc -l
756
That filters your options down.
However, I don't understand how/whether grepping can give you the optimal next guesses – some of these will give you less information than others. (Of course, you could run some simulations with grep, argmaxing over all the possible responses like the article says, but then you're not just doing simple grepping.)