학습 기록/코딩 테스트 기초 이론

파이썬 코딩테스트 준비: 배열 기초 문제 풀어보기 (1)

romi__ 2024. 9. 14. 18:30

/date 24.09.14.

 

 
코딩 테스트 합격자 되기: 파이썬 편
신입 사원 코딩 테스트를 준비하고 계신가요? 코딩 테스트는 문제만 열심히 푼다고 통과할 수 없습니다. 시험은 전략적으로 준비해야 합니다. 《코딩 테스트 합격자 되기》(파이썬 편)은 신입 사원 코딩 테스트 합격에 딱 맞는 빈출문제를 선정하고 풀이하기 위해 저자와 전문 교강사진이 오랜 시간을 들여 고민해 만들었습니다. 문제의 맥을 관통하는 자료구조와 알고리즘, 시간 복잡도 분석까지 완벽하게 풀이했죠! 모든 내용은 친절한 설명에 풍부한 그림을 더해 말끔하게 이해할 수 있도록 했습니다. 코딩 테스트뿐만 아니라 그 다음에 있을 면접까지 대비할 수 있을 것입니다. 이 책과 함께라면 합격은 여러분의 것입니다.
저자
박경록
출판
골든래빗(주)
출판일
2023.11.15

 

'코딩 테스트 합격자 되기: 파이썬 편'을 읽으면서 파이썬을 이용한 코딩 테스트에 도전해보려고 합니다. 기초적인 이론에 대해 공부한 내용을 여기에 기록하고, 실제로 코딩 테스트 문제를 풀며 공부한 내용은 또 다른 카테고리에 기록해 둘 예정입니다. 그러니 틀린 내용이 있다면 댓글로 알려주세요. 코테 고수가 되는 그날까지 화이팅...!

 

 

📌

오늘은 배열을 활용할 수 있는 코딩 테스트 문제를 몇 가지 풀어보려고 합니다. 안타깝게도 저는 파이썬의 아주 기초적인 문법정도만 숙지하고 있는 정도이기 때문에... 책에 나와 있는 모범 답안과 다른 사람들의 풀이, 챗GPT 선생님의 친절한 설명을 적극 활용하면서 공부해 볼 생각입니다. 언젠가는 제 힘으로 코테를 풀 수 있는 날이 오겠죠? 그때까지 화이탱...

 

 

 

📌 1) 두 개 뽑아서 더하기

https://school.programmers.co.kr/learn/courses/30/lessons/68644

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

def solution(numbers):
    answer = []
    for i in range(len(numbers)):
        for j in range(i+1, len(numbers)):
            answer.append(numbers[i] + numbers[j])
    answer = sorted(set(answer))
    return answer

 

제가 작성한 답안입니다. 한 줄씩 (chatGPT 선생님과) 살펴보겠습니다.

 

answers = []

 

빈 배열을 하나 만듭니다. 두 개의 숫자를 더한 결과를 저장할 용도입니다.

 

for i in range(len(numbers)):
    for j in range(i+1, len(numbers)):
        answer.append(numbers[i] + numbers[j])

 

이중 반복문을 활용했습니다. 이해하기 쉽게 작성해 보면,

i로는 numbers의 리스트 길이까지(= 0 ~ (리스트 길이 -1)):

     j가 i+1부터 리스트 길이까지:

          answer에 numbers[i]와 numbers[j]를 더한 값을 추가

가 되겠습니다.

 

answer = sorted(set(answer))
return answer

 

결과를 저장할 용도로 만든 answer 배열에 sorted(set(answer))를 넣습니다. set은 중복값을 제거해 주고(만들 수 있는 모든 수를 넣으라고 언급하였으니 중복값을 제거해 주는 것이 맞습니다), sorted는 파라미터를 따로 지정하지 않을 경우 오름차순으로 정렬해 줍니다.

answer 배열을 return합니다.

 

 

📌 2) 모의고사

https://school.programmers.co.kr/learn/courses/30/lessons/42840

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

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 = [0] * 3
    for i, answer in enumerate(answers):
        for j, pattern in enumerate(patterns):
            if answer == pattern[i % len(pattern)]:
                scores[j] += 1
    max_score = max(scores)
    answer = []
    for i, score in enumerate(scores):
        if score == max_score:
            answer.append(i+1)
    return answer

 

제가 작성한 답안입니다. 마찬가지로 한 줄씩 살펴보겠습니다.

 

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 = [0] * 3

 

