반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

프로그래머스) 공원 산책 본문

오뚝이 개발자/알고리즘

프로그래머스) 공원 산책

rriver2 2023. 5. 15. 15:39
반응형

 공원 산책 문제 

 

프로그래머스

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

programmers.co.kr

 1차 실패 : 문제 이해 X 

문제 중 다음과 같은 내용이 있었는데, 🌟 표시한 내용을 내가 대충 읽고 넘긴 탓에 고생을 했다. 단순하게 [0,0] 에서 ["E 2"]가 나오면 [0,2] 부분의 영역만 공원 밖으로 나가는지, 장애물인지 확인을 해서 코드를 짰었는데, 예제 2번이 틀려서 입출력 설명을 읽어보니 문제에서 설명하는 바를 놓쳤음을 알게 되었다. 문제를 꼼꼼히 읽자.

예를 들어 "E 5"는 로봇 강아지가 현재 위치에서 동쪽으로 5칸 이동했다는 의미입니다. 로봇 강아지는 명령을 수행하기 전에 다음 두 가지를 먼저 확인합니다.

- 주어진 방향으로 이동할 때 공원을 벗어나는지 확인합니다.
- 🌟 주어진 방향으로 이동 중 장애물을 만나는지 확인합니다.

 알게 된 것 

1️⃣ firstIndex의 종류 2가지 

🌟 firstIndex(of:)

첫번째는 firstIndex(of:)로, 특정 값과 일치하는 첫 번째 요소의 인덱스를 찾는다. 이때 of는 찾고자 하는 값을 지정하는 역할을 한다.

아래의 예제에서 students 배열의 값 중 Maxime과 첫번째로 같은 Index를 반환한다.

var students = ["Ben", "Ivy", "Jordell", "Maxime"]
if let i = students.firstIndex(of: "Maxime") {
    students[i] = "Max"
}
print(students)
// Prints "["Ben", "Ivy", "Jordell", "Max"]"

🌟 firstIndex(where:)

firstIndex(where:)는 조건을 만족하는 첫 번째 요소의 인덱스를 찾는다. 여기서 where는 클로저를 받아 조건을 지정하는 역할을 한다. 

아래 예시에서는 numbers의 값중 처음으로 0보다 작은 요소의 index를 반환한다.

let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
if let firstNegative = numbers.first(where: { $0 < 0 }) {
    print("The first negative number is \(firstNegative).")
}
// Prints "The first negative number is -2."

2️⃣ split

알고 있었는데 오랜만에 쓰려니까 정확하게 기억이 나지 않았다. "E 3"을 ["E", "3"]으로 반환해준다.

let direction_width = route.split(separator: " ")

split에 대해서 더 알아보니까, 더 많은 매개변수가 있었다.

🌟 separator

기본적으로 알고 있는 separator은 해당 string의 나누는 기준을 정할 수 있다.

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

🌟 maxSplits

maxSplits은 최대 분리 횟수를 지정해서 최대로 분리할 요소의 개수를 제한할 수 있다.

아래의 예시 같은 경우에는 maxSplits를 1로 지정했기 때문에, 첫번째 1개의 요소만 " "을 기준으로 분리가 되고, 2를 입력할 시 앞에서 2번재 요소가 분리된다.

print(line.split(separator: " ", maxSplits: 1))
// Prints "["BLANCHE:", "  I don\'t want realism. I want magic!"]"

print(line.split(separator: " ", maxSplits: 2))
// Prints "["BLANCHE:", "I", "don\'t want realism. I want magic!"]"

🌟 omittingEmptySubsequences

omittingEmptySubsequences는 빈 요소를 제외할지 여부를 결정한다. 기본값인 true은 연속된 구분자 사이의 빈 문자열 요소가 제외되고 false로 설정할 시에 아래와 같이 ""도 요소로 추가가 된다.

print(line.split(separator: " ", omittingEmptySubsequences: false))
// Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

 

 결과 

import Foundation

func solution(_ park:[String], _ routes:[String]) -> [Int] {
    let parkList = park.map { $0.map {$0} }
    var now: [Int] = []
    if let rowIndex = parkList.firstIndex(where: { $0.contains("S")}) {
        if let colIndex = parkList[rowIndex].firstIndex(of: "S") {
            now = [rowIndex, colIndex]
        }
    }
    for route in routes {
        let direction_width = route.split(separator: " ")
        let width = Int(direction_width[1])!
        var next: [Int] = now
        var change_now = true
        for _ in 0..<width {
            switch direction_width[0] {
                case "E":
                    next = [next[0], next[1]+1]
                case "N":
                    next = [next[0]-1, next[1]]
                case "W":
                    next = [next[0], next[1]-1]
                case "S":
                    next = [next[0]+1, next[1]]
                default:
                    next = [-1,-1]
            }
            if (next[0] < 0) || (next[1] < 0) || next[0] >= parkList.count || next[1] >= parkList[0].count || parkList[next[0]][next[1]] == "X" {
                change_now = false
                break
            }
        }
        if change_now {
            now = next
        }
    }
    return now
}

 코드 개선 

코드가 지저분한 것 같아서 걱정을 했는데 다른 사람들 풀이를 보니까 나른 잘 짠 것 같다는 생각을 해서 뿌듯했다.

하지만 아쉬운 점도 존재했다.

아래와 같이 코드를 짰으면 더 나았을 것 같다는 생각을 했고,

next = [next[0], next[1]+1]
▶️ next[1] += 1

아래에서 처럼 옵셔널이 나왔을 때 어떻게 처리하는 게 좋을지 고민이 된다는 점이었다. 이번 코드 같은 경우에는 아래와 같이 nil인 경우엔 0을 대입해도 괜찮을 것 같지만, 이렇게 케바케로 관리하는 게 맞나 하는 의문이 들었다. 다른 사람들은 어떻게 하지..? 💬

let width = Int(direction_width[1])!
▶️ let width = Int(direction_width[1]) ?? 0
반응형
Comments