Java、249700ポイント(私のテストでは、中国語の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 200400400500 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に似ています。私の主なアイデアは、次の推測に最も多くの情報を提供する推測(同じ長さの単語で、必ずしも残りの可能性の1つではない)を見つけることです。
現在、私はまだ数式で遊んでいますが、上記のスコアボードでは、次の最小値が得られる単語を選択します。
-num_confusion *エントロピー
最新バージョンでは、異なるスコアリングを使用して、次に最適な推測を見つけます。これは、現在の推測の後の「単一の可能性」の数を最大化します。これは、可能性のあるすべての候補に対して剪定された単語リストのすべての単語を試して(時間を節約する)、どの推測が「単一の可能性」を生み出す可能性が高いかを確認します次の推測。
したがって、たとえば、この実行:
新ラウンドの開始、言葉は恩恵
わかった:seora
送信済み:?XOXX
わかった:topsl
送信済み:XOX?X
得た:僧ks
送信済み:XO?XO
手に入れました:
送信済み:OXXXX
得た:ブーン
送信済み:OOOOO
ラウンドはスコア100で勝ちました
最初の3つの推測から、どこかに "n"が付いた "* oo * s"がすでに得られているため、さらに1文字を理解する必要があります。このアルゴリズムの利点は、その形式に似た単語を推測する代わりに、以前の推測とはまったく関係のない単語を推測し、より多くの文字を与えようとして、行方不明の文字を明らかにすることです。この場合、欠落している「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));
}
}
}