[Programmers] level 1 - (lang: Swift)


問題の説明
KACAに加入した新規開発者NEOは「KACAアカウント開発グループ」に割り当てられ、KACAサービスに加入したユーザのID生成を担当する.「ニオ」の最初のタスクは,新たに加入したユーザがKakao IDルールに合わないIDを入力する際に,入力したIDのようにルールに合ったIDを推薦できるようにするプログラムを開発することである.
次はKakao IDのルール
IDの長さは3文字または15文字を超えてはいけません.
IDは小文字、数字、マイナス(-)、アンダースコア()、ピリオド(.)文字のみ使用できます.
しかし、句号(.)先頭と末尾では使用できませんし、連続して使用することもできません.
「ニオ」は、次の7つのステップの連続処理により、新規ユーザが入力したIDがKACO IDルールに適合しているかどうかを確認し、ルールに適合していない場合は、ルールに適合している新規IDを推奨する.
新しいプレイヤーが入力したIDがnew idであれば、
1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
     만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
예를 들어, new_id 값이 "...!@BaT#*..y.abcdefghijklm" 라면, 위 7단계를 거치고 나면 new_id는 아래와 같이 변경됩니다.
第1段階の大文字「B」および「T」は、小文字「b」および「t」に変更された....!@BaT#*..y.abcdefghijklm...!@bat#*..y.abcdefghijklm第2段階「!」、「@」、「#」、「」文字が削除されました.
`...!@bat#..y.abcdefghijklm ...bat..y.abcdefghijklm`
第3段階「…」わあ「…」“.”に変更されました....bat..y.abcdefghijklm.bat.y.abcdefghijklm第4段階IDの先頭の‘削除に成功しました..bat.y.abcdefghijklmbat.y.abcdefghijklmステップ5のアイデンティティは空の文字列ではないので、変更はありません.bat.y.abcdefghijklmbat.y.abcdefghijklmステップ6のアイデンティティ長が16文字を超えるため、上位15文字以外の文字は削除された.bat.y.abcdefghijklmbat.y.abcdefghiステップ7のアイデンティティの長さは2文字を超えないため、変更はありません.bat.y.abcdefghibat.y.abcdefghi従って、新規ユーザが入力したnew idが...!@BaT#*..y.abcdefghijklmである場合、neoのプログラムが推奨する新規IDはbat.y.abcdefghiである.
[質問]
新規プレイヤーが入力したnew idにパラメータが付与された場合、solution関数を完了し、「ニオ」が設計した7段階の処理手順後の推奨IDを返してください.
[制限]
newidは、長さが1または1000未満の文字列です.
新idは、アルファベットの大文字、アルファベットの小文字、数字、特殊な文字から構成されています.
new idに現れる可能性のある特殊文字は-.~!@#$%^&*()=+[{]}:?,<>/のみ.
[I/O例]
no	new_id	result
예1	"...!@BaT#*..y.abcdefghijklm"	"bat.y.abcdefghi"
예2	"z-+.^."	"z--"
예3	"=.="	"aaa"
예4	"123_.def"	"123_.def"
예5	"abcdefghijklmn.p"	"abcdefghijklmn"
I/O例説明
I/O例#1
問題の例.
I/O例#2
ステップ7でnew idの変化過程は以下の通りである.
手順1は変わりません.
ステップ2「z-+.^.」→ "z-.."
手順3「z-...」→ "z-."
ステップ4"z-."→ "z-"
手順5はありません.
手順6はありません.
手順7「z-」→「z--」
I/O例#3
ステップ7でnew idの変化過程は以下の通りである.
手順1は変わりません.
手順2"=.="→"."
手順3がありません.
ステップ4'."→「」(new idは空の文字列になります.)
手順5"→"a"
手順6はありません.
ステップ7「a」→「aaa」
I/O例#4
ステップ1からステップ7の間、newid(「123.def」)は変わらない.つまり、new idは最初からKakaoのIDルールに合っている.
I/O例#5
手順1は変わりません.
第2段階の変化はない.
手順3がありません.
手順4は変わりません.
手順5はありません.
手順6「abcdefghijklmn.p」→「abcdefghijklmn」→ "abcdefghijklmn"
手順7は変わりません.
========================================
私が書いたコード
import Foundation


/*
   - 아이디의 길이는 3자 이상 15자 이하여야 합니다.
   - 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
   - 단 마침표는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없다.
 
 1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
 2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
 3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
 4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
 5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
      만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
 */
func solution(_ new_id:String) -> String {
    
    let whiteList: [String] = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "." ,"_", "-"]
    
    var tempString: String = ""
    var tempString2: String = ""
    
    /* Step 1, 2 */
    for element in new_id.lowercased(){
        if whiteList.contains(String(element)) {
            tempString = tempString + String(element)
        }
    }
    
    /* Step 3*/
    for element in tempString{
        if (tempString2.last?.description ?? "") != String(element){
            tempString2 = tempString2 + String(element)
        }
    }
    if (tempString2.first?.description ?? "") == "." {
        tempString2.removeFirst()
    }
    if (tempString2.last?.description ?? "") == "." {
        tempString2.removeLast()
    }
    
    if tempString2.isEmpty {
        tempString2 = "a"
    }
    
    if tempString2.count > 15 {
        let endIndex = tempString2.index(tempString2.startIndex, offsetBy: 14)
        tempString2 = String(tempString2[...endIndex])
    }
    
    if (tempString2.last?.description ?? "") == "." {
        tempString2.removeLast()
    }
    
    while tempString2.count < 3 {
        tempString2 = tempString2 + (tempString2.last?.description ?? "")
    }

    
    return tempString2
}