View difference between Paste ID: hLf2cASz and tZQmiZUa
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
}