암호화 키커 //


12

암호화 키커

텍스트를 암호화하는 일반적이지만 안전하지 않은 방법은 알파벳 문자를 퍼 뮤트하는 것입니다. 즉, 알파벳의 각 문자는 텍스트에서 다른 문자로 일관되게 바뀝니다. 암호화를 되돌릴 수 있도록하기 위해 두 글자가 같은 글자로 바뀌지 않습니다. 각 줄이 서로 다른 대체 집합을 사용하고 해독 된 텍스트의 모든 단어가 알려진 단어의 사전에 있다고 가정하면 인코딩 된 여러 줄의 텍스트를 해독해야합니다.

입력

입력은 알파벳 순서로 소문자로 구성됩니다. 이 단어는 해독 된 텍스트에 나타날 수있는 단어 사전을 구성합니다. 사전 다음에는 여러 줄의 입력이 있습니다. 각 라인은 위에서 설명한대로 암호화됩니다.

사전에 1,000 개 이하의 단어가 없습니다. 16자를 초과하는 단어는 없습니다. 암호화 된 줄은 소문자와 공백 만 포함하며 길이는 80자를 초과하지 않습니다.

산출

각 줄을 해독하여 표준 출력으로 인쇄하십시오. 여러 솔루션이있는 경우 어느 솔루션이든 가능합니다. 해결책이 없으면 알파벳의 모든 문자를 별표로 바꾸십시오.

샘플 입력

and dick jane puff spot yertle

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

샘플 출력

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

해결책은 다음과 같습니다 . 나는 가장 짧은 바이트 / 경쟁 프로그래머를 위해 경주에서 달리는 말이 아닙니다 . 난 그냥 퍼즐을 좋아한다!

( 소스 )


1
각 언어에 적용 할 수있는> input <제약 조건을 완화하십시오. 예를 들어, 많은 언어는 증오를 나타내며 형식이 6으로 시작한다는 것을 인식하지 못합니다. 형식을 완전히 지정하지 않은 채로 두는 것이 좋습니다. 입력은 단어 목록과 암호화 할 행 목록이라고 만 말하겠습니다.
orlp

알았어!
Dhruv Ramani

1
이것에 대한 런타임 제약이 있습니까? 한 번의 작업이 완료 될 때까지 가능한 모든 교체 조합을 간단히 반복 할 수 있습니까?
Nathan Merrill

@NathanMerrill 그렇게하고, 몇 년이 걸리면 별 모양으로 인쇄하면됩니다. Vihan, 중복되지 않습니다. 질문을 올바르게 읽으십시오.
Dhruv Ramani

단어를 출력 할 수 있습니까? 아니면 단어를 결합해야합니까?
Downgoat

답변:


3

파이썬 3, 423 바이트

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))

샘플 입력 / 출력과 동일한 형식을 사용하여 STDIN에서 입력을 읽고 출력을 STDOUT에 씁니다.

설명

암호문의 각 줄에 대해 다음 절차를 수행합니다.

우리 는 이미 확립 한 모든 문자 변환에 대한 맵 M을 유지합니다 (처음 비어 있음). 소스 문자가 모두 소문자이고 대상 문자가 모두 대문자가되도록합니다.

암호문의 단어를 순서대로 처리합니다. 각 단어에 대해 다음과 같이 사전에서 일치하는 모든 단어를 찾습니다.

우리의 단어 wglpplppljjl있고 M 이 규칙을 포함 한다고 가정하자 j -> P. 먼저 M 의 기존 규칙을 사용하여 w 를 변환 하여을 얻습니다 . 그런 다음 w 를 다음과 같은 파이썬 풍미 정규 표현식으로 변환합니다 .glpplpplPPl

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

변환 규칙은 다음과 같습니다.

  • 각 소문자의 첫 번째 문자 x는로 대체됩니다 . 단일 cahracter와 일치 하는 명명 된 캡처 그룹 ()을 정의합니다 .(?P<x>.)x
  • 이후의 모든 소문자 x는로 대체됩니다 . 이름이 지정된 그룹에 의해 미리 캡처 된 문자에 대한 역 참조 입니다.(?P=x)x

우리는 w 를 뒤집은 다음 다음 두 정규식 대체를 적용 하여이 변환을 수행합니다 .

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

그런 다음 결과를 되돌립니다. 이전에 M에 의해 변환 된 문자 는 대문자로 표시되므로 변경되지 않은 상태로 유지됩니다.

결과 정규식을 각 사전 단어와 비교하여 사전 단어가 대문자로 나타납니다. 예를 들어 위의 정규 표현식은 단어와 일치합니다 MISSISSIPPI. 일치하는 것을 찾으면 새로운 변환 규칙을 추출하여 M에 추가합니다 . 새로운 변환 규칙은 단순히 각 캡처 그룹이 캡처 한 문자입니다. 위의 정규 표현식에서 그룹이 g일치 M하고 그룹이 l일치 I하며 그룹이 p일치 S하여 규칙을 제공 g -> M, l -> I, p -> S합니다. 결과 규칙이 일치하는지 확인해야합니다. 즉, 두 개의 원본 문자가 동일한 대상 문자에 매핑되지 않아야합니다. 그렇지 않으면, 우리는 경기를 거부합니다.

그런 다음 확장 변환 규칙을 사용하여 다음 단어로 진행합니다. 이 프로세스를 사용하여 모든 암호문 단어를 일치시킬 수 있으면 텍스트를 해독 한 것입니다. 사전 단어와 일치하는 단어를 찾을 수 없으면 이전 단어를 다른 사전 단어와 역 추적하고 일치 시키려고합니다. 이 프로세스가 실패하면 해결책이 없으며 별표가 인쇄됩니다.


2

CJam, 62 56 바이트

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

상당히 느리고 메모리가 부족하지만 Java 인터프리터를 사용하여 테스트 케이스에서 작동합니다.

예제 실행

$ 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.