SHOW:
|
|
- or go back to the newest paste.
1 | using System; | |
2 | using System.Collections.Generic; | |
3 | using System.IO; | |
4 | using System.Linq; | |
5 | using System.Text; | |
6 | using System.Threading.Tasks; | |
7 | ||
8 | namespace GuessTheNameTwo | |
9 | { | |
10 | class GuessTheNameTwo | |
11 | { | |
12 | const int PreceedingWordsCount = 5; | |
13 | const int FollowingWordsCount = 1; | |
14 | ||
15 | private static readonly char[] separators = new char[] { ',', '.', '!', '?', ' ', '\r', ')', '(', '#', '&', '*', '[', ']', '{', '}', '_', '"', '\'', '/', '\\' }; | |
16 | ||
17 | static string inputText; | |
18 | ||
19 | static HashSet<string> personPrimaryClues; | |
20 | static HashSet<string> placePrimaryClues; | |
21 | ||
22 | static HashSet<string> personSecondaryClues; | |
23 | static HashSet<string> placeSecondaryClues; | |
24 | ||
25 | static void Main() | |
26 | { | |
27 | InitializeKeywords(); | |
28 | ||
29 | // Console.SetIn(new StreamReader("zero.txt")); | |
30 | ||
31 | inputText = Console.ReadLine(); | |
32 | ||
33 | int numberOfNames = int.Parse(Console.ReadLine()); | |
34 | ||
35 | for (int i = 0; i < numberOfNames; i++) | |
36 | { | |
37 | string targetName = Console.ReadLine(); | |
38 | string result = InitialGuess(targetName); | |
39 | ||
40 | if (result == string.Empty) | |
41 | { | |
42 | result = DeeperGuess(targetName); | |
43 | } | |
44 | ||
45 | Console.WriteLine(result); | |
46 | } | |
47 | } | |
48 | ||
49 | private static void InitializeKeywords() | |
50 | { | |
51 | personPrimaryClues = new HashSet<string>() | |
52 | { | |
53 | "г-н", "г-жа", "г-ца", "д-р", "проф.", "доц.", "доктор", "свети", "св.", "генерал", "арх.", "ген.", | |
54 | }; | |
55 | ||
56 | placePrimaryClues = new HashSet<string>() | |
57 | { | |
58 | "море", "остров", "планина", "океан", "град", "държава", "кралство", "царство", "република", "село", "север", "изто", "юж", "запад", "юг", "горн", "долн", "земя", "район", "храм", "църква", "паметник", "монумент", "статуя", "мавзолей", | |
59 | }; | |
60 | ||
61 | personSecondaryClues = new HashSet<string>() | |
62 | { | |
63 | "с", "със", "без", "брат", "сестра", "баща", "майка", "баба", "дядо", "син", "ст", "св", "адв", "д-р", "арх", "на", "спрямо", "когото", "която", "което", "който", "кой", "у", "комуто", "чието", "чийто", "чиято", "чиито", "президент", "политик", "министър", "председател", "директор", "началник", "мениджър", "ръководител", "лидер", "учен", "изследовател", "актьор", "артист", "спортист", "физик", "химик", "кмет", "княз", "цар", "крал", "кралица", "принц", "кан", "хан", "владетел", "император", "г-н", "г-жа", "г-ца", "инж", "проф", "доц", "ас", "герой", "епископ", "папа", "внук", "племеник", "генерал", "бил", "беше", "бъде", "им", "съпруг", "съпруга", "личност", "особа", "лице", "същество", "човече", "индивид", "особа", "персона", "герой", | |
64 | }; | |
65 | ||
66 | placeSecondaryClues = new HashSet<string>() | |
67 | { | |
68 | "в", "във", "към", "от", "над", "под", "при", "между", "насред", "срещу", "извън", "отвъд", "около", "през", "град", "градче", "страна", "и", "из", "област", "спрямо", "държава", "село", "планина", "река", "местност", "околия", "окръг", "север", "изток", "юг", "запад", "република", "пещера", "водопад", "долина", "низина", "връх", "щат", "провинция", "площад", "улица", "булевард", "където", "пред", "зад", "ресторант", "хотел", "заведение", "клуб", "зала", "стадион", "квартал", "район", "регион", "махала", "община", "пл", "вр", "континент", "море", "океан", "язовир", "катедрала", "паметник", "край", "граница", "място", "местност", "зона", "територия", "землище", "пункт", "пространство", "разположение", "месторазположение", "положение", "позиция", "местонахождение", "местопребиваване", "почва", "терен", "земя", "район", "храм", "църква", "монумент", "статуя", "мавзолей", | |
69 | }; | |
70 | } | |
71 | ||
72 | private static string InitialGuess(string targetName) | |
73 | { | |
74 | int personPrimaryClues = GetPersonPrimaryClues(targetName); | |
75 | int placePrimaryClues = GetPlacePrimaryClues(targetName); | |
76 | ||
77 | if (personPrimaryClues > placePrimaryClues) | |
78 | { | |
79 | return "Person"; | |
80 | } | |
81 | else if (personPrimaryClues < placePrimaryClues) | |
82 | { | |
83 | return "Place"; | |
84 | } | |
85 | else | |
86 | { | |
87 | return string.Empty; | |
88 | } | |
89 | } | |
90 | ||
91 | private static string DeeperGuess(string targetName) | |
92 | { | |
93 | int startIndex = inputText.IndexOf(targetName); | |
94 | ||
95 | int personCluesAroundName = 0; | |
96 | int placeCluesAroundName = 0; | |
97 | ||
98 | while (startIndex != -1) | |
99 | { | |
100 | List<string> preceedingWords = GetNeighboringWords(startIndex - 1, false); | |
101 | List<string> followingWords = GetNeighboringWords(startIndex + targetName.Length, true); | |
102 | ||
103 | personCluesAroundName += FindCluesInNeighboringWords(preceedingWords, personSecondaryClues) + FindCluesInNeighboringWords(followingWords, personSecondaryClues); | |
104 | placeCluesAroundName += FindCluesInNeighboringWords(preceedingWords, placeSecondaryClues) + FindCluesInNeighboringWords(followingWords, placeSecondaryClues); | |
105 | ||
106 | startIndex = inputText.IndexOf(targetName, startIndex + 1); | |
107 | } | |
108 | ||
109 | if (personCluesAroundName > 2 || placeCluesAroundName > 2) | |
110 | { | |
111 | int certaintyIndex = Math.Abs(placeCluesAroundName - personCluesAroundName); | |
112 | ||
113 | if (certaintyIndex < 2) | |
114 | { | |
115 | return "Unknown"; | |
116 | } | |
117 | } | |
118 | ||
119 | if (personCluesAroundName > placeCluesAroundName) | |
120 | { | |
121 | return "Person"; | |
122 | } | |
123 | else if (personCluesAroundName < placeCluesAroundName) | |
124 | { | |
125 | return "Place"; | |
126 | } | |
127 | else | |
128 | { | |
129 | return "Unknown"; | |
130 | } | |
131 | } | |
132 | ||
133 | private static int GetPlacePrimaryClues(string targetName) | |
134 | { | |
135 | int clues = 0; | |
136 | ||
137 | string[] nameSplit = targetName.Split(separators, StringSplitOptions.RemoveEmptyEntries); | |
138 | ||
139 | foreach (string namePart in nameSplit) | |
140 | { | |
141 | if (namePart.EndsWith("ия")) | |
142 | { | |
143 | clues++; | |
144 | } | |
145 | } | |
146 | ||
147 | string nameLower = targetName.ToLower(); | |
148 | ||
149 | foreach (string clue in placePrimaryClues) | |
150 | { | |
151 | if (nameLower.Contains(clue)) | |
152 | { | |
153 | clues++; | |
154 | } | |
155 | } | |
156 | ||
157 | return clues; | |
158 | } | |
159 | ||
160 | private static int GetPersonPrimaryClues(string targetName) | |
161 | { | |
162 | int clues = 0; | |
163 | ||
164 | string[] nameSplit = targetName.Split(separators, StringSplitOptions.RemoveEmptyEntries); | |
165 | ||
166 | foreach (string namePart in nameSplit) | |
167 | { | |
168 | if (namePart.EndsWith("ев") || namePart.EndsWith("ов") || namePart.EndsWith("ий") || namePart.EndsWith("ски")) | |
169 | { | |
170 | clues++; | |
171 | } | |
172 | } | |
173 | ||
174 | string nameLower = targetName.ToLower(); | |
175 | ||
176 | foreach (string clue in personPrimaryClues) | |
177 | { | |
178 | if (nameLower.Contains(clue)) | |
179 | { | |
180 | clues++; | |
181 | } | |
182 | } | |
183 | ||
184 | return clues; | |
185 | } | |
186 | ||
187 | private static List<string> GetNeighboringWords(int startIndex, bool isLookingForward) | |
188 | { | |
189 | List<string> extractedWords = new List<string>(); | |
190 | StringBuilder wordBuilder = new StringBuilder(); | |
191 | ||
192 | int targetWordsCount = PreceedingWordsCount; | |
193 | ||
194 | if (isLookingForward) | |
195 | { | |
196 | targetWordsCount = FollowingWordsCount; | |
197 | } | |
198 | ||
199 | while ((startIndex > 0) && (startIndex < inputText.Length) && (extractedWords.Count < targetWordsCount)) | |
200 | { | |
201 | char currentChar = inputText[startIndex]; | |
202 | ||
203 | if (char.IsLetter(currentChar)) | |
204 | { | |
205 | wordBuilder.Append(currentChar); | |
206 | } | |
207 | else | |
208 | { | |
209 | AddWord(wordBuilder, extractedWords, isLookingForward); | |
210 | ||
211 | if (currentChar == '.' || currentChar == '!' || currentChar == '?') | |
212 | { | |
213 | break; | |
214 | } | |
215 | } | |
216 | ||
217 | if (isLookingForward) | |
218 | { | |
219 | startIndex++; | |
220 | } | |
221 | else | |
222 | { | |
223 | startIndex--; | |
224 | } | |
225 | } | |
226 | ||
227 | return extractedWords; | |
228 | } | |
229 | ||
230 | private static void AddWord(StringBuilder wordBuilder, List<string> extractedWords, bool isLookingForward) | |
231 | { | |
232 | string extractedWord = wordBuilder.ToString().Trim(separators); | |
233 | ||
234 | if (extractedWord != string.Empty) | |
235 | { | |
236 | if (!isLookingForward) | |
237 | { | |
238 | extractedWord = ReverseWord(wordBuilder).Trim(separators); | |
239 | } | |
240 | ||
241 | extractedWords.Add(extractedWord); | |
242 | wordBuilder.Clear(); | |
243 | } | |
244 | } | |
245 | ||
246 | private static string ReverseWord(StringBuilder wordBuilder) | |
247 | { | |
248 | StringBuilder result = new StringBuilder(); | |
249 | ||
250 | for (int i = 0; i < wordBuilder.Length; i++) | |
251 | { | |
252 | result.Append(wordBuilder[wordBuilder.Length - i - 1]); | |
253 | } | |
254 | ||
255 | return result.ToString(); | |
256 | } | |
257 | ||
258 | private static int FindCluesInNeighboringWords(List<string> neighboringWords, HashSet<string> relatedKeywords) | |
259 | { | |
260 | int clues = 0; | |
261 | ||
262 | foreach (string word in neighboringWords) | |
263 | { | |
264 | if (relatedKeywords.Contains(word.ToLower())) | |
265 | { | |
266 | clues++; | |
267 | } | |
268 | } | |
269 | ||
270 | return clues; | |
271 | } | |
272 | } | |
273 | } |