문제 설명

과일 장수가 사과 상자를 포장하고 있습니다. 사과는 상태에 따라 1점부터 k점까지의 점수로 분류하며, k점이 최상품의 사과이고 1점이 최하품의 사과입니다. 사과 한 상자의 가격은 다음과 같이 결정됩니다.

  • 한 상자에 사과를 m개씩 담아 포장합니다.
  • 상자에 담긴 사과 중 가장 낮은 점수가 p (1 ≤ p ≤ k)점인 경우, 사과 한 상자의 가격은 p * m 입니다.

과일 장수가 가능한 많은 사과를 팔았을 때, 얻을 수 있는 최대 이익을 계산하고자 합니다.(사과는 상자 단위로만 판매하며, 남는 사과는 버립니다)

예를 들어, k = 3, m = 4, 사과 7개의 점수가 [1, 2, 3, 1, 2, 3, 1]이라면, 다음과 같이 [2, 3, 2, 3]으로 구성된 사과 상자 1개를 만들어 판매하여 최대 이익을 얻을 수 있습니다.

  • (최저 사과 점수) x (한 상자에 담긴 사과 개수) x (상자의 개수) = 2 x 4 x 1 = 8

사과의 최대 점수 k, 한 상자에 들어가는 사과의 수 m, 사과들의 점수 score가 주어졌을 때, 과일 장수가 얻을 수 있는 최대 이익을 return하는 solution 함수를 완성해주세요.

제한사항
  • 3 ≤ k ≤ 9
  • 3 ≤ m ≤ 10
  • 7 ≤ score의 길이 ≤ 1,000,000
    • 1 ≤ score[i] ≤ k
  • 이익이 발생하지 않는 경우에는 0을 return 해주세요.

내가 푼 풀이

등급별 갯수를 저장할 수 있는 Dictionary에 저장한다 [Int: Int]

등급 내림차순으로 높은 등급부터 상자에 최대한 담아서 최대 이익을 계산한다.

이익 계산이 상자에 들어있는 가장 낮은 점수의 곱이라서 내림차순으로 높은 점수부터 넣어야 최대 이익이 나올꺼라 생각했다.

import Foundation

func solution(_ k:Int, _ m:Int, _ score:[Int]) -> Int {
    var result = 0
    var dict = [Int: Int]()
    var good = k
    var count = m
    
    for i in 1...k {
        dict[i] = score.filter{$0 == i}.count
    }
    
    while good > 0 {
        if count > 0 {
            if dict[good]! > 0 {
                var num = count
                if dict[good]! >= count {
                    dict[good]! -= count
                    count = 0
                } else {
                    count -= dict[good]!
                    dict[good]! = 0
                }
            } else {
                good -= 1
            }
        } else {
            result = result + good * m 
            count = m
        }

    }
    return result
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

햄버거 만들기 Swift  (0) 2023.04.10
푸드 파이트 대회 Swift  (0) 2023.04.10
기사단원의 무기 Swift  (0) 2023.04.10
명예의 전당 (1) Swift  (0) 2023.04.10
문자열 나누기 Swift  (0) 2023.04.10

문제 설명

숫자나라 기사단의 각 기사에게는 1번부터 number까지 번호가 지정되어 있습니다. 기사들은 무기점에서 무기를 구매하려고 합니다.

각 기사는 자신의 기사 번호의 약수 개수에 해당하는 공격력을 가진 무기를 구매하려 합니다. 단, 이웃나라와의 협약에 의해 공격력의 제한수치를 정하고, 제한수치보다 큰 공격력을 가진 무기를 구매해야 하는 기사는 협약기관에서 정한 공격력을 가지는 무기를 구매해야 합니다.

예를 들어, 15번으로 지정된 기사단원은 15의 약수가 1, 3, 5, 15로 4개 이므로, 공격력이 4인 무기를 구매합니다. 만약, 이웃나라와의 협약으로 정해진 공격력의 제한수치가 3이고 제한수치를 초과한 기사가 사용할 무기의 공격력이 2라면, 15번으로 지정된 기사단원은 무기점에서 공격력이 2인 무기를 구매합니다. 무기를 만들 때, 무기의 공격력 1당 1kg의 철이 필요합니다. 그래서 무기점에서 무기를 모두 만들기 위해 필요한 철의 무게를 미리 계산하려 합니다.

기사단원의 수를 나타내는 정수 number와 이웃나라와 협약으로 정해진 공격력의 제한수치를 나타내는 정수 limit와 제한수치를 초과한 기사가 사용할 무기의 공격력을 나타내는 정수 power가 주어졌을 때, 무기점의 주인이 무기를 모두 만들기 위해 필요한 철의 무게를 return 하는 solution 함수를 완성하시오.


제한사항
  • 1 ≤ number ≤ 100,000
  • 2 ≤ limit ≤ 100
  • 1 ≤ power  limit

내가 푼 풀이

약수의 갯수를 구해서 limit을 초과하면 기본공격력 power 만큼 더하고, 초과하지 않으면 약수의 갯수만큼 더해서 출력한다.

 

이 문제에서 주어지는 number는 100,000 까지 제공한다.

일반적인 약수의 갯수를 구하는방법은 

숫자 n 이 주어졌을때, 1부터 n까지 나누어 떨어지면 약수이고 그 갯수를 구하는것이 일반적인 방법이다

하지만 이 방법은 2중 반복문 안에서 갯수를 구하므로 ( O(n^2) ) 시간초과가 날 경우가 많다.

이 문제 역시 모든 숫자를 순회해서 약수를 구하는 방법을 이용하면 시간초과가 뜬다.

 

그래서 약수를 구하는 더 효율적인 방법을 이용해야한다.

여러가지가 있겠지만 그 중 하나는 범위를 좁히는것이다. 

숫자 n 이 주어졌을때, n의 제곱근까지 확인한다.

이전에 소수를 효율적으로 구하는 과정이랑 비슷한데,

10의 약수 2 는 2 x 5 = 10이지만 10의 약수 5 도 역시 5 x 2 = 10 이다.

갯수는 2개지만 표현식은 앞뒤만 다를뿐 결국 같다는것을 이용하는 것이다

 

그리고 제곱근이 정수로 딱 떨어지는 경우, ex) 100

