[ 1, 101, 650, 1000, 465, 87, 11 ]
A simple algorithm computing the list of remaining possible words and picking either the first one if there are less than 3 of them, or the one located at a precomputed index otherwise. (This is therefore playing in 'hard mode'.)
The precomputed values are based on a hash of the list of remaining words and were simply found with a naive random search running for a while. They are probably very far from optimal ones.
const GRAY = 0;
const YELLOW = 1;
const GREEN = 2;
const LOOKUP = {'14143202':1,'26364370':2,'30190943':3,'38882992':23,'43995839':2,'46997544':2,'47100915':2,'58773399':2,'70621541':3,'76111564':0,'78629445':0,'83279074':4,'53c11c74':2100,'921bd960':36,'2528c69d':1,'7964d0cf':11,'2e48ad14':2,'8b3ca4cb':0,'79c8a291':121,'8cf4eed6':3,'67c21ff2':1,'bc7835a4':33,'26270c62':16,'5095e262':0,'6fc77853':90,'aa78d00f':2,'efd5ee03':13,'f7e85504':0,'9ed6869a':13,'2f28d552':2,'ebadec4c':9,'dd657502':1,'75e99b72':9,'9e4d1e39':1,'6b1ee6bc':0,'94847f8e':2,'d69854c6':1,'79f08c51':29,'975ea22e':5,'74a4f766':4,'93913d7d':1,'f5a80453':3,'834b3950':10,'d311f685':3,'cf69c214':0,'3c1bb448':1,'eea7d694':7,'67980f55':2,'5bc6e50f':1,'b6a74c7f':1,'41086a3f':5,'c42acaa3':5,'f1ed7962':19,'f013f6de':1,'e2c19ca8':6,'bd62ab41':2,'31850f4c':14,'a65e6c62':1,'d8d65610':0,'0b60b7a3':7,'377f178d':1,'bed253cc':2,'55417f48':21,'2a195973':2,'89b99ca0':0,'5734ec44':1,'d994dab6':6,'747ac68c':1,'5cbfb6df':4,'6d145f3f':9,'cd7cd6dd':4,'ef04be81':2,'4332f7de':4,'9d0bdd07':1,'dc12394d':9,'90ae0678':2,'c76b85f1':4,'ec06d2ca':2,'c1c8a84f':10,'e8c899d1':0,'cc022066':14,'48f50318':3,'cac2bc3a':3,'e25292bb':1,'48a08d77':5,'14db746d':1,'f086993f':0,'5ce89220':9,'f9ad9ada':1,'229f8965':0,'0c4905a7':0,'0302235f':0,'96f622f5':0,'54252eab':2,'0c8e25a6':3,'9286bc52':3,'d2d53386':2,'c8f8fb4e':166,'702bb5a4':16,'38cbb5d6':0,'4474aa82':18,'d96b3f5d':28,'30ec466d':4,'8796640a':2,'5ccf8034':4,'f397de6b':18,'40ba7a83':38,'85ee6b8a':2,'1ee95569':0,'e6881291':1,'165b616c':0,'bb9a5866':0,'79fbfdcf':27,'b43dee5f':2,'50f28e4b':197,'f2ba2523':23,'fdef66e9':1,'e53b6fb5':1,'d6d16e7d':15,'708ab8ab':13,'c1214176':1,'453b0ab9':1,'bf525f76':6,'9baaa801':12,'99a34529':3,'e8cdc21c':1,'a1d69531':3,'43cb5c4e':4,'f2cc4081':3,'4497f9dd':3,'2c4dd2f4':3,'7f76ec38':1,'216cf28f':6,'427af08e':1,'5565ea4a':3,'ab97f7e6':5,'d621e228':2,'ac239f20':6,'ab593aad':1,'e1a6be75':0,'07a70237':1,'e5849d40':1,'0771e66f':0,'f0b2ccad':3,'5263f0b5':4,'dc007dc6':1,'8061bddc':2,'1b738423':7,'9c3c3eb4':3,'2c207b38':3,'1e560e0c':1,'9d483c9c':1,'a54ad297':3,'adf1e213':1,'8ece546f':0,'2868ded4':1,'0be47967':2,'76c48ab0':1,'ec5a2986':5,'08f02724':4,'2f1e8fe0':13,'61b01746':2,'a945af43':2,'b3298621':0,'c902c85d':0,'59b4b3a6':0,'65adc148':7,'da2d4f4f':1,'bdabc7b7':1,'363a673f':78,'57df5665':21,'4dff9da8':2,'0e86ae9c':7,'6c77953e':1,'714ca992':2,'32f55d3c':0,'8f730c78':4,'bef4237c':9,'0cd58e64':1,'9782b612':1,'46e616b4':5,'d8aea010':1,'9928cb50':12,'49a9a502':0,'899b630b':2,'e62dc0ee':0,'5e422bc1':1,'028f178c':1,'0d18106f':1,'73318b3f':1,'f99ae1c9':34,'e1cd8425':4,'4dfed81f':3,'add3dd22':10,'3b3db49a':0,'f1034ad7':2,'4a5046f3':1,'7ac5ce28':2,'28536ff5':0,'75ea6e53':1,'63fea0b1':2,'ab09cc25':2,'d6ceba64':2,'bfc4bed7':3,'960d9151':0,'cd868422':3,'11a4d91c':1,'83a7119c':0,'6c552bd4':0,'77095d30':10,'c8bcfcac':2,'ba21e593':0,'3d336693':5,'fba36a94':2,'10f9f1ed':2,'6204e786':0,'6e07f888':2,'2bb3482a':10,'d686a716':2,'e31d35d2':2,'dce35a86':0,'78d964ba':1,'851c0f3b':1,'37f4f3b4':2,'fe75e788':1,'93d09506':5,'604107e8':0,'44c077ae':13,'0f7f452d':1,'7c9bce8b':4,'7e6687c7':2,'7e58e0a8':5,'7dbabf3c':0,'65aec92b':74,'5b0b56f2':4,'ce548f7e':1,'f37040ba':0,'61a3de73':0,'6e752063':1,'f70d8eb1':0,'3855ec7a':4,'ec9b1d60':1,'a9de0559':2,'5db0cc60':3,'09ac011b':1,'06f2bd54':19,'c0abb288':1,'7740b151':8,'a2e3e28b':0,'f4c7948d':2,'dd7e56a0':2,'257e38eb':2,'8ec556e6':2,'fad4a8aa':2,'007da174':3,'48a5ee80':8,'daf0805d':1,'2c0bbd90':22,'a68704dd':2,'2edc16a2':0,'bdd7d751':1,'12fa8a9c':2,'bd6c82c1':5,'daa03ebb':2,'14a007cc':3,'b057a058':3,'fe2e6048':3,'930b8a67':2,'e6021a93':0,'715f9f50':2,'3bb3f9c8':2,'314ae620':2,'bf9d0ff9':3,'d6f78470':3,'6ffd5525':0,'bfa4d989':7,'2fcb4ed3':1,'8dff3605':2,'cc0e1441':2,'510e2239':2,'932cad71':4,'8a2babae':7,'b5069042':2,'870facb1':2,'81dc1545':2,'a366065a':2,'7f92a451':1,'17e04242':1,'00f397da':1,'5c792244':0,'d0bb4351':0,'98ffa283':3,'78bac9e6':2,'14f2bafd':0,'d086c2ee':2,'08a38507':0,'5fd0ea1d':3,'2ba1913e':0,'117654e7':1,'f5eea614':7,'b811e17b':1,'69dda9de':3,'46b94977':2,'7b766732':3,'af195935':2,'b1eb20d4':3,'8b66476e':2,'aa533625':0,'be9f3907':0,'743ce282':3,'02a97dc8':4,'42bec4ec':0,'5f8be41b':2,'4e053217':17,'efaf99ff':2,'558976a8':3,'f61dff94':2,'13784ef6':0,'05354011':0,'382e4364':1,'6f20b790':1,'e1b754bf':2,'c979fdaf':1,'ddd9b414':1,'2a2dddfc':3,'7f585610':2,'dc70293f':12,'7f328e23':2,'bbc51714':4,'d970cf9e':1,'f1db083f':3,'c698465c':1,'d67bb6a4':2,'6bf5c971':0,'a5dad7ee':3,'c20230d7':2,'6c69bcc4':2,'ddaa91fc':0,'aceffaa8':3,'5ac4f937':0,'fb589434':0,'e3f3c1d7':2,'062698f6':0,'67cff0e7':0,'2c367774':1,'5f163080':0,'c526fc35':0,'b77cce91':0,'f69aa500':2,'9f5bb9b2':1,'88c58554':2,'4524f59e':1,'d8d3541e':1,'c007c12f':0,'71a48e89':4,'897fcd24':0,'8f6a94fe':0,'4ab727d1':3,'95d7089e':0,'44b3c427':4,'689a27db':2,'42f43571':3,'b02a73cd':0,'c4310e8c':1,'e605072f':5,'cea8ea81':1,'072fdcc0':1,'bb4c095c':1,'bb6830d5':2,'ae22f8fb':1,'ffa4e084':1,'79aec494':2,'db71d0dc':2,'8f481b7a':4,'5e30001f':1,'0e114e8c':1,'6ecfeac0':0,'da3c8846':1,'bb77b1b0':1,'3d8d6830':3,'063be66d':0,'b07584b9':1,'e6aa8602':2,'00ee7c82':4,'8a0b3a9b':1,'fff50a02':2,'9522070e':2,'9fb93302':2,'f5c487bb':1,'f3becf6c':2,'7acd7d34':1,'e39973c9':0,'48a2f6d7':10,'c556b389':0,'aae28d8b':2,'26394f7b':2,'6987fcb5':1,'3c8b70b5':1,'0ec76191':3,'bede1e43':3,'e9e75a90':2,'93ecaaaf':7,'9c85d484':0,'6cfc5c54':4,'0e956f0c':0,'e0ee2ae6':2,'ae37d2b7':6,'e7356cc4':1,'191bee62':4,'34ac52df':2,'edf40c22':1,'a3c46eae':1,'07c59ea8':0,'cebc4b79':2,'b83825b1':4,'967d3108':2,'52674dd2':1,'ad289b28':0,'671ce983':5,'3f340614':1,'99027f41':4,'96da67b7':0,'4a8871e3':0};
let wordList = require('fs').readFileSync(0).toString().split(' ');
let stat = [];
wordList.forEach(secret => {
let hist = solve(word => guess(word, secret)),
n = hist.length;
console.log('[' + secret + '] ' + hist.join(' '));
stat[n] = -~stat[n];
});
console.log(stat.slice(1));
function solve(blackBox) {
let list = [...wordList],
hist = [],
w, j;
for(j = 1;; j++) {
let key = list.join(''),
md5 = require('crypto').createHash('md5').update(key).digest('hex').slice(0, 8);
w = list[list.length < 3 ? 0 : LOOKUP[md5]];
hist.push(w);
let res = blackBox(w);
if(res.every(c => c == GREEN)) {
break;
}
list = filter(list, w, res);
}
return hist;
}
function filter(list, w, res) {
let cnt = {};
let exact = {};
res.map((c, i) => c == GRAY ? (cnt[w[i]] = ~~cnt[w[i]], exact[w[i]] = true) : cnt[w[i]] = -~cnt[w[i]]);
let pattern = RegExp(res.map((c, i) => c == GREEN ? w[i] : '[^' + w[i] + ']').join(''));
let newList = list.filter(word => pattern.test(word));
res.forEach((_, i) => {
if(cnt[w[i]] !== undefined) {
newList = newList.filter(word => {
let n = [...word].reduce((p, c) => p += c == w[i], 0);
return exact[w[i]] ? n == cnt[w[i]] : n >= cnt[w[i]];
});
}
});
return newList;
}
function guess(word, secret) {
let misplaced = {};
[...secret].forEach((c, i) => c != word[i] ? misplaced[c] = -~misplaced[c] : 0);
return [...word].map((c, i) => c == secret[i] ? GREEN : misplaced[c] ? (misplaced[c]--, YELLOW) : GRAY);
}
Try it online!