CS/알고리즘

[Javascript] 백준 14584: 암호 해독

s0ojin 2023. 2. 17. 18:46

 

문제

로마의 장군 카이사르는 로마군의 작전을 적이 모르게 하기 위하여 암호를 사용했다. 카이사르는 다음과 같이 문장에 있는 모든 알파벳 글자를 몇 칸 뒤의 알파벳으로 바꾸는 방식으로 암호를 만들었다. 아래 표는 모든 글자를 17칸 뒤의 알파벳으로 바꿨을 때 각 글자가 어떤 알파벳으로 바뀌는지 나타낸 표이다.

이 방법에 따라 ‘Baekjoon Online Judge’를 암호화하면 ‘Srvbaffe Feczev Aluxv’가 된다.

당신은 페르시아 군대의 장군으로서 카이사르의 암호를 해독해야 한다. 당신은 카이사르가 어떤 방법으로 문장을 암호화하는지는 알고 있지만 카이사르가 몇 칸 뒤의 알파벳으로 바꾸는지는 모른다. 다행히, 당신의 부하가 로마어 사전을 가져와서 이를 통해 카이사르의 암호를 해독할 수 있을 것으로 보인다. 보통 전령에는 보편적인 단어가 나오기 때문에 사전에 나오는 단어가 반드시 있을 것이다. 따라서 암호를 해독한 후, 해독한 문장에서 사전에 나오는 단어가 반드시 하나 이상 등장해야 한다.

카이사르의 암호와 사전의 정보가 주어졌을 때, 암호를 해독하는 프로그램을 작성하여라.

입력

첫 번째 줄에 암호문이 주어진다. 암호문은 소문자로만 이루어진 길이 100 이하의 문자열이다.

두 번째 줄에는 사전에 있는 단어의 수 N이 주어진다. (1 ≤ N ≤ 20)

세 번째 줄부터 N개의 줄에는 사전에 있는 단어가 주어진다. 모든 단어는 소문자로만 이루어진 길이 20 이하의 문자열이다.

출력

암호문을 해독하여 나온 원문을 출력한다. 모든 데이터에 대해서 답이 한 가지인 경우만 들어온다고 가정한다.

예제 입력 1 

srbvaffefeczevaluxv
3
bake
bread
cookie

예제 출력 1 

bakejoononlinejudge

 


문제 풀이

: 들어오는 암호문을 한칸씩 미뤄가며 주어진 단어가 포함된 문자열이 나오면 출력해주면 됩니다.

 

1. 알파벳 배열을 만들어 주었습니다.

2. 들어온 암호문을 charCodeAt()을 이용하여 숫자로 변환해주었습니다(a=0이 되도록, passwordNum).

3. passwordNum을 순회하면서  1씩 증가시켜주면 한칸 씩 밀리게 됩니다. 

  • 가령 'abcde' 는  passwordNum = [0, 1, 2, 3, 4] 상태입니다.
  • passwordNum을 순회하며 +1씩해주면  [1, 2, 3, 4, 5]가 되므로 다시 문자로 변환한다면 'bcdef'가 될 것입니다.

4. 이런식으로 복호화된 문자열에서 주어진 단어를 포함하고 있는 문자열이 나오면 출력하고 루프를 멈춰줍니다. 

 

 

const input = require("fs")
  .readFileSync("/dev/stdin")
  .toString()
  .trim()
  .split("\n");

const password = input.shift().split("");
const N = +input.shift();
const dict = input;

const alphabet = Array.from({ length: 26 }, (_, i) =>
  String.fromCharCode(i + 97)
);

const passwordNum = [];

for (let i = 0; i < password.length; i++) {
  passwordNum.push(password[i].charCodeAt() - 97);
}

outer: for (let i = 0;; i++) {
  let decryption = "";

  for (let j = 0; j < passwordNum.length; j++) {
    if (passwordNum[j] + i > 25) {
      decryption += alphabet[passwordNum[j] + i - 26];
    } else decryption += alphabet[passwordNum[j] + i];
  }

  for (let k = 0; k < N; k++) {
    if (decryption.includes(dict[k])) {
      console.log(decryption);
      break outer;
    }
  }
}