Ніби цей виклик міг би бути більше піфонескою за духом ... Ніяких попередніх знань про ланцюги Маркова або методи шифрування не потрібно.
Ви шпигун, якому потрібно отримати важливу інформацію від британської служби безпеки M1S. Агенти M1S прекрасно знають, що їхні сигнали Wi-Fi можуть бути перехоплені, їх захищені вразливості для Android / iOS тощо. Тому всі вони використовують Nokia 3310 для передачі текстової інформації, яка набирається за допомогою автоматичного заповнення T9 .
Ви раніше зламали телефони для доставки в розвідувальну агенцію і встановили кейлоггери під їхніми славними пластиковими клавіатурами, тож тепер ви отримуєте послідовності номерів, що відповідають літерам, які вони набрали, так що « орел покинув гніздо оповіщення агентів »
84303245304270533808430637802537808430243687
Але зачекайте! Деякі послідовності T9 неоднозначні ("6263" може бути "ім'я", "грива" або "гобой"; чим більше незрозумілим, тим підозрілішим воно стає!), І що робити? Ви знаєте, що єдиним вступним іспитом, який M1S використовує, є підведення підсумків шедевра Марселя Пруста «Пам'ять речей минулого» за 15 секунд, тож ви хочете вибрати слово, яке буде наступним після попереднього, відповідно до його частотного розподілу в цілому шеф-кухаря. œuvre Пруста!
Чи можете ви зламати код і отримати те, що може бути оригінальним повідомленням?
Принцип T9
Механізм автоматичного заповнення T9 можна описати наступним чином. Він відображає алфавітні символи на числа, як показано на малюнку вище.
abc -> 2
def -> 3
ghi -> 4
jkl -> 5
mno -> 6
pqrs -> 7
tuv -> 8
wxyz -> 9
<space> -> 0
<other> -> <is deleted>
Дешиптор T9 отримує послідовність цифр і намагається відгадати слово, яке можна було б набрати за допомогою цих клавіш. Він може використовувати стандартну таблицю частот, але ми йдемо на крок далі і прогнозуємо наступне слово за допомогою ланцюга Маркова!
Зразок навчання
Корпус є це сильно розділу версію «Спогади про минуле» Пруст ( s/-/ /g
, s/['’]s //g
і s/[^a-zA-Z ]//g
- забиратися в омані присвійним 's
!) Спочатку опубліковано на Університеті Аделаїди сайту (текст цієї роботи знаходиться в суспільному надбанні в Австралії).
Весь текст повинен бути проаналізований як один рядок, як одне довге речення, як один довгий вектор слів (що зручніше для вашої мови), позбавлений розривів рядків і розділений на слова на пробіли . (Я не надаю одноразовий файл, оскільки такий інструмент може нахмуритися інструментами github.)
Як я читаю весь текст у вигляді одного рядка / речення? Приклад в R :
p_raw <- read.table("proust.txt", sep="\t") # Because there are no tabs
p_vec <- as.character(p_raw$V1) # Conversion to character vector
p_str <- paste(p_vec, collapse=" ") # One long string with spaces
p_spl <- strsplit(p_str, split=" ")[[1]] # Vector of 1360883 words
proust <- p_spl[p_spl!=""] # Remove empty entries — 1360797
Завдання
З огляду на послідовність цифр у вигляді числа, поверніть можливий текстовий рядок, який можна було б набрати за допомогою відповідних клавіш T9, використовуючи ланцюжок ймовірностей, щоб передбачити наступне слово X на основі цього навчального тексту, який розглядається як одне довге речення.
Якщо X - це перше слово T9 тексту, і є декілька здогадок, виберіть одне навмання, інакше виберіть єдине можливе.
Для всіх наступних T9-слів X (i), яким передує вже розшифроване слово w (i-1) :
- Якщо T9-слово X можна перетворити в звичайне слово x одним унікальним способом, зробіть це.
- Якщо для X , скажімо x1, x2, ... , доступно кілька варіантів перетворення , знайдіть попереднє здогадане слово w .
- Якщо за початковим твором Пруста w ніколи не дотримується нічого, що позначає X , виберіть будь-який із можливих x1, x2, ... навмання.
- Якщо w X завжди відповідає w x1 в оригіналі і немає одночасних xi , які можна було б відобразити в X , виберіть x1 .
- Якщо w X можна перетворити на w x1 , w x2 , ..., які можуть бути знайдені в корпусі, то порахуйте всі можливі xi , які слідують w, і переведіть на X у корпусі, і виберіть xi з вірогідністю xi / (x1 + x2 + ...) .
Приклад 2a. Якщо повідомлення є 76630489
, де це 489
може бути guy
або ivy
(вони трапляються в корпусі хоча б один раз), 7663
можна розшифрувати як some
(дуже ймовірне перше слово). Якщо some
ніколи не супроводжується чимось, що відображається 489
в корпусі, виберіть guy
або ivy
навмання з імовірністю 0,5.
Приклад 2b. Якщо повідомлення є 766302277437
, де це 2277437
може бути barrier
або carrier
, 7663
можна розшифрувати як some
. Якщо Пруст завжди використовувався some carrier
і ніколи some barrier
, тоді вибирайте some carrier
.
Приклад 2c. Припустимо, ви хочете розшифрувати послідовність 536307663
. 5363
було прогнозовано як lend
. 7663
може бути будь-який з них: pond
, roof
і some
. Ви підраховуєте випадки слова, наступного lend
у зразку корпусу. Припустимо, у вас виходить щось подібне (просто для ілюстрації):
T9 Word following lend Occurrences
7663 some 7
7663 pond 2
7663 roof 1
Так що якщо 7663
передує lend
, існує 7/(7+2+1)=70%
ймовірність того, що 7663
означає some
, 20% pond
і 10% roof
. Ваш алгоритм повинен виробляти lend some
у 70% випадків, lend pond
у 20% випадків тощо.
Ви можете з упевненістю припустити, що агенти використовують лише букви та пробіли (без розділових знаків, ніяких присвійних 's
чи без цифр).
Ви також можете припустити, що агенти M1S ніколи не вживають жодних слів за межами «Пам'яті речей минулого» (що є колосальним словником з 29 237 слів!).
Коефіцієнт корисної дії T9 був реалізований у цьому виклику , тож ви можете подивитися на це.
Якщо вам потрібна будь-яка допомога, імовірнісні ланцюги були славно приручені в цьому , тому та наступних викликах, але вам навіть не потрібно знати принцип таких ланцюгів: все зазначено в завданні.
Тестові справи
--Inputs--
20784250276960369
20784250276960369
84303245304270533808430637802537808430243687
94280343084306289072908608430262780482737
94280343084306289072908608430262780482737
--Possible outputs--
c quick brown fox
a stick crown fox
the eagle gas left the nest blest vie agents
what did the navy pay to the coast guards
what did the navy raz un the coast guards
Правила:
- Застосовуються стандартні лазівки .
- Ви не знаєте оригінального повідомлення, все, що ви отримуєте, - це послідовність цифр і файл proust.txt, який вам просто потрібно завантажити в пам'ять / робочу область / що завгодно. Не потрібно мати щось самостійне; припустимо
proust.txt
, завжди доступний. - Ваш алгоритм повинен мати можливість виробляти різні результати з відповідними ймовірностями, якщо відповідно до корпусу є більше ніж один варіант дешифрування (див. Приклад 2в).
Вам потрібно залишатися максимально стриманим, щоб виграв найкоротший код!
PS Очевидною перевагою цього ймовірнісного алгоритму є той факт, що ймовірність, що ви отримаєте справжню оригінальну рядок для неоднозначної розшифрованої рядки, має тенденцію до однієї - просто зачекайте ...
PPS Див. Також Прогноз шляхом часткового узгодження .