Java, 24,9700 คะแนน (ชนะ Perl จีน Goth ในการทดสอบของฉัน)
อัปเดตอันดับแล้ว:
4 5 6 7 8 9 10 11 12 13 รวมทั้งสิ้น
perl chinese_perl_goth.pl 6700 12300 16900 19200 23000 26100 28500 29600 32100 33900 228300
java Lingo 9400 14700 18900 21000 26300 28700 30300 32400 33800 34200 249700
นี่คืออันดับเก่าที่ใช้pit.rb
:
4 5 6 7 8 9 10 11 12 13 รวมทั้งสิ้น
ruby player-example.rb 200 400 400 500 1800 1400 1700 1600 3200 4400 15600
ruby player-example2.rb 2700 3200 2500 4300 7300 6300 8200 10400 13300 15000 73200
ruby player-example3.rb 4500 7400 9900 13700 15400 19000 19600 22300 24600 27300 163700
perl chinese_perl_goth.pl 6400 14600 16500 21000 22500 26000 27200 30600 32500 33800 231100
java Lingo 4800 13100 16500 21400 27200 29200 30600 32400 33700 36100 245000
** การจัดอันดับ **
1: java Lingo (245000)
2: perl chinese_perl_goth.pl (231100)
3: ruby player-example3.rb (163700)
4: ruby player-example2.rb (73200)
5: ruby player-example.rb (15600)
เมื่อเทียบกับ @chineseperlgoth ฉันแพ้ในคำที่สั้นกว่า (<6 ตัวอักษร) แต่ฉันชนะในคำที่ยาวกว่า (> = 6 ตัวอักษร)
ความคิดคล้ายกับ @ chineseperlgoth เป็นเพียงความคิดหลักของฉันเกี่ยวกับการค้นหาการเดา (อาจเป็นคำใด ๆ ที่มีความยาวเท่ากันไม่จำเป็นต้องเป็นหนึ่งในความเป็นไปได้ที่เหลืออยู่) ซึ่งให้ข้อมูลมากที่สุดสำหรับการคาดเดาครั้งต่อไป
ขณะนี้ฉันยังคงเล่นกับสูตรอยู่ แต่สำหรับกระดานคะแนนด้านบนฉันเลือกคำที่จะให้ผลขั้นต่ำสำหรับ:
-num_confusion * เอนโทรปี
เวอร์ชันล่าสุดใช้การให้คะแนนที่แตกต่างกันเพื่อค้นหาการทายที่ดีที่สุดต่อไปซึ่งเป็นการเพิ่มจำนวน "ความเป็นไปได้ครั้งเดียว" สูงสุดหลังจากการเดาปัจจุบัน สิ่งนี้ทำได้โดยการลองทุกคำใน wordlist ที่ถูกตัด (เพื่อประหยัดเวลา) กับผู้สมัครที่เป็นไปได้ทั้งหมดและดูว่าการเดาแบบไหนที่เป็นไปได้มากกว่าในการสร้าง "ความเป็นไปได้ครั้งเดียว" (นั่นคือหลังจากการเดานี้ เดาต่อไป
ตัวอย่างเช่นการวิ่งครั้งนี้:
เริ่มต้นรอบใหม่คำว่า boons
เตรียมพร้อม: seora
ส่งแล้ว:? XOXX
เตรียมพร้อม: topsl
ส่งแล้ว: XOX? X
เตรียมพร้อม: พระภิกษุ
ส่งแล้ว: XO? XO
เตรียมพร้อม: bewig
ส่งแล้ว: OXXXX
เตรียมพร้อม: boons
ส่งแล้ว: OOOOO
รอบชนะด้วยคะแนน 100
จากการคาดเดาสามครั้งแรกเราได้รับ "* oo * s" ด้วย "n" ที่ไหนสักแห่งแล้วและเรายังต้องหาตัวอักษรอีกหนึ่งตัว ตอนนี้ความสวยงามของอัลกอริทึมนี้คือแทนที่จะคาดเดาคำที่คล้ายกับรูปแบบนั้นแทนที่จะคาดเดาคำที่ไม่เกี่ยวข้องกับการเดาก่อนหน้าเลยพยายามให้ตัวอักษรมากขึ้นหวังว่าจะเปิดเผยตัวอักษรที่หายไป ในกรณีนี้จะเกิดขึ้นเพื่อให้ได้ตำแหน่ง "b" ที่หายไปอย่างถูกต้องและสรุปด้วยการคาดเดาสุดท้าย "boons" ที่ถูกต้อง
นี่คือรหัส:
import java.util.*;
import java.io.*;
class Lingo{
public static String[] guessBestList = new String[]{
"",
"a",
"sa",
"tea",
"orae",
"seora", // 5
"ariose",
"erasion",
"serotina",
"tensorial",
"psalterion", // 10
"ulcerations",
"culteranismo",
"persecutional"};
public static HashMap<Integer, ArrayList<String>> wordlist = new HashMap<Integer, ArrayList<String>>();
public static void main(String[] args){
readWordlist("wordlist.txt");
Scanner scanner = new Scanner(System.in);
int wordlen = Integer.parseInt(args[0]);
int roundNum = 5;
ArrayList<String> candidates = new ArrayList<String>();
candidates.addAll(wordlist.get(wordlen));
String guess = "";
while(roundNum-- > 0){
guess = guessBest(candidates, roundNum==4, roundNum==0);
System.out.println(guess);
String response = scanner.nextLine();
if(isAllO(response)){
break;
}
updateCandidates(candidates, guess, response);
//print(candidates);
}
}
public static void print(ArrayList<String> candidates){
for(String str: candidates){
System.err.println(str);
}
System.err.println();
}
public static void readWordlist(String path){
try{
BufferedReader reader = new BufferedReader(new FileReader(path));
while(reader.ready()){
String word = reader.readLine();
if(!wordlist.containsKey(word.length())){
wordlist.put(word.length(), new ArrayList<String>());
}
wordlist.get(word.length()).add(word);
}
} catch (Exception e){
System.exit(1);
}
}
public static boolean isAllO(String response){
for(int i=0; i<response.length(); i++){
if(response.charAt(i) != 'O') return false;
}
return true;
}
public static String getResponse(String word, String guess){
char[] wordChar = word.toCharArray();
char[] result = new char[word.length()];
Arrays.fill(result, 'X');
for(int i=0; i<guess.length(); i++){
if(guess.charAt(i) == wordChar[i]){
result[i] = 'O';
wordChar[i] = '_';
}
}
for(int i=0; i<guess.length(); i++){
if(result[i] == 'O') continue;
for(int j=0; j<wordChar.length; j++){
if(result[j] == 'O') continue;
if(wordChar[j] == guess.charAt(i)){
result[i] = '?';
wordChar[j] = '_';
break;
}
}
}
return String.valueOf(result);
}
public static void updateCandidates(ArrayList<String> candidates, String guess, String response){
for(int i=candidates.size()-1; i>=0; i--){
String candidate = candidates.get(i);
if(!response.equals(getResponse(candidate, guess))){
candidates.remove(i);
}
}
}
public static int countMatchingCandidates(ArrayList<String> candidates, String guess, String response){
int result = 0;
for(String candidate: candidates){
if(response.equals(getResponse(candidate, guess))){
result++;
}
}
return result;
}
public static String[] getSample(ArrayList<String> words, int size){
String[] result = new String[size];
int[] indices = new int[words.size()];
for(int i=0; i<words.size(); i++){
indices[i] = i;
}
Random rand = new Random(System.currentTimeMillis());
for(int i=0; i<size; i++){
int take = rand.nextInt(indices.length-i);
result[i] = words.get(indices[take]);
indices[take] = indices[indices.length-i-1];
}
return result;
}
public static String guessBest(ArrayList<String> candidates, boolean firstGuess, boolean lastGuess){
if(candidates.size() == 1){
return candidates.get(0);
}
String minGuess = candidates.get(0);
int wordlen = minGuess.length();
if(firstGuess && guessBestList[wordlen].length()==wordlen){
return guessBestList[wordlen];
}
int minMatches = Integer.MAX_VALUE;
String[] words;
if(lastGuess){
words = candidates.toArray(new String[0]);
} else if (candidates.size()>10){
words = bestWords(wordlist.get(wordlen), candidates, 25);
} else {
words = wordlist.get(wordlen).toArray(new String[0]);
}
for(String guess: words){
double sumMatches = 0;
for(String word: candidates){
int matches = countMatchingCandidates(candidates, guess, getResponse(word, guess));
if(matches == 0) matches = candidates.size();
sumMatches += (matches-1)*(matches-1);
}
if(sumMatches < minMatches){
minGuess = guess;
minMatches = sumMatches;
}
}
return minGuess;
}
public static String[] bestWords(ArrayList<String> words, ArrayList<String> candidates, int size){
int[] charCount = new int[123];
for(String candidate: candidates){
for(int i=0; i<candidate.length(); i++){
charCount[(int)candidate.charAt(i)]++;
}
}
String[] tmp = (String[])words.toArray(new String[0]);
Arrays.sort(tmp, new WordComparator(charCount));
String[] result = new String[size+Math.min(size, candidates.size())];
String[] sampled = getSample(candidates, Math.min(size, candidates.size()));
for(int i=0; i<size; i++){
result[i] = tmp[tmp.length-i-1];
if(i < sampled.length){
result[size+i] = sampled[i];
}
}
return result;
}
static class WordComparator implements Comparator<String>{
int[] charCount = null;
public WordComparator(int[] charCount){
this.charCount = charCount;
}
public Integer count(String word){
int result = 0;
int[] multiplier = new int[charCount.length];
Arrays.fill(multiplier, 1);
for(char chr: word.toCharArray()){
result += multiplier[(int)chr]*this.charCount[(int)chr];
multiplier[(int)chr] = 0;
}
return Integer.valueOf(result);
}
public int compare(String s1, String s2){
return count(s1).compareTo(count(s2));
}
}
}