⚙️ 알고리즘/프로그래머스

[Swift] 프로그래머스 - [1차] 비밀지도

dev_zoe 2023. 3. 19. 16:19
반응형

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/17681

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

내 풀이

- 엄청 문제 그대로 날것으로 풀었다.. 허허

func solution(_ n:Int, _ arr1:[Int], _ arr2:[Int]) -> [String] {
    var arr1 = arr1.map { String($0, radix: 2)} //2진수로 변환
    var arr2 = arr2.map { String($0, radix: 2)}

    var answer: [String] = []
    
    for i in 0..<n {
        var arr1_temp = arr1[i].map { String($0) }
        var arr2_temp = arr2[i].map { String($0) }
        var element = ""
        
        /*
        정수 배열의 각 원소 x를 이진수로 변환했을 때의 길이는 n 이하이다. 즉, 0 ≦ x ≦ 2n - 1을 만족한다.
        라는 조건으로 인해, 만약 이진수로 변환한 길이가 n보다 작다면, 그 앞을 0으로 채워줘야한다.
        */
        
        if arr1[i].count < n { 
            for j in 0..<n-arr1_temp.count {
                arr1_temp.insert("0", at:j)
            }
        }
        if arr2[i].count < n {
            for j in 0..<n-arr2_temp.count {
                arr2_temp.insert("0", at:j)
            }
        }
        
        /*
        더한게 0이라면 공백을, 아니라면 #을 더하도록 하여 배열에 넣어주었다.
        */
        for j in 0..<n {
            if Int(arr1_temp[j])! + Int(arr2_temp[j])! == 0 {
                element += " "
            }
            else {
                element += "#"
            }
        }
        answer.append(element)
    }
    return answer
}

 

다른 분 풀이

func solution(_ n:Int, _ arr1:[Int], _ arr2:[Int]) -> [String] {

    return (0..<n).map {
        let binary = String(arr1[$0] | arr2[$0], radix: 2)
        let padded = String(repeating: "0", count: n - binary.count) + binary
        return padded.reduce("") { $0 + ($1 == "0" ? " " : "#") }
    }
}

 

1) let binary = String(arr1[$0] | arr2[$0], radix: 2)

- | 연산은 비트 연산 or 을 가리키고, int값을 들어오면 2진수로 변환하여 or 연산자를 수행한다.

or 연산을 수행하면 둘 중 하나라도 1이면 1으로 변환해주게된다.

- String(Int, radix: 2)는 정수를 2진수 문자열로 변환해준다. (*반대로 2진수를 정수로 바꿔주는 연산은 Int(String, radix: 2)!

위 이미지에서 연산을 살펴보면, 둘중 하나라도 1이면 퍼즐이 1(#)로 채워진다.

 

2) let padded = String(repeating: "0", count: n - binary.count) + binary

- 내 코드에서는 반복문을 돌려서 앞에 0이 모자란 개수만큼 (배열 안의 모든 수의 이진수 변환의 길이는 항상 n이하이므로, 모든 수의 이진수 변환의 길이를 n으로 채워줘야한다.) 0을 insert 해주었다면

- 이 코드는 0이 모자란 개수만큼 0이 반복되는 문자열을 만들고, 그 뒤에 2진수 문자열을 추가하는 내용이다.

- 그리고 내 코드는 먼저 2진수로 변환한 다음에 서로 계산하고, 해당 코드는 먼저 계산한다음에 2진수로 변환하게 되는데, 

앞에 부족한 개수만큼 0을 먼저 채운다음에 계산을 한다 해도 0끼리 더하면 0이기 때문에, 비트 연산을 하고 앞을 0으로 채워도 같은 결과일 것이다. (이진수의 길이가 n이 아니라는 것은 맨 앞이 1이 아니라는 의미이므로, 순서는 상관 없음)

 

3) (0..<n).map { ... return padded.reduce("") { $0 + ($1 == "0" ? " " : "#") } }

- 이부분이 인상 깊었는데, 배열의 길이는 곧 n이므로 길이가 n인 배열을 조건에 의해 문자열로 매핑을 하겠다 라는 코드가 인상깊었다.

- 특히 reduce를 사용해서 문자열을 더한부분은 이후에 또 많이 쓰일것같아서 따로 기록해놨다.

 

 

반응형