문제
https://school.programmers.co.kr/learn/courses/30/lessons/72412
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
풀이
지원자 정보를 저장하기 위해 infomap을 만들었다. defaultdict로 선언하여 value에 해당하는 값을 리스트로 초기화하였다.
infomap의 key는 info로 만드는데, 하나의 info는 총 16가지 경우의 수로 나눠진다.
16가지의 경우의 수는 중복 조합을 구하는 함수인 product를 통해 구한다. itertools.product((True, False), repeat=4))를 선언하면,
[(True, True, True, True), (True, True, True, False), (True, True, False, True), (True, True, False, False), (True, False, True, True), (True, False, True, False), (True, False, False, True), (True, False, False, False), (False, True, True, True), (False, True, True, False), (False, True, False, True), (False, True, False, False), (False, False, True, True), (False, False, True, False), (False, False, False, True), (False, False, False, False)]
와 같은 배열이 만들어지게 되고, False인 곳에 '-'가 들어간다고 생각하면 된다.
이렇게 key를 만들었으면 infomap[key]에 info의 점수를 value로 저장한다. 지원자들의 info를 보다가 정보는 동일하지만 점수가 다르다면, 정보를 key로 하는 곳에 점수가 추가되는 방식이다. ex) 'javabackend--': [150, 80]
infomap의 value의 원소들을 오름차순으로 정렬한다. 그러면 infomap의 세팅이 완료된다.
infomap을 다 만들었으면, query를 돌아야 한다.
query의 구성요소인 q는 조건과 'and'로 구성되어 있으므로 and를 제거해주어야 한다. and를 제외한 나머지 것들로 infomap 검색에 사용할 key를 만든다.
q에 존재하는 점수보다 같거나 큰 지원자가 몇 명인지 구해야 하므로 q의 점수를 타겟으로 하여 infomap[key] 안에서 이진 탐색을 한다.
이진 탐색을 할 때에는 직접 구현해도 되지만, 파이썬의 자랑인 bisect 라이브러리를 사용한다.
bisect 라이브러리에는 bisect_left와 bisect_right가 있다. 여기서는 bisect_left를 사용하는 것이 바람직하다.
인덱스를 구하였으면 infomap[key]의 길이에 인덱스를 빼서 인덱스 q의 점수보다 같거나 큰 지원자의 수를 구한다.
**참고**
1. 해당 값이 리스트에 있을 때
bisect_left : 해당 index 반환
bisect_right : 해당 index+1 반환
2. 해당 값이 리스트에 없을 때
bisect_left : 리스트에 해당값을 넣는다고 가정하였을 때, 오름차순으로 존재해야 할 index 반환
bisect_right : 리스트에 해당값을 넣는다고 가정하였을 때, 오름차순으로 존재해야 할 index 반환
import bisect, itertools, collections
def solution(info, query):
infomap = collections.defaultdict(list)
binarys = list(itertools.product((True, False), repeat=4))
for inf in info:
inf = inf.split()
for binary in binarys:
key = ''.join([inf[i] if binary[i] else '-' for i in range(4)])
infomap[key].append(int(inf[4]))
for k in infomap.keys():
infomap[k].sort()
answer = []
for q in query:
a, _, b, _, c, _, d, score = q.split()
key = ''.join([a, b, c, d])
idx = bisect.bisect_left(infomap[key], int(score))
answer.append(len(infomap[key]) - idx)
return answer
총평
정확도는 다 맞춰도 효율성이 도저히 통과되지 않았다.
그래서 그냥 '질문하기'에 있는 풀이를 참고하였다. 이 풀이를 온전히 내 것을 만들려면 시간이 좀 걸릴 것 같다.
'알고리즘 > 카카오 EASY' 카테고리의 다른 글
프렌즈4블록 (Level 2) (0) | 2022.07.08 |
---|---|
후보키 (Level 2) (0) | 2022.07.07 |
튜플 (Level 2) (0) | 2022.07.04 |
수식 최대화 (Level 2) (0) | 2022.07.04 |
거리두기 확인하기 (Level 2) (0) | 2022.06.30 |