이 문제는 더 이상이 될 수있는 것처럼 Pythonesque을 정신 ... 마르코프 체인 또는 암호화 기술에 대한 사전 지식은 필요하지 않습니다.
영국 보안 서비스 M1S로부터 중요한 정보를 얻어야하는 스파이입니다. M1S의 에이전트는 Wi-Fi 신호를 가로 챌 수 있고 Android / iOS 보안 취약점을 악용 할 수 있다는 점을 잘 알고 있으므로 모두 Nokia 3310을 사용하여 T9 자동 완성 기능을 사용하여 입력 한 텍스트 정보를 전송하고 있습니다.
당신은 이제 당신이 그렇게 "가 입력 한 문자에 해당하는 숫자의 순서를 받기 이전에 정보 기관에 전달 될 수있는 전화를 해킹했고 자신의 영광스러운 플라스틱 키보드 아래에 키로거를 설치 한 독수리는 에이전트가 둥지 경고 떠났다 가된다"를
84303245304270533808430637802537808430243687
하지만 기다려! 일부 T9 시퀀스는 모호합니다 ( "6263"은 "이름", "갈기"또는 "oboe"일 수 있습니다. 더 모호할수록 더 의심됩니다!). 어떻게해야합니까? M1S가 사용하는 유일한 입시 시험은 15 초 만에 Marcel Proust의 걸작“과거의 추억”을 요약하는 것입니다. – 자유로운 자외선!
코드를 해독하고 원래 메시지가 될 수있는 것을 얻을 수 있습니까?
T9의 원리
T9 자동 완성 메커니즘은 다음과 같이 설명 할 수 있습니다. 위의 그림과 같이 알파벳 문자를 숫자로 매핑합니다.
abc -> 2
def -> 3
ghi -> 4
jkl -> 5
mno -> 6
pqrs -> 7
tuv -> 8
wxyz -> 9
<space> -> 0
<other> -> <is deleted>
T9 암호 해독기는 일련의 숫자를 수신하고 해당 키 누름으로 입력 할 수있는 단어를 추측하려고합니다. 표준 빈도 표를 사용할 수도 있지만 Markov 체인을 사용하여 한 단계 더 나아가 다음 단어를 예측하고 있습니다!
학습 샘플
코퍼스는 프루스트의 "것 과거의 기억"이 많이 제거 버전 ( 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 다음에 Proust의 원래 작업에서 X 에 매핑되는 항목이없는 경우 가능한 x1, x2 등 을 임의로 선택하십시오.
- 경우 X 승 항상에 해당하는 1 개 w 원본과 더 동시 없습니다 XI이 의 그에 매핑 할 수 있습니다 X , 선택 1 개를 .
- 경우 X 승 으로 변환 할 수 있습니다 X1 승 , 2 배 승 ... 그 코퍼스에서 찾을 수 있습니다, 모든 가능한 계산 XI 것은 '그 후속이야 승 및 매핑 X 코퍼스와 선택 XI을 확률로 XI / (1 개 + x2 + ...) .
실시 예 2a. 이 메시지가 76630489
어디에 489
있을 수 guy
있거나 ivy
(적어도 한 번 코퍼스에서 발생하는 경우) (매우 가능성이 높은 첫 단어) 7663
로 해독 될 수 있습니다 some
. 만약 some
에 매핑 아무것도 뒤에되지 않습니다 489
코퍼스에서 다음 선택 guy
또는 ivy
확률 0.5 무작위로.
실시 예 2b. 메시지 인 경우 766302277437
, 어디 2277437
수 barrier
또는 carrier
, 7663
로 해독 할 수 있습니다 some
. Proust가 항상 사용 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 % 경우 등에서 생성해야합니다 .
상담원은 az 문자와 공백 만 사용한다고 가정 할 수 있습니다 (마침표, 소유 's
및 숫자 없음).
또한 M1S 요원이 “과거의 기억 (Remembrance of Things Past)” (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
항상 액세스 할 수 있다고 가정합니다 . - 모음에 따라 둘 이상의 암호 해독 옵션을 사용할 수있는 경우 알고리즘에서 각 확률로 다른 출력을 생성 할 수 있어야합니다 (예 2c 참조).
가능한 한 신중하게 유지해야하므로 가장 짧은 코드가 승리합니다!
PS 이 확률 적 알고리즘의 명백한 이점은 모호한 해독 된 문자열에 대해 실제 원본 문자열을 얻을 확률이 1 인 경향이 있다는 사실입니다.
PPS 부분 일치 예측을 참조하십시오 .