1 x 100 = 100 

2 x 50 = 100

4 x 25 = 100

5 x 20 = 100

10 x 10 = 100

20 x 5 = 100

25 x 4 = 100

50 x 2 = 100

100 x 1 = 100 

10 x 10 을 기준으로 대칭을 이루고 있다.

정수 n의 제곱근이 정수로 떨어지는 경우 num * num == n 인경우 횟수 증가한다.

이 방법의 시간복잡도는 O(√N) 으로 이전에 쓰는 일반적인 방법보다 시간이 훨씬 단축된다.

 

 

import Foundation

func solution(_ number:Int, _ limit:Int, _ power:Int) -> Int {
    var result = 0
    
    for i in 1...number {
        var num = 1
        var count = 0
        
        while num * num <= i {
            if (num * num) == i {
                count += 1
            } else if i % num == 0 {
                count += 2
            }
            num += 1
        }
        if count > limit {
            result += power
        } else {
            result += count
        }
    }
    return result
}

 

약수의 개수 구하기 알고리즘 참고:

https://chwan.tistory.com/entry/Java-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

푸드 파이트 대회 Swift  (0) 2023.04.10
과일 장수 Swift  (0) 2023.04.10
명예의 전당 (1) Swift  (0) 2023.04.10
문자열 나누기 Swift  (0) 2023.04.10
가장 가까운 같은 글자 Swift  (0) 2023.04.09

문제 설명

"명예의 전당"이라는 TV 프로그램에서는 매일 1명의 가수가 노래를 부르고, 시청자들의 문자 투표수로 가수에게 점수를 부여합니다. 매일 출연한 가수의 점수가 지금까지 출연 가수들의 점수 중 상위 k번째 이내이면 해당 가수의 점수를 명예의 전당이라는 목록에 올려 기념합니다. 즉 프로그램 시작 이후 초기에 k일까지는 모든 출연 가수의 점수가 명예의 전당에 오르게 됩니다. k일 다음부터는 출연 가수의 점수가 기존의 명예의 전당 목록의 k번째 순위의 가수 점수보다 더 높으면, 출연 가수의 점수가 명예의 전당에 오르게 되고 기존의 k번째 순위의 점수는 명예의 전당에서 내려오게 됩니다.

