본문 바로가기
알고리즘/프로그래머스

프로그래머스: 해시 - 완주하지 못한 선수

by 패쓰킴 2024. 11. 12.
728x90

https://school.programmers.co.kr/learn/courses/30/lessons/42576?language=javascript

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

이 문제도 swift를 지원하지 않지만 풀어봄

 

풀이

주어진 참가자 배열과 완주자 배열을 비교해서 완주하지 못한 한명을 반환하면 되는 문제

처음엔 단순히 배열끼리 for, if 문으로 비교하면 된다고 생각했는데

해시 문제 이므로 해시를 사용해서 풀 수 있는 방법을 고민해보았다.

참가자를 키로 두고 모두 false 값으로 설정한 딕셔너리를 만들어서 사용하는 것부터 생각을 해봤는데 도저히 동명이인일 경우 처리가 되지 않았다.

한 30분 고민해보다가 GPT에게 물어보니, Bool값 대신 Int를 사용해서 푸는 방식을 알려줬다.

[String: Int] 딕셔너리를 만들고

완주자에 해당하는 키에 1씩 더해준 후

0값인 키는 삭제하여

마지막에 남는 완주하지 못한 선수를 거른다.

테스트 케이스 ->

 

  • 기본 케이스
  • 동명이인 케이스
  • 모든 참가자가 완주한 경우
  • 단일 참가자가 완주하지 못한 경우
  • 대규모 참가자 목록에서 한 명만 완주하지 못한 경우

 

var map = [String: Int]()

for name in participant {
  if let _ = map[name] {
    map[name]! += 1
  } else {
    map[name] = 1
}

for name in completion {
  if let _ = map[name] {
    map[name]! -= 1
    
    if map[name] ==0 {
      map.removeValue(forKey: name)
    }
  }
}

for name in map {
  print(name.key)
}

위와 같이 풀어도 모든 테스트 케이스에 통과 되지만, 더 간결하게 바꿔 볼 수 있단다 GPT가..

var map = [String: Int]()

for name in participant {
  map[name, default: 0] += 1
}

for name in completion {
  map[name]! -= 1
  
  if map[name] == 0 {
    map.removeValue(forKey: name)
  }
}

if let incomplete = map.keys.first {
  print(incomplete)
}
if let _ = map[name] 부분은 값을 확인하면서 바로 접근할 수 있으므로, if let을 생략하고, 마지막 부분에서 map.keys.first를 사용하면 남은 키를 가져와 간단하게 출력할 수 있다

 

이 코드에서 'map[name, default: 0]' 이 방식은 처음 알게 되었다 기존의 배열을 돌면서 값이 있는지 없는지 확인 하지 않고 바로 없으면 default로 0을 넣고 아니면 1씩 증가 시킨다.

4줄이었던 코드가 한줄이 되었다. 앞으로도 유용히 사용할 수 있을 것 같다.

728x90

댓글