IT 기타/Coding Test

[Coding Test] Programmers Weekly Challenge 2주차 (python)

버건디 팩토리 2021. 8. 13. 01:38
반응형

Intro

코딩테스트를 공부해야 할 것 같아서 많지는 않겠지만 내가 푼 내용을 간단하게 정리해보려고 한다.
나는 주로 c++을 활용해 여러 프로젝트를 진행했지만 python이 여러가지 기능들이 많아서
코딩 테스트에서는 확실히 유리해 보인다.
그래서 포스트들을 통해 코딩테스트 준비와 python 공부를 함께 하려고 한다!
내 코드와 다른 사람 코드 중, 배울만한 코드 두가지를 정리하여 소개하겠다.

Problem

프로그래머스 weekly 2차 시험 문제이다.

https://programmers.co.kr/learn/challenges

 

코딩테스트 연습

기초부터 차근차근, 직접 코드를 작성해 보세요.

programmers.co.kr

n x n의 2차원 배열이 주어지고, 이는 i행 학생이 j열 학생에게 준 점수를 의미한다.
이때 자신의 값이 유일한 최대 / 최소 일 시 자신을 제외하고 평균 값을 구한다.
이후 평균 값에 따라 함수를 통해 알맞은 grade를 출력한다.

자세한 내용은 위 링크의 문제 확인을 부탁한다!

 

Solution

파이프라인은 2가지 task를 필요로 한다.

1-1. 내가 유일한 최대일 때
-> 나를 제외하고 나머지 어레이를 더해서 평균 값을 구한다
1-2. 내가 유일한 최소일 때
-> 나를 제외하고 나머지 어레이를 더해 평균을 구한다.
1-3. 내가 유일한 최대/최소가 아닐 때
-> 나를 포함한 어레이를 모두 더해 평균 값을 구한다.

2. 평균 값에 따라 알맞은 grade를 출력해 answer에 더한다.

 

초기 solution은 아래와 같이 주어진다.
Scores는 n x n의 배열을 의미한다.

def solution(scores):
    answer = ''
    
    return answer


My Code

해당 코드에서 가장 중요한 점은 i 행의 학생이 j 열 학생에게 점수를 준다는 것이다.
따라서 n x n의 scores 배열에서 i 번 학생의 점수를 search하기 위해서는 scores[j][i] 에서 i를 고정시키고 j 를 변화시키며 count해야한다.

checkUniqueMax

pipeline의 1-1에 해당한다.

현재 search하는 인물의 번호 num을 받았으며 해당 사람이 자신에게 준 값이 유일한 최대 값인지를 구한다.

if max <= scores[i][num] and i != num:

위 조건문을 통해 점수 중, 만약 자신보다 같거나 높은 점수가 존재한다면 함수를 종료하고 0을 return한다.

만약 자신의 점수 중, 위 조건문이 실행이 되지 않았다면 이는 자신이 유일하게 높은 것을 의미하며 1을 return한다.

def checkUniqueMax(num, scores):
    
    max = scores[num][num]
    
    for i in range(len(scores)):
        if max <= scores[i][num] and i != num:
            return 0        # 내가 최대가 아닐 때

    return 1                # 내가 최대일 때

 

checkUniqueMin

checkUniqueMax 함수와 모든 과정이 동일하다.

def checkUniqueMin(num, scores):

    min = scores[num][num]
    
    for i in range(len(scores)):
        if min >= scores[i][num] and i != num:
            return 0        # 내가 최저가 아닐 때

    return 1                # 내가 최저일 때

 

getAvg

checkUniqueMax, checkUniqueMin 두 함수를 통해 현재 search하는 사람의 평균 점수를 구한다.

만약 return 값이 1이라면 자신을 제외하고 계산하며 점수의 개수를 나타내는 변수 count를 1 감소시킨다.

만약 return 값이 0이라면 자신을 제외시키지 않아도 되므로 열 내의 모든 값의 평균을 구한다.

def getAvg(num, scores):
    
    avg = 0
    count = len(scores)
    
    if checkUniqueMax(num, scores) or checkUniqueMin(num, scores):
        count -= 1
        for i in range(len(scores)):
            if i != num :
                avg += scores[i][num]
    else :
        for i in range(len(scores)):
            avg += scores[i][num]
        
    return avg / count


getGrade

평균 값 grade에 따라 알맞은 등급을 return한다.

def getGrade(grade):
    if grade >= 90: return 'A'
    elif grade >= 80: return 'B'
    elif grade >= 70: return 'C'
    elif grade >= 50: return 'D'
    else: return 'F'

 

main

for문을 통해 모든 i의 평균을 구해 answer string에 저장하며 이 문제를 풀 수 있다.

def solution(scores):
    answer = ''
    
    for i in range(len(scores)):
    	# i에 대한 점수 평균 구하기
        grade = getAvg(i, scores)
        answer += getGrade(grade)
    
    return answer

 

Another Code Review

나도 나름 잘 짰다고 생각했지만 다른 사람 코드 확인해보니 거의 10줄 이내로 완료한 분들이 있었다…
코드 분석을 해보니 나와는 다르게 파이썬에 대해 많은 이해를 기반으로 기본 함수를 정말 효과적으로 활용하는 것을 확인했다.

크게 4가지 기법을 활용하는 것으로 보인다.

1. Transpose

python에서는 sum, max, min 등의 함수를 통해 list 내 연산을 아주 쉽게 진행할 수 있다. 하지만 해당 문제에서는 열 기반으로 계산이 진행되므로 쉬운 계산을 위해 아래 코드로 tensor transpose를 진행한다.

scores = list(map(list, zip(*scores)))


2. Counter

쉽게 list 내 값의 개수를 count하는 별도의 방법이 존재했었다!

import counter를 통해 개수를 계산한다...

이것 또한 알아두면 좋을 것 같다.

from collections import Counter

def solution(scores):   
    if Counter(score)[score[idx]] == 1

3. delete

만약 list 내에서 자신을 삭제하고 싶다면 그 방법은 정말 단순했다.

단순히 list에서 원하는 index를 입력해주면 끝이다.

간단하지만 해당 기법은 추후 다양하게 활용할 수 있을 것 같다.

del score[idx]


4. Sum

마지막으로 평균 계산이 for문이 아닌 sum을 통해 쉽게 계산할 수 있다.

grade = sum(score) / length

 

반응형