Cryptic Kicker //


12

Cryptic Kicker

Un metodo comune ma insicuro di crittografia del testo è quello di consentire le lettere dell'alfabeto. In altre parole, ogni lettera dell'alfabeto viene costantemente sostituita nel testo da un'altra lettera. Per garantire che la crittografia sia reversibile, non ci sono due lettere sostituite dalla stessa lettera. Il tuo compito è decrittografare diverse righe di testo codificate, supponendo che ciascuna riga utilizzi un diverso set di sostituzioni e che tutte le parole nel testo decrittografato provengano da un dizionario di parole conosciute.

Ingresso

L'input è composto da parole minuscole, in ordine alfabetico. Queste parole compongono il dizionario di parole che possono apparire nel testo decrittografato. Di seguito il dizionario sono diverse righe di input. Ogni riga è crittografata come descritto sopra.

Non ci sono più di 1.000 parole nel dizionario. Nessuna parola supera le 16 lettere. Le righe crittografate contengono solo lettere minuscole e spazi e non superano gli 80 caratteri di lunghezza.

Produzione

Decifrare ogni riga e stamparla sull'output standard. Se ci sono più soluzioni, ognuna lo farà. Se non esiste una soluzione, sostituire ogni lettera dell'alfabeto con un asterisco.

Input di esempio

and dick jane puff spot yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd

Uscita campione

dick and jane and puff and spot and yertle
**** *** **** *** **** *** **** *** ******

Ecco la soluzione. Si prega di notare che non sono un cavallo che corre in gara per i byte più brevi / programmatore competitivo. Mi piacciono i puzzle!

( Fonte )


1
Rilascia i tuoi> input <vincoli a qualcosa che è applicabile per ogni lingua. Ad esempio, molte lingue odieranno e non apprezzano che il formato inizi con un 6. Suggerirei di lasciare il formato totalmente non specificato, e direi solo che l'input è un elenco di parole e un elenco di righe da crittografare.
orlp

Ok, eccoti!
Dhruv Ramani,

1
Ci sono vincoli di runtime a questo? Posso semplicemente scorrere tutte le possibili combinazioni di sostituzione, fino a quando non funziona (che probabilmente impiegherebbe anni per finire)?
Nathan Merrill,

@NathanMerrill Fallo, e se ci vorranno anni, stampalo sotto forma di stella. Vihan, non è un duplicato, ti preghiamo di leggere correttamente la domanda.
Dhruv Ramani,

Possiamo semplicemente scrivere le parole o dobbiamo unirci a loro?
Downgoat,

Risposte:


3

Python 3, 423 byte

import sys,re
S=re.sub
D,*L=sys.stdin.read().split('\n')
def f(W,M=[],V="",r=0):
 if len({d for(s,d)in M})==len(M):
  if[]==W:return V.lower()
  for d in D.split():p='([a-z])(?%s.*\\1)';m=re.match(S(p%'=',')\\1=P?(',S(p%'!',').>\\1<P?(',W[0].translate(dict(M))[::-1]))[::-1]+'$',d.upper());r=r or m and f(W[1:],M+[(ord(s),m.group(s))for s in m.groupdict()],V+d+" ")
  return r
for l in L:print(f(l.split())or S('\w','*',l))

Legge l'input da STDIN e scrive l'output su STDOUT, utilizzando lo stesso formato dell'input / output di esempio.

Spiegazione

Per ogni riga di testo cifrato, eseguiamo la seguente procedura:

Manteniamo una mappa, M , di tutte le trasformazioni di lettere che abbiamo già stabilito (che inizialmente è vuota). Lo facciamo in modo tale che le lettere di origine siano tutte minuscole e le lettere di destinazione siano tutte maiuscole.

Elaboriamo le parole nel testo cifrato in ordine. Per ogni parola, troviamo tutte le parole nel dizionario che potrebbe corrispondere, come segue:

Supponiamo che la nostra parola, w , sia glpplppljjle che M contenga la regola j -> P. Trasformiamo prima w usando le regole esistenti in M , ottenendo glpplpplPPl. Trasformiamo quindi w nel seguente regex al gusto di pitone:

(?P<g>.)(?P<l>.)(?P<p>.)(?P=p)(?P=l)(?P=p)(?P=p)(?P=l)PP(?P=l)

Le regole della trasformazione sono le seguenti:

  • La prima occorrenza di ogni lettera minuscola x, viene sostituita da . Questo definisce un gruppo di acquisizione denominato , chiamato , che corrisponde a un singolo cahracter.(?P<x>.)x
  • Ogni ricorrenza successiva ogni lettera minuscola x, viene sostituita da . Questo è un riferimento al personaggio precedentemente catturato dal gruppo nominato .(?P=x)x

Eseguiamo questa trasformazione invertendo w , quindi applicando le due seguenti sostituzioni regex:

s/([a-z])(?!.*\1)/)>\1<P?(/
s/([a-z])(?=.*\1)/)\1=P?(/

e quindi invertire il risultato. Notare che i caratteri precedentemente trasformati da M appaiono in maiuscolo e quindi rimangono invariati.

Abbiniamo la regex risultante a ciascuna delle parole del dizionario, in cui le parole del dizionario appaiono in maiuscolo. Ad esempio, la regex di cui sopra corrisponderebbe alla parola MISSISSIPPI. Se troviamo una corrispondenza, si estrae le nuove regole di trasformazione da esso, e aggiungerli al M . Le nuove regole di trasformazione sono semplicemente i personaggi catturati da ciascuno dei gruppi di acquisizione. Nella regex sopra, il gruppo gcorrisponde M, il gruppo lcorrisponde Ie il gruppo pcorrisponde S, dandoci le regole g -> M, l -> I, p -> S. Dobbiamo assicurarci che le regole risultanti siano coerenti, cioè che non vi siano due lettere di origine associate alla stessa lettera di destinazione; altrimenti, rifiutiamo la partita.

Passiamo quindi alla parola successiva, utilizzando le regole di trasformazione aumentata. Se riusciamo ad abbinare tutte le parole cifrate usando questo processo, abbiamo decifrato il testo. Se non riusciamo a far corrispondere una parola a nessuna delle parole del dizionario, facciamo un passo indietro e proviamo ad abbinare le parole precedenti a parole diverse del dizionario. Se questo processo fallisce, non c'è soluzione e stampiamo una fila di asterischi.


2

CJam, 62 56 byte

qN%Sf/(f{\:C,m*{C..+`Sa`m2/Q|z_''f-Qf|=},C:,'*f*a+0=S*N}

Abbastanza lento e affamato di memoria, ma funziona per il test case con l'interprete Java.

Esempio di esecuzione

$ cat input; echo
and dick jane puff spot yertle

bjvg xsb hxsn xsb qymm xsb rqat xsb pnetfn
xxxx yyy zzzz www yyyy aaa bbbb ccc dddddd
$ time cjam kicker.cjam < input
dick and jane and puff and spot and yertle
**** *** **** *** **** *** **** *** ******

real    5m19.817s
user    6m41.740s
sys     0m1.611s
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.