코딩 테스트/프로그래머스
[Swift] 프로그래머스(lv.1) 32 - 시저 암호
말차프라푸치노
2022. 3. 17. 19:08
시저 암호
문제 설명
어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.
제한 조건
- 공백은 아무리 밀어도 공백입니다.
- s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
- s의 길이는 8000이하입니다.
- n은 1 이상, 25이하인 자연수입니다.
문제 풀이
유니코드를 사용해서 String에 대해 +n 을 해주고 리턴해주었다.
이 때 Z -> A, z -> a, 공백에 대해 예외 처리를 해주었다.
- 우선 파라미터 s를 배열 strArray로 만들어주었다.
- 배열의 for 루프를 돌면서 각 문자에 대해 유니코드 스칼라 값을 얻었다. 이 때 UnicodeScalar()는 String을 인자로 받으므로 String 래핑을 해주었다. 또 옵셔널 값을 리턴하기 때문에 !를 사용해 강제 언래핑을 해주었다.
- 예외 처리를 해주었다. A의 유니코드는 65, Z의 유니코드는 90이다. 여기서 90을 넘는다고 그냥 26을 빼면 안된다. a의 유니코드가 97, z의 유니코드가 122이기 때문이다. 그래서 1. n을 이동시키기 전에는 Z 이전이고 이동시킨 후에는 Z를 넘어가는 조건 (str_to_num <= 90 && str_to_num + n > 90)이랑 2. n을 이동시키기 전에는 z 이전이고 이동시킨 후에는 z를 넘어가는 조건 (str_to_num <= 122 && str_to_num + n > 122)을 두었다.
- 공백(유니코드 32) 에 대해 예외를 두었다.
- append 메소드를 사용해 배열 result에 n만큼 민 값을 추가해주었다.
- joined() 메소드를 사용해 String으로 합쳐주었다.
코드
내 코드
func solution(_ s:String, _ n:Int) -> String {
let strArray = Array(s)
var result:[String] = []
for i in strArray {
var str_to_num:Int = Int(UnicodeScalar(String(i))!.value)
if((str_to_num <= 90 && str_to_num + n > 90) || (str_to_num <= 122 && str_to_num + n > 122)) {
str_to_num -= 26
}
if(str_to_num != 32) {
str_to_num += n
}
result.append(String(UnicodeScalar(str_to_num)!))
}
return
다른 사람의 코드
func solution(_ s:String, _ n:Int) -> String {
return s.utf8.map {
var code = Int($0)
switch code {
case 65...90:
code = (code + n - 65) % 26 + 65
case 97...122:
code = (code + n - 97) % 26 + 97
default:
break
}
return String(UnicodeScalar(code)!)
}.joined()
}
utf8.map 을 사용해 string을 돌았다. 이 점에 있어서 배열로 변환했다가 다시 문자열로 변환하는 내 코드보다 효율적이었다.
switch 문과 나머지 개념을 사용했다. 이거는 신박했다.
리턴한 문자열을 joined()를 사용해 합쳐주었다.
후기
원 점으로 돌아오는 경우는 항상 나머지를 염두해주자.
(왜 나는 나머지를 생각 못 했지 😭)