Als ob diese Herausforderung im Geiste pythonesker sein könnte ... Es sind keine Vorkenntnisse in Markov-Ketten oder Verschlüsselungstechniken erforderlich.
Sie sind ein Spion, der wichtige Informationen vom britischen Sicherheitsdienst M1S erhalten muss. Die Agenten von M1S sind sich bewusst, dass ihre Wi-Fi-Signale abgefangen, ihre Sicherheitslücken in Android / iOS ausgenutzt usw. werden können. Daher verwenden alle Nokia 3310s, um Textinformationen zu übertragen, die mit der automatischen Vervollständigung des T9 eingegeben wurden .
Sie hatten zuvor die Telefone gehackt, die an den Geheimdienst geliefert werden sollten, und Keylogger unter ihren prächtigen Plastiktastaturen installiert. Jetzt erhalten Sie Zahlenfolgen, die den eingegebenen Buchstaben entsprechen, sodass „ der Adler das Nest verlassen hat, um die Agenten zu alarmieren “
84303245304270533808430637802537808430243687
Aber warte! Einige T9-Sequenzen sind mehrdeutig ("6263" könnte "Name", "Mähne" oder "Oboe" sein; je dunkler, desto verdächtiger wird es!). Was machen Sie also? Sie wissen, dass die einzige Aufnahmeprüfung, die M1S verwendet, darin besteht, Marcel Prousts Meisterwerk „Remembrance of Things Past“ in 15 Sekunden zusammenzufassen. Sie möchten also das Wort, das nach dem vorherigen kommt, anhand seiner Häufigkeitsverteilung im gesamten Chef-d 'auswählen. œuvre of Proust!
Können Sie den Code knacken und die ursprüngliche Nachricht erhalten?
Das Prinzip von T9
Der T9-Mechanismus zur automatischen Vervollständigung kann wie folgt beschrieben werden. Es ordnet alphabetische Zeichen Zahlen zu, wie im obigen Bild gezeigt.
abc -> 2
def -> 3
ghi -> 4
jkl -> 5
mno -> 6
pqrs -> 7
tuv -> 8
wxyz -> 9
<space> -> 0
<other> -> <is deleted>
Der T9-Entschlüsseler empfängt eine Folge von Ziffern und versucht, das Wort zu erraten, das mit diesen Tastendrücken eingegeben werden könnte. Es könnte eine Standardfrequenztabelle verwenden, aber wir gehen noch einen Schritt weiter und sagen das nächste Wort mithilfe einer Markov-Kette voraus!
Lernbeispiel
Der Korpus ist diese stark gestrippt Version von Prousts „ nach dem verlorenen Zeit“ ( s/-/ /g
, s/['’]s //g
und s/[^a-zA-Z ]//g
- begone verwirrend besitzergreifend 's
!) , Die ursprünglich auf der veröffentlichte University of Adelaide Webseite (der Text dieser Arbeit ist in der Public Domain in Australien).
Der gesamte Text muss als eine Zeichenfolge, als ein langer Satz, als ein langer Vektor von Wörtern (je nachdem, was für Ihre Sprache am bequemsten ist) analysiert , von Zeilenumbrüchen befreit und an Leerzeichen in Wörter aufgeteilt werden . (Ich liefere keine Datei mit einem Absatz, da diese möglicherweise von Github-Tools verpönt wird.)
Wie lese ich den gesamten Text als eine Zeichenfolge / einen Satz? Ein Beispiel in 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
Aufgabe
Geben Sie bei einer gegebenen Folge von Ziffern als Zahl eine mögliche Textzeichenfolge zurück, die mit den entsprechenden T9-Tasten unter Verwendung einer Wahrscheinlichkeitskette eingegeben werden kann, um das nächste Wort X basierend auf diesem als ein langer Satz behandelten Trainingstext vorherzusagen .
Wenn X das erste T9-Wort des Textes ist und es mehrere Vermutungen gibt, wählen Sie eine zufällig aus, andernfalls die einzig mögliche.
Für alle nachfolgenden T9-Wörter X (i), denen ein bereits entschlüsseltes Wort w (i-1) vorangestellt ist :
- Wenn ein T9-Wort X auf einzigartige Weise in ein normales Wort x umgewandelt werden kann, tun Sie dies.
- Wenn für X mehrere Konvertierungsoptionen verfügbar sind, z . B. x1, x2, ... , suchen Sie das vorhergehende erratene Wort w nach .
- Wenn auf w niemals etwas folgt, das in der Originalarbeit von Proust X zugeordnet ist , wählen Sie zufällig eines der möglichen x1, x2, ... aus .
- Wenn w X im Original immer w x1 entspricht und es keine gleichzeitigen xi gibt , die auf X abgebildet werden könnten , wählen Sie x1 .
- Wenn w X in w x1 , w x2 , ... konvertiert werden kann, die sich im Korpus befinden, zählen Sie alle möglichen xi , die w folgen, und ordnen Sie sie X im Korpus zu, und wählen Sie xi mit der Wahrscheinlichkeit xi / (x1) aus + x2 + ...) .
Beispiel 2a. Wenn die Nachricht ist 76630489
, wo 489
könnte guy
oder ivy
(sie kommen mindestens einmal im Korpus vor), 7663
kann sie als some
(ein sehr wahrscheinliches erstes Wort) entschlüsselt werden . Wenn some
niemals etwas folgt, das 489
im Korpus abgebildet ist, wählen Sie guy
oder ivy
zufällig mit einer Wahrscheinlichkeit von 0,5.
Beispiel 2b. Wenn die Nachricht ist 766302277437
, wo 2277437
könnte barrier
oder kann carrier
, 7663
kann als entschlüsselt werden some
. Wenn Proust immer verwendet hat some carrier
und nie some barrier
, dann wählen Sie some carrier
.
Beispiel 2c. Angenommen, Sie möchten die Sequenz entschlüsseln 536307663
. 5363
wurde vorhergesagt als lend
. 7663
eine dieser sein könnte: pond
, roof
und some
. Sie zählen die Vorkommen des folgenden Wortes lend
im Beispielkorpus. Angenommen, Sie erhalten so etwas (nur zur Veranschaulichung):
T9 Word following lend Occurrences
7663 some 7
7663 pond 2
7663 roof 1
Wenn 7663
also vorangestellt wird lend
, gibt es eine 7/(7+2+1)=70%
Wahrscheinlichkeit, 7663
die für some
20% pond
und 10% steht roof
. Ihr Algorithmus sollte lend some
in 70% der Fälle, lend pond
in 20% der Fälle usw. produzieren.
Sie können davon ausgehen, dass die Agenten nur az-Buchstaben und Leerzeichen verwenden (keine Satzzeichen, keine Possessiv- 's
und keine Zahlen).
Sie können auch davon ausgehen, dass die Agenten von M1S niemals Wörter außerhalb des Bereichs „Erinnerung an vergangene Dinge“ verwenden (was ein unglaubliches Vokabular von 29.237 Wörtern ist!).
Die T9-Funktionalität wurde in dieser Herausforderung implementiert , sodass Sie sie sich ansehen können.
Wenn Sie Hilfe benötigen, wurden probabilistische Ketten in dieser , jener und den folgenden Herausforderungen herrlich gezähmt , aber Sie müssen nicht einmal das Prinzip solcher Ketten kennen: Alles ist in der Aufgabe angegeben.
Testfälle
--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
Regeln:
- Es gelten Standardlücken .
- Sie kennen die ursprüngliche Nachricht nicht. Sie erhalten lediglich eine Folge von Ziffern und die Datei proust.txt , die Sie nur in den Speicher / Arbeitsbereich / was auch immer laden müssen. Es besteht keine Notwendigkeit, etwas in sich geschlossenes zu haben; Angenommen,
proust.txt
ist immer zugänglich. - Ihr Algorithmus muss in der Lage sein, unterschiedliche Ausgaben mit entsprechenden Wahrscheinlichkeiten zu erzeugen, wenn je nach Korpus mehr als eine Entschlüsselungsoption wahrscheinlich ist (siehe Beispiel 2c).
Sie müssen so diskret wie möglich bleiben, damit der kürzeste Code gewinnt!
PS Der offensichtliche Vorteil dieses probabilistischen Algorithmus ist die Tatsache, dass die Wahrscheinlichkeit, dass Sie eine echte Originalzeichenfolge für eine mehrdeutige entschlüsselte Zeichenfolge erhalten, zu eins tendiert - warten Sie einfach ...
PPS Siehe auch Vorhersage durch partielle Übereinstimmung .