이 프로그램에서는 매일 "명예의 전당"의 최하위 점수를 발표합니다. 예를 들어, k = 3이고, 7일 동안 진행된 가수의 점수가 [10, 100, 20, 150, 1, 100, 200]이라면, 명예의 전당에서 발표된 점수는 아래의 그림과 같이 [10, 10, 10, 20, 20, 100, 100]입니다.

명예의 전당 목록의 점수의 개수 k, 1일부터 마지막 날까지 출연한 가수들의 점수인 score가 주어졌을 때, 매일 발표된 명예의 전당의 최하위 점수를 return하는 solution 함수를 완성해주세요.

제한사항
  • 3 ≤ k ≤ 100
  • 7 ≤ score의 길이 ≤ 1,000
    • 0 ≤ score[i] ≤ 2,000

내가 푼 풀이
점수들이 있는 배열을 순회해서 명예의전당의 최솟값을 결과배열에 넣었다.
  • 명예전당이 비어있으면 -> 추가
  • 명예전당이 k보다 적게있으면 -> 점수크기 상관없이 추가 
  • 명예전당이 꽉 차있으면 -> 주어진 점수보다 작은 값이 명예전당에 있다면 순회해서 찾아서 주어진 점수랑 바꾼다 
  • 결과 배열은 명예전당 추가와 상관없이 순회할때 마다 명예전당의 최솟값을 추가

 

 

import Foundation

func solution(_ k:Int, _ score:[Int]) -> [Int] {
    var points = score
    var glory = [Int]()
    var result = [Int]()
    for i in 0..<points.count {
        if glory.isEmpty {
            glory.append(points[i])
            result.append(points[i])
            continue
        }
        if glory.count < k {
            glory.append(points[i])
            result.append(glory.min()!)
        } else if glory.count >= k {
            var point = points[i]
            if glory.filter{ $0 < point}.count > 0 {
                var min = glory.min()!
                for j in 0..<glory.count {
                    if glory[j] == min {
                        glory[j] = point
                        break
                    }
                }
                result.append(glory.min()!)
            } else {
                result.append(glory.min()!)
            }
        }
    }
    return result
}

 

 
 

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

과일 장수 Swift  (0) 2023.04.10
기사단원의 무기 Swift  (0) 2023.04.10
문자열 나누기 Swift  (0) 2023.04.10
가장 가까운 같은 글자 Swift  (0) 2023.04.09
크기가 작은 부분문자열 Swift  (0) 2023.04.09

문제 설명

문자열 s가 입력되었을 때 다음 규칙을 따라서 이 문자열을 여러 문자열로 분해하려고 합니다.

  • 먼저 첫 글자를 읽습니다. 이 글자를 x라고 합시다.
  • 이제 이 문자열을 왼쪽에서 오른쪽으로 읽어나가면서, x와 x가 아닌 다른 글자들이 나온 횟수를 각각 셉니다. 처음으로 두 횟수가 같아지는 순간 멈추고, 지금까지 읽은 문자열을 분리합니다.
  • s에서 분리한 문자열을 빼고 남은 부분에 대해서 이 과정을 반복합니다. 남은 부분이 없다면 종료합니다.
  • 만약 두 횟수가 다른 상태에서 더 이상 읽을 글자가 없다면, 역시 지금까지 읽은 문자열을 분리하고, 종료합니다.

문자열 s가 매개변수로 주어질 때, 위 과정과 같이 문자열들로 분해하고, 분해한 문자열의 개수를 return 하는 함수 solution을 완성하세요.


제한사항
  • 1 ≤ s의 길이 ≤ 10,000
  • s는 영어 소문자로만 이루어져 있습니다.

내가 푼 풀이

문자열을 배열로만들어서 순회하면서 첫번째 문자의 수와 첫번째 문자가 아닌 수를 비교해서 결과 출력했다.

 

import Foundation

func solution(_ s:String) -> Int {
    var arr = s.map{String($0)}
    var keepArr = [String]()
    var firstStr = ""
    var result = 0

    for i in 0..<arr.count {
        if keepArr.isEmpty {
            firstStr = arr[i]
            keepArr.append(firstStr)
        } else {
            keepArr.append(arr[i])
            if keepArr.filter{$0 == firstStr}.count == keepArr.filter{$0 != firstStr}.count {
                keepArr.removeAll()
                result += 1
            }
        }
        if i == arr.count - 1 {
            if keepArr.count > 0 {
                result += 1
            }
        }
    }

    return result
}

