Softeer - 플레이페어 암호 [HSAT 3회 정기 코딩 인증평가 기출] - Java

chaemin·2024년 2월 15일
0

Softeer

목록 보기
6/8

1. 문제

https://softeer.ai/practice/6255

2. 풀이

두개 중에서는 밑에 풀이가 훨씬 이해가 잘 갔다.
쉬웠던 문제라고들 하는데

  1. 알파벳의 중복검사와 Map사용
  2. 암호화 하려는 메시지 두 글자씩 나누기

두 가지가 관건이였던거 같다.

2-1. 풀이를 참고한 방법.

  1. 'A'를 활용해서 숫자로 바꿀 수도 있다!
char keyMap[][] = new char[5][5];
boolean alpha[] = new boolean[26];
int idx = 0;
Arrays.fill(alpha, false);
alpha['J' - 'A'] = true;
  1. 나머지 알파벳을 암호화 5 * 5 배열에 넣어준다.
for(int a = 0; a < alpha.length; a++) {
	if(!alpha[a]) {
		keyMap[idx / 5][idx % 5] = (char) (a + 'A');
		idx++;
	}
}
  1. Queue를 이용해서 암호화 문자열을 두 글자씩 쪼갠다.
    ✨peek()를 활용하여 다음 글자를 알 수 있다.
Queue<Character> que = new LinkedList<>();
ArrayList<String> list = new ArrayList<>();

for(int m = 0; m < message.length(); m++) {
	que.add(message.charAt(m));
}

while(!que.isEmpty()) {
	
	char firstChar = que.poll();
	char secondChar;
	
	if(!que.isEmpty()) {
		if(que.peek() == firstChar) {
			secondChar = (firstChar == 'X') ? 'Q' : 'X';
		} else {
			secondChar = que.poll();
		}
	} else {
		secondChar = 'X';
	}
	
	list.add( String.valueOf(firstChar) + String.valueOf(secondChar) );
}

3. 코드

import java.util.*;
import java.io.*;

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br =  new BufferedReader(new InputStreamReader(System.in));
		
		String message = br.readLine();
		String key = br.readLine();
		
		/**
		 * 1. key를 Map에 넣기
		 */
		char keyMap[][] = new char[5][5];
		boolean alpha[] = new boolean[26];
		int idx = 0;
		Map<Character, Point> pointMap = new HashMap<>();
		
		Arrays.fill(alpha, false);
		alpha['J' - 'A'] = true;
		
		for(int k = 0; k < key.length(); k++) {
			int nowKey = key.charAt(k) - 'A';
			
			if(alpha[nowKey]) {
				continue;
				
			} else {
				keyMap[idx / 5][idx % 5] = key.charAt(k);
				alpha[nowKey] = true;
				idx++;
			}
		}
		
		for(int a = 0; a < alpha.length; a++) {
			if(!alpha[a]) {
				keyMap[idx / 5][idx % 5] = (char) (a + 'A');
				idx++;
			}
		}
		
		for(int i = 0; i < 5; i++) {
			for(int j = 0; j < 5; j++) {
				pointMap.put(keyMap[i][j], new Point(i, j));
			}
		}
        
		Queue<Character> que = new LinkedList<>();
		ArrayList<String> list = new ArrayList<>();
		
		for(int m = 0; m < message.length(); m++) {
			que.add(message.charAt(m));
		}
		
		/**
		 * 2. 암호화 문자열 두 단어씩 쪼개기
		 */
		while(!que.isEmpty()) {
			
			char firstChar = que.poll();
			char secondChar;
			
			if(!que.isEmpty()) {
				if(que.peek() == firstChar) {
					secondChar = (firstChar == 'X') ? 'Q' : 'X';
				} else {
					secondChar = que.poll();
				}
			} else {
				secondChar = 'X';
			}
			
			list.add( String.valueOf(firstChar) + String.valueOf(secondChar) );
		}
		
		StringBuilder sb = new StringBuilder();
		for(String str : list) {
			Point firstP = pointMap.get(str.charAt(0));
			Point secondP = pointMap.get(str.charAt(1));
			
			int moveFx = firstP.x;
			int moveFy = firstP.y;
			int moveSx = secondP.x;
			int moveSy = secondP.y;
			
			if(firstP.x == secondP.x) { // 같은 행
				moveFy = (moveFy == 4) ? 0 : moveFy + 1;
				moveSy = (moveSy == 4) ? 0 : moveSy + 1;
				
			} else if(firstP.y == secondP.y) { // 같은 열
				moveFx = (moveFx == 4) ? 0 : moveFx + 1;
				moveSx = (moveSx == 4) ? 0 : moveSx + 1;
				
			} else {
				int tmp = moveFy;
				moveFy = moveSy;
				moveSy = tmp;
			}
			
			sb.append(String.valueOf(keyMap[moveFx][moveFy]));
			sb.append(String.valueOf(keyMap[moveSx][moveSy]));
		}
		
		System.out.println(sb.toString());

	}
	
	public static class Point {
		int x;
		int y;
		
		public Point(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}

}

0개의 댓글