57. 모의고사 완전탐색
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.
1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...
1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.
57-1. 딕셔너리를 사용하고 길고 복잡한 방법
def supoja(pattern):
supo=(pattern*(len(answers)//5))[:len(answers)]
return supo
pattern1=[1,2,3,4,5]
pattern2=[2,1,2,3,2,4,2,5]
pattern3=[3,3,1,1,2,2,4,4,5,5]
supo1=supoja(pattern1)
supo2=supoja(pattern2)
supo3=supoja(pattern3)
def solution(answers):
count1, count2, count3=0,0,0
score={}
for i in range(len(answers)):
if supo1[i]==answers[i]: count1+=1
if supo2[i]==answers[i]: count2+=1
if supo3[i]==answers[i]: count3+=1
score[1]=count1
score[2]=count2
score[3]=count3
final_score={key:value for key, value in score.items() if value>0}
sorted_final_score=dict(sorted(final_score.items(), key=lambda x: x[1], reverse=True))
return list(sorted_final_score.keys())
supoja() 라는 함수를 정의해서 수포자1,2,3이 정답을 입력하는 패턴을 정의하고
solution() 함수에서 수포자1,2,3의 정답과 실제 정답지(answers)의 정답을 하나씩 비교해서 일치할때만 count를 1씩 증가
score={} 인 빈 딕셔너리에
score[1]=count1
score[2]=count2
score[3]=count3
score[키]=벨류 로 1,2,3의 정답수(count)를 등록
-> score={1: count1, 2:count2, 3:count3}
final_score={key:value for key, value in score.items() if value>0}
만약에 count=0으로 맞은 답이 없으면 이 사람은 제외해야 하므로 value>0만 남겼다.
sorted_final_score=dict(sorted(final_score.items(), key=lambda x: x[1], reverse=True))
딕셔너리에서 벨류 기준으로 정렬하는 법
sorted() 를 사용하고 itmes() 로 키랑 벨류를 튜플형태로 가져옴 (키, 벨류)
key=함수 sorted는 key에서 쓴 함수가 반환하는 값 기준으로 iterable을 정렬함
x[1]은 튜플로 가져온 (키,벨류) 중 벨류를 의미
만약 x[0]이면 키 기준으로 정렬된다.
57-2. 조금 더 간단한 방법
def solution(answers):
patterns = [
[1, 2, 3, 4, 5],
[2, 1, 2, 3, 2, 4, 2, 5],
[3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
]
scores = [
sum(1 for i, ans in enumerate(answers) if ans == patterns[0][i % len(patterns[0])]),
sum(1 for i, ans in enumerate(answers) if ans == patterns[1][i % len(patterns[1])]),
sum(1 for i, ans in enumerate(answers) if ans == patterns[2][i % len(patterns[2])])
]
max_score = max(scores)
return [i + 1 for i, score in enumerate(scores) if score == max_score] if max_score>0 else []
if ans == patterns[0][i % len(patterns[0])]
patterns[0] =[1, 2, 3, 4, 5] ->수포자1이 찍는 패턴
[i % len(patterns[0])]
만약 7번 문제이면 7%5=2 -> patterns[0][2]=3 수포자1은 7번문제의 답을 3으로 찍음
이 3이 ans와 같은지 확인해서 같을때만(참일때만) 1을 더하면 총점이 나옴
return [i + 1 for i, score in enumerate(scores) if score == max_score] if max_score>0 else []
최고점을 받은 사람만 리스트로 반환하되
만약 세 명 다 0점이라서 max_score=0이면 빈 리스트를 반환하게 함
60. 기사단원의 무기
숫자나라 기사단의 각 기사에게는 1번부터 number까지 번호가 지정되어 있습니다. 기사들은 무기점에서 무기를 구매하려고 합니다.
각 기사는 자신의 기사 번호의 약수 개수에 해당하는 공격력을 가진 무기를 구매하려 합니다. 단, 이웃나라와의 협약에 의해 공격력의 제한수치를 정하고, 제한수치보다 큰 공격력을 가진 무기를 구매해야 하는 기사는 협약기관에서 정한 공격력을 가지는 무기를 구매해야 합니다.
예를 들어, 15번으로 지정된 기사단원은 15의 약수가 1, 3, 5, 15로 4개 이므로, 공격력이 4인 무기를 구매합니다. 만약, 이웃나라와의 협약으로 정해진 공격력의 제한수치가 3이고 제한수치를 초과한 기사가 사용할 무기의 공격력이 2라면, 15번으로 지정된 기사단원은 무기점에서 공격력이 2인 무기를 구매합니다. 무기를 만들 때, 무기의 공격력 1당 1kg의 철이 필요합니다. 그래서 무기점에서 무기를 모두 만들기 위해 필요한 철의 무게를 미리 계산하려 합니다.
기사단원의 수를 나타내는 정수 number와 이웃나라와 협약으로 정해진 공격력의 제한수치를 나타내는 정수 limit와 제한수치를 초과한 기사가 사용할 무기의 공격력을 나타내는 정수 power가 주어졌을 때, 무기점의 주인이 무기를 모두 만들기 위해 필요한 철의 무게를 return 하는 solution 함수를 완성하시오.
def solution(number, limit, power):
numbers=[n for n in range(1,number+1)]
attack=[]
for x in numbers:
divisor_x=[num for num in numbers if x%num==0]
attack.append(len(divisor_x))
for att in attack:
attack=[power if att>limit else att for att in attack]
return sum(attack)
다른 부분은 쉬운데
divisor_x=[num for num in numbers if x%num==0]
이렇게 약수를 리스트컴프리헨션으로 만드는 부분만 기억하면 된다.
'파이썬' 카테고리의 다른 글
정규표현식 (0) | 2024.12.05 |
---|---|
re.compile (0) | 2024.12.04 |
heapq, deque (0) | 2024.12.02 |
CodeKata-3 (2) | 2024.11.21 |
CodeKata-2 (2) | 2024.11.15 |