문제 설명

문자열 s가 주어졌을 때, s의 각 위치마다 자신보다 앞에 나왔으면서, 자신과 가장 가까운 곳에 있는 같은 글자가 어디 있는지 알고 싶습니다.
예를 들어, s="banana"라고 할 때,  각 글자들을 왼쪽부터 오른쪽으로 읽어 나가면서 다음과 같이 진행할 수 있습니다.

  • b는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
  • a는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
  • n은 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
  • a는 자신보다 두 칸 앞에 a가 있습니다. 이는 2로 표현합니다.
  • n도 자신보다 두 칸 앞에 n이 있습니다. 이는 2로 표현합니다.
  • a는 자신보다 두 칸, 네 칸 앞에 a가 있습니다. 이 중 가까운 것은 두 칸 앞이고, 이는 2로 표현합니다.

따라서 최종 결과물은 [-1, -1, -1, 2, 2, 2]가 됩니다.

문자열 s이 주어질 때, 위와 같이 정의된 연산을 수행하는 함수 solution을 완성해주세요.


제한사항
  • 1 ≤ s의 길이 ≤ 10,000
    • s은 영어 소문자로만 이루어져 있습니다.

내가 푼 풀이

1.  주어진 문자열 배열로 변환

2. 문자 배열 순회하면서 Dictionary에 문자와 문자의 인덱스 갱신하면서 result 배열에 추가 (문자 s)

2-1) dict[s] == nil 이면 append(-1) , dict[s] = 현재 인덱스

2-2) dict[s] != nil 이면 append( 현재 인덱스 - dict[s] ) , dict[s] = 현재 인덱스

3. result 배열 출력

 

import Foundation

