한참 삽질하면서 왜 안되는지 자가진단 하려고 짠 테스트 코드... 짜 놓고도 원인을 못 찾아서 문제였지만 그래도 comprehension 연습한 셈 치자.
import random
student_number = random.randint(2, 30)
lost_list = sorted(set(random.randint(1, student_number) for x in range(random.randint(1, student_number))))
reserve_list = sorted(set(random.randint(1, student_number) for x in range(random.randint(1, student_number))))
print("n (%d)" % student_number)
print("lost (%d) =" % len(lost_list), lost_list)
print("reserve(%d) =" % len(reserve_list), reserve_list)
print(solution(student_number, lost_list, reserve_list))
for 문의 범위 안에 있는 인자를 for 문 안에서 삭제해서 오류가 남. 한참 끙끙대다 if 문에서 reserve 조건을 처리해서 해결하나 싶었는데 학생 수만큼 도느라 lost에 [3, 4]가 있고 reserve에 [4]가 있을 때 3을 처리하면서 reserve의 4를 삭제해버려서 답이 틀리는 경우가 있었다. 그걸 보완해서 바로 제출한 게 아래 코드.
def solution(n, lost, reserve):
for student in range(1, n + 1):
if student in lost and student in reserve:
lost.remove(student)
reserve.remove(student)
elif student in lost and student - 1 in reserve:
lost.remove(student)
reserve.remove(student - 1)
elif student in lost and student + 1 in reserve:
if student + 1 not in lost:
lost.remove(student)
reserve.remove(student + 1)
answer = n - len(lost)
return answer
그리고 좀더 깔끔하게 하고자 장 씨의 도움을 받은 게 아래 코드.
if를 두 번 쓴 이유는 조건이 위아래가 다르므로 구분하기 위함.
def solution(n, lost, reserve):
for student in range(1, n + 1):
if student not in lost:
continue
if student in reserve:
lost.remove(student)
reserve.remove(student)
elif student - 1 in reserve:
lost.remove(student)
reserve.remove(student - 1)
elif (student + 1 in reserve) and (student + 1 not in lost):
lost.remove(student)
reserve.remove(student + 1)
answer = n - len(lost)
return answer
for 문을 학생 수만큼 돌지 않아도 되므로 회전을 최소화하려고 lost로 돌게 만든 코드
마지막 elif 문처럼 여러 문이 중첩되어 있으면 구분하기 쉽게 괄호()를 넣어주는 게 좋다고 한다.
def solution(n, lost, reserve):
recover_count = 0
for student in lost:
if student in reserve:
recover_count += 1
reserve.remove(student)
elif student - 1 in reserve:
recover_count += 1
reserve.remove(student - 1)
elif (student + 1 in reserve) and (student + 1 not in lost):
recover_count += 1
reserve.remove(student + 1)
answer = n - (len(lost) + recover_count)
return answer
집합은 교집합, 합집합, 차집합을 구할 수 있다. 교집합은 집합 사이에 &를 넣어 표기한다. 여기서 lost와 reserve를 교집합을 빼고 집합으로 for 문에 넘겼다. 이러면 .remove를 했을 때 list에서보다 처리가 빠르다.
def solution(n, lost, reserve):
dupl = set(lost) & set(reserve)
lost, reserve = set(lost) - dupl, set(reserve) - dupl
answer = n - len(lost)
for student in lost:
if student - 1 in reserve:
reserve.remove(student - 1)
answer += 1
elif student + 1 in reserve:
reserve.remove(student + 1)
answer += 1
return answer
그 이유는 리스트에서 뭔가를 찾아서 지운다는 것은 아래처럼 for문으로 리스트 안에 있는 그 값을 찾아서 지우느라 시간이 걸리기 때문이다. 반면 사전형이나 집합은 hash이므로 바로 값을 찾아서 삭제할 수 있다. 그래서 처리 속도가 빨라지는 것이다.
_lost.remove(f)
def remove(f):
for item in _lost:
if item == f:
del _lost[f]
break
'코딩 기록장' 카테고리의 다른 글
python 3 : 프로그래머스 Level. 1 가운데 글자 가져오기 (0) | 2020.11.06 |
---|---|
python 3 : 프로그래머스 Level. 1 3진법 뒤집기 (0) | 2020.11.06 |
python 3 : 프로그래머스 Level. 1 2016년 (0) | 2020.11.06 |
python 3 : 프로그래머스 Level. 1 K번째 수 (0) | 2020.11.06 |
python 3 : 프로그래머스 Level. 1 모의고사 (0) | 2020.11.05 |