본문 바로가기
📖 Coding Test/Programmers LV.1

[Swift] 프로그래머스 LV.1 둘만의 암호

by hyebin (Helia) 2023. 3. 18.
프로그래머스 LV.1 모음

둘만의 암호

문제 설명

두 문자열 s와 skip, 그리고 자연수 index가 주어질 때, 다음 규칙에 따라 문자열을 만들려 합니다. 암호의 규칙은 다음과 같습니다.

  • 문자열 s의 각 알파벳을 index만큼 뒤의 알파벳으로 바꿔줍니다.
  • index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아갑니다.
  • skip에 있는 알파벳은 제외하고 건너뜁니다.

예를 들어 s = "aukks", skip = "wbqd", index = 5일 때, a에서 5만큼 뒤에 있는 알파벳은 f지만 [b, c, d, e, f]에서 'b'와 'd'는 skip에 포함되므로 세지 않습니다. 따라서 'b', 'd'를 제외하고 'a'에서 5만큼 뒤에 있는 알파벳은 [c, e, f, g, h] 순서에 의해 'h'가 됩니다. 나머지 "ukks" 또한 위 규칙대로 바꾸면 "appy"가 되며 결과는 "happy"가 됩니다.

 

두 문자열 s와 skip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return 하도록 solution 함수를 완성해 주세요.

제한 사항

  • 5 ≤ s의 길이 ≤ 50
  • 1 ≤ skip의 길이 ≤ 10
  • s와 skip은 알파벳 소문자로만 이루어져 있습니다.
    • skip에 포함되는 알파벳은 s에 포함되지 않습니다.
  • 1 ≤ index ≤ 20

입출력 예

s skip index result
"aukks" "wbqd" 5 "happy"

입출력 예 설명

입출력 예 #1

  • 본문 내용과 일치합니다.

제출

import Foundation

func solution(_ s:String, _ skip:String, _ index:Int) -> String {
    func find(_ ch: Int) -> String{
        var cnt = 0, pos = 1
        var target = ch
        while cnt < index{
            pos = pos > 26 ? 1 : pos
            target = ch+pos > 122 ? ch+pos-26 : ch+pos

            if !skip.contains(String(UnicodeScalar(target)!)){
                cnt += 1
            }
            pos += 1
        }
        return target > 122 ? String(UnicodeScalar(target-26)!) : String(UnicodeScalar(target)!)
    }

    var result = ""

    for i in s{
        result += find(Int(i.asciiValue!))
    }

    return result
}

 

<find 함수 동작>
find 함수를 생성해 알파벳의 아스키코드 값을 매개변수로 받는다.
변수 cnt는 0으로, pos는 1로 초기화하여 생성한다.

cnt가 index보다 작은 경우에만 while문을 반복한다.
pos가 26보다 크다면 1로 값을 바꾼다. (pos는 알파벳을 가리키기 때문에 1 <= pos <= 26이다.)
target은 pos+cnt인데, 이 값이 122보다 크다면 26을 뺀다. (target은 아스키코드 값을 저장함, 알파벳 소문자의 아스키코드는 97부터 122이기 때문에 122보다 크다면 26을 뺀다.)
target을 알파벳으로 변환했을 때, skip에 포함되어 있지 않다면 cnt를 1 증가시킨다.
pos를 1 증가시킨다.

최종 tartget이 122보다 크다면 target-26을, 아니라면 tartget을 알파벳으로 변환해 반환한다.

<solution 함수>
결과 값을 담을 result 변수를 생성한다.
입력받은 문자열 s에서 문자 하나씩 find 함수를 사용해 알파벳을 얻어 result 변수에 추가한다.

다른 풀이

import Foundation

func solution(_ s:String, _ skip:String, _ index:Int) -> String {
    let arr = "abcdefghijklmnopqrstuvwxyz".map{String($0)}.filter {!skip.contains($0) }
    
    return s
    .map { 
        arr[arr.index(arr.firstIndex(of: String($0))!, offsetBy: index) % arr.count] 
    }
    .joined()
}
a부터 z까지 알파벳들 중에서 skip에 포함되지 않은 알파벳들만 arr 배열에 저장한다.
입력받은 문자열 s에 map을 사용하여 (arr에서 s의 문자의 인덱스 + index) % arr의 크기를 인덱스로 갖는 알파벳을 반환한다.
(입력값이 본문과 같을 때,
arr에서 a의 인덱스는 0, 0+5 = 5, arr의 5번째 알파벳은 "h"이기 때문에 "h"를 반환한다.
연산 값이 arr의 크기보다 커진 경우를 대비해 % arr.count를 사용한다.)
알파벳들을 joined()를 사용하여 하나의 문자열로 반환한다.

 

반응형

댓글