func solution(_ s:String) -> [Int] {
    var dict = [String: Int]()
    var arr = s.map{String($0)}
    var result = [Int]()
    for i in 0..<arr.count {
        if dict[arr[i]] == nil {
            dict[arr[i]] = i
            result.append(-1)
            continue
        }
        var idx = dict[arr[i]]!
        result.append(i - idx)
        dict[arr[i]] = i
    }
    return result
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

명예의 전당 (1) Swift  (0) 2023.04.10
문자열 나누기 Swift  (0) 2023.04.10
크기가 작은 부분문자열 Swift  (0) 2023.04.09
개인정보 수집 유효기간 Swift  (0) 2023.04.09
둘만의 암호 Swift  (0) 2023.04.09

문제 설명

숫자로 이루어진 문자열 t와 p가 주어질 때, t에서 p와 길이가 같은 부분문자열 중에서, 이 부분문자열이 나타내는 수가 p가 나타내는 수보다 작거나 같은 것이 나오는 횟수를 return하는 함수 solution을 완성하세요.

예를 들어, t="3141592"이고 p="271" 인 경우, t의 길이가 3인 부분 문자열은 314, 141, 415, 159, 592입니다. 이 문자열이 나타내는 수 중 271보다 작거나 같은 수는 141, 159 2개 입니다.


제한사항
  • 1 ≤ p의 길이 ≤ 18
  • p의 길이 ≤ t의 길이 ≤ 10,000
  • t와 p는 숫자로만 이루어진 문자열이며, 0으로 시작하지 않습니다.

내가 푼 풀이

1. 문자열 t의 배열을 순회해서 p의 길이만큼 부분 문자열을 뽑아서 배열에 저장한다.

2. 뽑은 배열을 순회하면서 p보다 작거나 같은 문자의 갯수 출력

 

import Foundation

func solution(_ t:String, _ p:String) -> Int {
    var strArr = t.map{String($0)}
    var count = p.count
    var num = Int(p)!
    var numArr = [Int]()
    
    for i in 0..<strArr.count-count + 1 {
        var arr = [String]()
        for j in i..<i+count {
            arr.append(strArr[j])
        }
        numArr.append(Int(arr.joined(separator: ""))!)
    }
    return numArr.filter{ $0 <= num }.count
}

 

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

문자열 나누기 Swift  (0) 2023.04.10
가장 가까운 같은 글자 Swift  (0) 2023.04.09
개인정보 수집 유효기간 Swift  (0) 2023.04.09
둘만의 암호 Swift  (0) 2023.04.09
카드 뭉치 Swift  (0) 2023.04.09

문제 설명

고객의 약관 동의를 얻어서 수집된 1~n번으로 분류되는 개인정보 n개가 있습니다. 약관 종류는 여러 가지 있으며 각 약관마다 개인정보 보관 유효기간이 정해져 있습니다. 당신은 각 개인정보가 어떤 약관으로 수집됐는지 알고 있습니다. 수집된 개인정보는 유효기간 전까지만 보관 가능하며, 유효기간이 지났다면 반드시 파기해야 합니다.

예를 들어, A라는 약관의 유효기간이 12 달이고, 2021년 1월 5일에 수집된 개인정보가 A약관으로 수집되었다면 해당 개인정보는 2022년 1월 4일까지 보관 가능하며 2022년 1월 5일부터 파기해야 할 개인정보입니다.
당신은 오늘 날짜로 파기해야 할 개인정보 번호들을 구하려 합니다.

모든 달은 28일까지 있다고 가정합니다.

다음은 오늘 날짜가 2022.05.19일 때의 예시입니다.

  • 첫 번째 개인정보는 A약관에 의해 2021년 11월 1일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.
  • 두 번째 개인정보는 B약관에 의해 2022년 6월 28일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능합니다.
  • 세 번째 개인정보는 C약관에 의해 2022년 5월 18일까지 보관 가능하며, 유효기간이 지났으므로 파기해야 할 개인정보입니다.
  • 네 번째 개인정보는 C약관에 의해 2022년 5월 19일까지 보관 가능하며, 유효기간이 지나지 않았으므로 아직 보관 가능합니다.

따라서 파기해야 할 개인정보 번호는 [1, 3]입니다.

오늘 날짜를 의미하는 문자열 today, 약관의 유효기간을 담은 1차원 문자열 배열 terms와 수집된 개인정보의 정보를 담은 1차원 문자열 배열 privacies가 매개변수로 주어집니다. 이때 파기해야 할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요.


제한사항
  • today는 "YYYY.MM.DD" 형태로 오늘 날짜를 나타냅니다.
  • 1 ≤ terms의 길이 ≤ 20
    • terms의 원소는 "약관 종류 유효기간" 형태의 약관 종류와 유효기간을 공백 하나로 구분한 문자열입니다.
    • 약관 종류는 A~Z중 알파벳 대문자 하나이며, terms 배열에서 약관 종류는 중복되지 않습니다.
    • 유효기간은 개인정보를 보관할 수 있는 달 수를 나타내는 정수이며, 1 이상 100 이하입니다.
  • 1 ≤ privacies의 길이 ≤ 100
    • privacies[i]는 i+1번 개인정보의 수집 일자와 약관 종류를 나타냅니다.
    • privacies의 원소는 "날짜 약관 종류" 형태의 날짜와 약관 종류를 공백 하나로 구분한 문자열입니다.
    • 날짜는 "YYYY.MM.DD" 형태의 개인정보가 수집된 날짜를 나타내며, today 이전의 날짜만 주어집니다.
    • privacies의 약관 종류는 항상 terms에 나타난 약관 종류만 주어집니다.
  • today와 privacies에 등장하는 날짜의 YYYY는 연도, MM은 월, DD는 일을 나타내며 점(.) 하나로 구분되어 있습니다.
    • 2000 ≤ YYYY ≤ 2022
    • 1 ≤ MM ≤ 12
    • MM이 한 자릿수인 경우 앞에 0이 붙습니다.
    • 1 ≤ DD ≤ 28
    • DD가 한 자릿수인 경우 앞에 0이 붙습니다.
  • 파기해야 할 개인정보가 하나 이상 존재하는 입력만 주어집니다.

내가 푼 풀이

 

1. Dictionary에 [약관명: 유효기간] 을 저장한다.

2. 개인정보 배열을 순회해서 개인정보의 약관 유효기간을 계산해 현재 시간과 비교한다.

3. 유효기간이 현재시간보다 빠르다면( 현재시간보다 이전의 시간이라면), 배열의 인덱스 추출해서 출력한다.

 

문제를 어떻게 접근해야 할지는 금방 생각이 났는데, 날짜를 계산하는 과정에서 쉽게 빈틈이 생겼다.

month = month + 유효기간

만약 month > 12이 참이면  ->  year = year + month / 12 , month 는 13보다 작을때 까지 12를 계속 빼줬다.

이렇게 날짜를 계산했는데 테스트문제 14, 17 에서 자꾸 실패가 떴다.

생각하지 못한 곳에서 계산을 놓친것이 있다는건데 역시나 month + 유효기간이 만약 12로 나누어 떨어지는 경우를 생각하지 못했다.

 

month % 12 == 0 -> year = year + month / 12 - 1

month % 12 != 0 -> year = year + month / 12 

년도를 계산할땐 더 정확하고 세심하게 계산알고리즘을 짜야겠다..

 

import Foundation

func solution(_ today:String, _ terms:[String], _ privacies:[String]) -> [Int] {
    var todayTime = today.split(separator:".").map{Int($0)!}
    var termsArr = terms
    var priv = privacies
    var dict = [String: Int]()
    var result = [Int]()
    
    for i in 0..<terms.count {
        var arrs = terms[i].split(separator: " ").map{ String($0)}
        dict[arrs[0]] = Int(arrs[1])
    }
    
    for i in 0..<priv.count {
        var arr = priv[i].split(separator: " ").map{ String($0)}
        var date = arr[0].split(separator: ".").map{ Int($0)!}
        var term = dict[arr[1]]!
        
        date[1] += term
        if date[1] > 12 {
            if date[1] % 12 == 0 {
                date[0] = date[0] + date[1] / 12 - 1 
            } else {
                date[0] = date[0] + date[1] / 12
            }
            while date[1] > 12 {
                date[1] -= 12
            }            
        }
        if date[0] < todayTime[0] {
            result.append(i + 1)
            continue
        } else if date[0] == todayTime[0] {
            if date[1] < todayTime[1] {
                result.append(i + 1)
                continue
            } else if date[1] == todayTime[1] {
                if date[2] <= todayTime[2] {
                    result.append(i+1)
                    continue
                }
            }
        }
        

    }
    
    return result
}

 

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

가장 가까운 같은 글자 Swift  (0) 2023.04.09
크기가 작은 부분문자열 Swift  (0) 2023.04.09
둘만의 암호 Swift  (0) 2023.04.09
카드 뭉치 Swift  (0) 2023.04.09
대충 만든 자판 Swift  (1) 2023.04.09

문제 설명

두 문자열 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

풀이

1. 문자열 s를 배열로 만든다.

2. 각 문자의 아스키코드를 index만큼 증가시키면서 skipArr에 포함되면 더 건너뛰면서 증가한다.

3. 증가된 아스키코드의 문자를 출력

 

처음에는 index만큼 증가시킨 문자가 skip에 있는경우 건너뛰는줄 알았다.

문제를 잘 읽어보니 index만큼 증가시키되, 그 과정에서 skip에 있는 알파벳이면 index를 카운팅 하지 않고 건너뛴다는 점이다.

그래서 index를 불러서 계속 증가시키는 중에 skip에 포함되어있지 않으면 횟수를 올리고 그 횟수가 index가 되면 출력하는 방식으로

풀었다.

유니코드로 문자열 변환할땐 옵셔널로 반환된다

 

import Foundation

func solution(_ s:String, _ skip:String, _ index:Int) -> String {
    var strArr = s.map{String($0)}
    var skipArr = skip.map{String($0)}
    var result = [String]()
    
    for i in 0..<strArr.count {
        var str = strArr[i]
        var asciiNum = Int(UnicodeScalar(str)!.value)
        var checkNum = index
        var isDone = false
        while !isDone {
            asciiNum += 1
            if asciiNum > 122 {
                asciiNum -= 26
            }
            if !skipArr.contains(String(UnicodeScalar(asciiNum)!)) {
                checkNum -= 1
            }
            
            if checkNum == 0 {
                isDone = true
            }
        }
        result.append(String(UnicodeScalar(asciiNum)!))
    }

    return result.joined(separator: "")
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

크기가 작은 부분문자열 Swift  (0) 2023.04.09
개인정보 수집 유효기간 Swift  (0) 2023.04.09
카드 뭉치 Swift  (0) 2023.04.09
대충 만든 자판 Swift  (1) 2023.04.09
덧칠하기 Swift  (1) 2023.04.09

+ Recent posts