본문 바로가기
코딩 테스트/프로그래머스

[프로그래머스] (Swift) 비밀지도 (2018 카카오 1차) - Lv.1

by Dev.Andy 2023. 5. 9.

머리말

문제 링크

이번 문제는 설명이 매우 길어서 한번에 캡처가 힘들어 링크만 첨부했다.

코딩테스트 연습 - [1차] 비밀지도 | 프로그래머스 스쿨

풀이

처음에는 Swift에서 제곱 메서드를 찾지 못해 직접 구현했다.

  1. 우선 정해진 길이의 이진법으로 변환하는 함수를 구현했다. 이진수의 길이와 정해진 길이를 고려해 "0"을 더할지 말지를 정했다.
  2. 이제는 매개변수로 주어진 배열을 1번의 함수를 이용해 이진수로 변환한다.
  3. 2번으로 구한 이진수로 서로 겹치는 과정이 필요하다.
  4. 이진수 문자열을 다시 쪼개어 각 자리를 더하여 크기에 따라 서로 다른 문자열로 변환하고 이를 연결하는 과정을 구현했다.

코드

func solution(_ n:Int, _ arr1:[Int], _ arr2:[Int]) -> [String] {
    // 반환값 초기화
    var answer: [String] = []

    // 주어진 배열의 각 요소를 정해진 길이의 이진수로 모두 변환
    var map1 = arr1.map{ decimalToBinary(n, $0) } // ["01001", "10100", "11100", "10010", "01011"]
    var map2 = arr2.map{ decimalToBinary(n, $0) } // ["11110", "00001", "10101", "10001", "11100"]

    // 각 배열의 이진수를 서로 겹치는 과정
    let indexRange = map1.count - 1
    for i in 0...indexRange {
        // 이진수의 각 자리를 정수로 변환한 배열로 분할
        let integerRow1 = map1[i].map { Int(String($0))! } // [0, 1, 0, 0, 1]
        let integerRow2 = map2[i].map { Int(String($0))! } // [1, 1, 1, 1, 0]
        
        // 각 자리를 더해서 0보다 크면 "#"을, 그렇지 않으면 " "을 연결
        var overlap = ""
        for j in 0..<n {
            (integerRow1[j] + integerRow2[j] > 0) ? (overlap += "#") : (overlap += " ")
        }
        
        // 총 연결된 한 줄을 결괏값에 더하고, 빈 문자열로 재할당
        answer.append(overlap)
        overlap = ""
    }
    
    return answer
}

// 정해진 길이로, 십진법을 이진법으로 변환하는 함수 정의
func decimalToBinary(_ len: Int, _ digit: Int) -> String {
    var binary = String(digit, radix: 2)
    
    // 정해진 길이와 이진수 길이의 차이를 할당
    let offset = len - binary.count
    if offset == 0 {
        return binary
    }
    
    // 차이만큼 앞에 "0"을 추가
    for _ in 1...offset {
        binary = "0" + binary
    }
    
    return binary
}

// 제곱 함수 정의
func power(_ n: Int, _ p: Int) -> Int {
    var result = 1
    for _ in 1...p {
        result *= n
    }
    return result
}

 

꼬리말

문제 후기

  • 대기업 문제이라서 그런지 단순한 구현 문제가 아닌 실제 문제 상황처럼 추상적인 형식으로 문제가 길게 주어졌다.
  • 따라서 긴 문장에 대한 문해력도 요구가 되어서 이에 대해 익숙해지는 것이 필요해 보인다.
  • 겉으로 보면 문자열과 이진법 변환을 몇 번 하면 되는 문자이지만, 이를 정말 자유자재로 할 수 있어야 겨우 풀리는 문제였다. 쉽게 봐서는 안되는 난이도이다.

보완점

다른 사람의 풀이 - [1차] 비밀지도

  • 다른 사람들의 문제 풀이를 보니 Swift 클로저나, 인스턴스 메서드(reduce), 인수 레이블(repeating, count) 등을 이용해 코드의 길이를 획기적으로 줄인 걸 보았다.
  • 또는 UInt로 8진법/16진법을 이용하거나, >> 연산 기호(아마 bitwise 기호인 것 같다)를 이용한 풀이도 있었다.
  • 되짚어 보니 내가 reduce 메서드를 제대로 활용한 적이 거의 없다. Playground로 이에 대해 몇 번 연습을 해 봐야겠다.
  • String 이니셜라이저에 "버티컬 바(|)"가 들어간 걸 본 건 처음이었는데 이것의 활용 방법 또한 알아 봐야겠다.

댓글