[파이썬] 프로그래머스 LV1 모의고사

청수동햄주먹·2023년 2월 7일
0

파이썬코딩테스트

목록 보기
13/35

프로그래머스 모의고사

첫시도

def answerCheck(student,answers):
    count = 0
    size = len(answers)
    chunk = len(student)
    sheet = student * (size//chunk) + student[:size%chunk]
    for x,y in zip(answers, sheet):
        if x == y:
            count += 1
    return count

def solution(answers):
    no1 = [1,2,3,4,5]
    no2 = [2, 1, 2, 3, 2, 4, 2, 5]
    no3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    rank = []
    rank.append([1,answerCheck(no1,answers)])
    rank.append([2,answerCheck(no2,answers)])
    rank.append([3,answerCheck(no3,answers)])
    rank.sort(key=lambda x: x[1],reverse=True)
    if(rank[0][1] == rank[2][1]) : return [x[0] for x in rank]
    elif(rank[0][1] == rank[1][1]) : return [rank[0][0],rank[1][0]]
    return [rank[0][0]]

answerCheck([학생의 답], [정답지])

  1. 정답지의 길이로 학생의 답 리스트를 조절하여 길이를 똑같이 맞춘다
  2. 정답지와 리스트를 zip으로 묶고 같은 값이 있을 때만 카운트를 센다
  3. 정답수를 리턴

solution

  1. 학생 1,2,3의 찍기 패턴을 answerCheck에 보내 정답수를 얻는다
  2. rank 리스트에 (학생번호, 맞은 갯수)의 튜플로 넣는다
  3. 튜플의 두번째 값을 key로 내리막순 정렬을 해준다.
  4. 첫번째 수와 세번째 수가 같으면 세 학생 모두 점수가 같다는 뜻으로 튜플 첫번째 값 세개 리턴
  5. 첫번째 수와 두번째 수가 같으면 두 학생의 점수가 같다는 뜻으로 튜플 첫번째 값 두개 리턴
  6. 4,5에서 걸러진 경우 한명만 1등인 경우로 튜플 첫번째 값 한개 리턴

다른 사람의 풀이

def solution(answers):
    x1 = [1,2,3,4,5] 
    x2 = [2,1,2,3,2,4,2,5] 
    x3 = [3,3,1,1,2,2,4,4,5,5]
    cn_1, cn_2, cn_3 = 0, 0, 0
    for i in range(len(answers)):
        if answers[i] == x1[i%len(x1)]:
            cn_1 += 1
        if answers[i] == x2[i%len(x2)]:
            cn_2 += 1
        if answers[i] == x3[i%len(x3)]:
            cn_3 += 1
    max_ = max(cn_1,cn_2,cn_3)
    answer = []
    if max_ == cn_1:
        answer.append(1)
    if max_ == cn_2:
        answer.append(2)
    if max_ == cn_3:
        answer.append(3)
    return answer

흥미로운 풀이였다 나는 이렇게 생각해본적이 없어서
나는 리스트의 길이를 answers만큼 늘려서 했다면 이 풀이는 나머지값으로 늘려줄 필요없이 for-loop을 answers만큼 돌려줄수 있다. 다만 이부분이 시간이 좀 걸릴 것같다. 왜냐면 계속 세 리스트를 순회하며 n번째의 값에 접근하고 있기 때문에..

또 max 값을 정해주고 max 값만 같은 경우만 append하는 것도 좋은 접근인것 같다. 또 학생 번호 순으로 더해주기 때문에 튜플을 이용할 필요도, 소팅할 필요도 없다.

보완 수정

def answerCheck(student,answers):
    count = 0
    for i in range(len(answers)):
        if answers[i] == student[i%len(student)]:
            count += 1
    return count

def solution(answers):
    x1 = [1,2,3,4,5] 
    x2 = [2,1,2,3,2,4,2,5] 
    x3 = [3,3,1,1,2,2,4,4,5,5]
    cn_1 = answerCheck(x1,answers)
    cn_2 = answerCheck(x2,answers)
    cn_3 = answerCheck(x3,answers)
            
    max_ = max(cn_1,cn_2,cn_3)
    answer = []
    if max_ == cn_1:
        answer.append(1)
    if max_ == cn_2:
        answer.append(2)
    if max_ == cn_3:
        answer.append(3)
    return answer

위의 풀이를 리스트를 왔다갔다 할 필요 없이 한번에 한 학생의 답만 계산해서 할 수 있도록 해보았다. 내가 한 방법과 비교도 할겸.
스트링을 늘리는 것 vs 나머지값를 계속 계산해서 스트링을 늘리지 않는 것
그 결과는..

성능

첫 시도다른 사람의 풀이다른 사람의 풀이 보완
테스트 1 〉통과 (0.01ms, 10.3MB)통과 (0.01ms, 10.3MB)통과 (0.01ms, 10.3MB)
테스트 2 〉통과 (0.01ms, 10.2MB)통과 (0.01ms, 9.99MB)통과 (0.01ms, 10.2MB)
테스트 3 〉통과 (0.01ms, 10.3MB)통과 (0.01ms, 10.2MB)통과 (0.01ms, 10.2MB)
테스트 4 〉통과 (0.01ms, 10.3MB)통과 (0.01ms, 10.2MB)통과 (0.01ms, 10.2MB)
테스트 5 〉통과 (0.03ms, 10.2MB)통과 (0.04ms, 10.3MB)통과 (0.02ms, 10.2MB)
테스트 6 〉통과 (0.02ms, 10.2MB)통과 (0.03ms, 10.2MB)통과 (0.03ms, 10.3MB)
테스트 7 〉통과 (0.70ms, 10.3MB)통과 (2.01ms, 10.2MB)통과 (1.88ms, 10.1MB)
테스트 8 〉통과 (0.29ms, 10.3MB)통과 (0.99ms, 10.2MB)통과 (0.54ms, 10.2MB)
테스트 9 〉통과 (1.36ms, 10.2MB)통과 (2.96ms, 10.1MB)통과 (3.03ms, 10.3MB)
테스트 10 〉통과 (0.62ms, 10.4MB)통과 (2.50ms, 10.2MB)통과 (1.42ms, 10.2MB)
테스트 11 〉통과 (1.47ms, 10.4MB)통과 (3.00ms, 10.2MB)통과 (3.30ms, 10.3MB)
테스트 12 〉통과 (1.34ms, 10.4MB)통과 (4.94ms, 10.2MB)통과 (2.93ms, 10.3MB)
테스트 13 〉통과 (0.08ms, 10.4MB)통과 (0.29ms, 10.2MB)통과 (0.18ms, 10.2MB)
테스트 14 〉통과 (1.34ms, 10.3MB)통과 (4.47ms, 10.2MB)통과 (3.29ms, 10.3MB)
  • 스트링을 늘려줘서 값 비교만 하게 하는 것이 스트링을 늘리지 않고 계속 나머지계산을 하는 풀이보다 성능이 좋게 나왔다.
  • 보완한 방식이 원래의 방식보다 시간을 더 단축할 수 있었다
profile
코딩과 사별까지

0개의 댓글