점수를 저장해 줄 배열을 생성합니다. 처음엔 세 명 모두 0점에서 시작해서, 문제를 맞힐 때마다 1점씩 더해줍니다.

 

for i, answer in enumerate(answers):
    for j, pattern in enumerate(patterns):
        if answer == pattern[i % len(pattern)]:
            scores[j] += 1

 

enumerate는 파이썬에서 순회 가능한 객체를 반복할 때, 인덱스와 데이터를 함께 제공합니다. 위의 코드를 뜯어보면,

 

i(=문제번호)와 answer(=문제의 답)를 answers(=제공되는 답안)에서 순회합니다:

     j(=수포자 번호)와 pattern(=해당 수포자의 정답 패턴)을 patterns(=수포자 1,2,3의 패턴들)에서 순회합니다:

          만약 문제의 답이 수포자의 정답 패턴과 일치한다면(그리고 패턴은 계속해서 반복됩니다),

          수포자 j의 점수를 1점 올립니다.

 

이렇게 해석해 볼 수 있습니다.

 

max_score = max(scores)

 

scores 배열에서 가장 큰 값을 찾아 max_score에 저장합니다. 중복이 있을 수 있음에 주의하고, 그 경우 수포자 번호를 오름차순으로 정렬해야 합니다.

 

answer = []
for i, score in enumerate(scores):
    if score == max_score:
        answer.append(i+1)
return answer

 

제출하고자 하는 정답을 담을 answer 배열을 생성합니다.

 

i(=수포자 번호-1), score(=수포자의 점수)를 scores라는 배열에서 순회합니다:

     만약 score(=수포자의 점수)가 max_score(=scores 배열에서 가장 큰 값)과 같다면:

          answer 배열에 (문제에서 공식적으로 주어졌던 = i + 1) 수포자 번호를 추가합니다.

 

answer 배열을 반환합니다.

 

 

 

📌 2) 행렬의 곱셈

https://school.programmers.co.kr/learn/courses/30/lessons/12949

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

def solution(arr1, arr2):
    r1, c1 = len(arr1), len(arr1[0])
    r2, c2 = len(arr2), len(arr2[0])
    ret = [[0] * c2 for _ in range(r1)]
    for i in range(r1):
        for j in range(c2):
            for k in range(c1):
                ret[i][j] += arr1[i][k] * arr2[k][j]
    return ret

 

제가 작성한 코드는 다음과 같습니다. 한 줄씩 뜯어보겠습니다.

 

r1, c1 = len(arr1), len(arr1[0])
r2, c2 = len(arr2), len(arr2[0])

 

r1과 c1은 각각 arr1의 행 개수와 열 개수를 의미합니다. 마찬가지로 r2, c2는 각각 arr2의 행 개수와 열 개수를 의미합니다. 

 

ret = [[0] * c2 for _ in range(r1)]

 

결과를 저장할 ret 행렬을 초기화합니다. arr1의 행 개수와 arr2의 열 개수를 기준으로 크기가 정해지고, 그 크기만큼 [0]이 채워집니다. 

 

for i in range(r1):
    for j in range(c2):
        for k in range(c1):
            ret[i][j] += arr1[i][k] * arr2[k][j]

 

i는 arr1의 각 행을 순회합니다:

     j는 arr2의 각 열을 순회합니다:

          k는 arr1의 각 열을 순회하면서:

                arr1의 i번째 행과 arr2의 j번째 열을 곱해 ret[i][j]에 더합니다.

 

ret을 반환하여 마무리합니다.

 

 

 

/*사족입니다*/

  • 아직 뭣도 모르는 만큼 한 줄씩 뜯어보면서 찾아보고 공부하는 것이 도움이 많이 된다. 언제 다 공부해서 도움 없이 코딩테스트에 응시하나 싶어 아찔하긴 하지만 풍화작용...믿는다ㅏ.... 
  • enumerate는 오늘 처음 봤다! 이런 기능도 있구나. 생각해 보니까 자바스크립트로 백엔드 공부할 때도 비슷한 코드를 본 것 같다. 물론 이름은 다르지만.
  • 행렬...ㅋㅋㅋㅋㅋ 내 교육과정엔 없었는데 수학 선생님의 강경 권유로 공부했던 것이 이렇게 돌아오는구나. 쪼끔(많이는 절대 아님) 기억나는 것이 뿌듯하다.