1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
|
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace infoboard
{
class MainClass
{
static string[] dict;
static int[][] puzzle;
static int bestFit;
static void Main(string[] args) {
string path = "/home/eulerschezahl/Downloads/";
//einlesen
dict = File.ReadLines (path + "worte.txt").Select (x => x.Substring (0, x.IndexOf (" "))).ToArray ();
puzzle = File.ReadLines (path + "puzzle.txt").Select (x => x.Split(' ').Select(y => int.Parse(y)).ToArray()).ToArray ();
bestFit = puzzle.Length * 3 / 4;
//buchstabenhäufigkeit
List<KeyValuePair<int,int>> letterCount = new List<KeyValuePair<int,int>> ();
for (int i = 0; i <= 26; i++)
letterCount.Add (new KeyValuePair<int, int>(i, 0));
foreach (int[] word in puzzle)
foreach (int i in word)
letterCount [i] = new KeyValuePair<int, int> (i, letterCount [i].Value + 1);
letterCount = letterCount.OrderBy (x => -x.Value).Where(x => x.Value > 0).ToList();
letterCount = letterCount.Where (x => (new List<int> { 1, 6, 11, 22 }).IndexOf (x.Key) < 0).ToList ();
int[] nextLetter = letterCount.Select (x => x.Key).ToArray();
//Zuweisung vordefinierter Buchstaben P, R, I, M
bool[] used = new bool[26];
Dictionary<int,char> letters = new Dictionary<int, char> ();
letters.Add (22, 'P'); used ['P' - 'A'] = true;
letters.Add (1, 'R');used ['R' - 'A'] = true;
letters.Add (6, 'I');used ['I' - 'A'] = true;
letters.Add (11, 'M');used ['M' - 'A'] = true;
FindLetters (letters, used, nextLetter, 0);
}
static void FindLetters(Dictionary<int, char> letters, bool[] used, int[] nextLetter, int index) {
int fit = CountFit (letters);
if (fit < bestFit)
return;
if (index == nextLetter.Length) { //Alle Buchstaben zugeteilt, Bilanz ziehen und gegebenenfalls Ergebnis ausgeben
bestFit = fit;
foreach (int[] word in puzzle) {
StringBuilder sb = new StringBuilder ();
foreach (int i in word) {
sb.Append (letters.ContainsKey (i) ? letters [i] : '?');
}
Console.Write (sb.ToString().PadRight(10));
}
Console.Write ("\n" + fit + " bekannte Worte\n" + String.Join (", ", letters.Select (x => x.Key + "=" + x.Value)) + "\n\n");
return;
}
List<KeyValuePair<char, int>> fitCount = new List<KeyValuePair<char, int>> ();
for (char c = 'A'; c <= 'Z'; c++) {
if (used [c - 'A'])
continue;
Dictionary<int, char> newDict = new Dictionary<int, char> (letters);
newDict.Add (nextLetter [index], c);
fitCount.Add (new KeyValuePair<char, int>(c, CountFit (newDict)));
}
fitCount = fitCount.OrderBy (x => -x.Value).ToList();
foreach(KeyValuePair<char, int> pair in fitCount) {
if (pair.Value < bestFit)
return;
Dictionary<int, char> newDict = new Dictionary<int, char> (letters);
newDict.Add (nextLetter [index], pair.Key);
bool[] newUsed = (bool[])used.Clone ();
newUsed [pair.Key - 'A'] = true;
FindLetters (newDict, newUsed, nextLetter, index + 1);
}
}
private static int CountFit(Dictionary<int, char> letters) {
int result = 0;
foreach (int[] word in puzzle) {
StringBuilder regex = new StringBuilder ();
foreach (int i in word) {
regex.Append (letters.ContainsKey (i) ? letters [i] : '.');
}
bool match = false;
string pattern = regex.ToString ();
foreach (string s in dict) {
if (s.Length == word.Length && Regex.IsMatch (s, pattern)) {
match = true; break;
}
}
if (match)
result++;
}
return result;
}
}
} |