250x250
반응형
05-21 00:05
Today
Total
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Notice
Recent Posts
Recent Comments
Link
Archives
관리 메뉴

Bill Kim's Life...

[Swift] 프로그래머스 연습 문제(Level 1) : 모의고사 본문

CS(컴퓨터 과학)/Coding Test

[Swift] 프로그래머스 연습 문제(Level 1) : 모의고사

billnjoyce 2020. 10. 9. 12:49
728x90
반응형
실제 코딩테스트의 문제를 통하여 알고리즘 분석과 코딩 능력을 향상시킵니다.

 

 

#. 구독 대상

  • 기본 알고리즘을 코딩 테스트 문제를 통하여 학습하고 싶으신 분
  • 취업 및 이직을 준비하고 계신 개발자
  • Swift를 통하여 코딩 테스트 문제를 살펴보고 이해를 하고 싶으신 분
  • 코딩 테스트에 대한 거부감을 없애기 위하여 기초부터 하나씩 공부해보고 싶으신 분
  • 기타 알고리즘과 문제 해결 능력에 대해서 관심이 있는 모든 개발자분
참고 사항

본 코딩 테스트 문제에 대한 설명 및 해결 방안은 최적의 답이 아닐 수 있습니다.

본 강의에서 지향하는 목표는 바로 특정 문제에 대한 최적의 해결 방법을 찾기보다는 특정한 문제에 대해서 충분히 이해할 수 있고 다양한 방법을 통하여 해결하는 방법을 찾고 향상시키는데 그 목적이 있습니다.

좀 더 좋은 알고리즘 및 코드가 있으시다면 언제든지 본 게시물의 댓글을 통해서 제시해주시면 감사하겠습니다.

 

 

 


 

 

 

모의고사

 

먼저 오늘 살펴볼 문제에 대해서 먼저 살펴보겠습니다.

 

programmers.co.kr/learn/courses/30/lessons/42840

 

코딩테스트 연습 - 모의고사

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다. 1번 수포자가 찍는 ��

programmers.co.kr

 

 


 

 

 

문제 설명

 

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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 함수를 작성해주세요.

 

 

 


 

 

 

제한 조건

 

  • 시험은 최대 10,000 문제로 구성되어있습니다.
  • 문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
  • 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.

 

 

 


 

 

 

 

입출력 예

 

정답 반환 값
[1,2,3,4,5] [1]
[1,3,2,4,2] [1,2,3]

 

입출력 예 설명

 

입출력 예 #1

  • 수포자 1은 모든 문제를 맞혔습니다.
  • 수포자 2는 모든 문제를 틀렸습니다.
  • 수포자 3은 모든 문제를 틀렸습니다.

따라서 가장 문제를 많이 맞힌 사람은 수포자 1입니다.

 

입출력 예 #2

  • 모든 사람이 2문제씩을 맞췄습니다.

 

 

 


 

 

문제 분석

 

조금 특히한 예시이긴 하나 수학 문제를 푸는 데 있어서 각각의 세명의 학생이 특정한 번호를 가진 패턴을 통하여 문제를 찍기(?)를 통하여 풀었을 경우 가장 문제를 많이 맞춘 사람을 결과로 반환하는 문제입니다.

 

 

그렇다면 각 학생의 문제 찍기(?)의 패턴을 한번 살펴보겠습니다.

 

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번 학생 패턴 : 1, 2, 3, 4, 5
2번 학생 : 2, 1, 2, 3, 2, 4, 2, 5
3번 학생 : 3, 3, 1, 1, 2, 2, 4, 4, 5, 5

 

 

기본적으로 이 문제를 해결하기 위해서는 각 학생의 찍기(?) 패턴과 전체 문제를 처음부터 끝까지 하나씩 비교해가면서 맞춘 문제의 수를 저장한 후  세명의 학생을 각각 비교하여 가장 많이 맞춘 사람의 번호(인덱스)를 반환하도록 코드를 짜면 되겠습니다.

 

 

 

 


 

 

 

알고리즘

 

위의 내용을 기반으로 하여 본 문제를 해결하기 위한 알고리즘을 살펴보면 아래와 같습니다.

 

  • 각 학생의 찍기 패턴 배열을 생성 => 학생 패턴 배열 생성
  • 각 학생들의 번호와 정답 수를 관리하기 위하여 key, value 형태를 가진 Dictionary 객체를 생성
  • 학생의 찍기 패턴 배열과 정답 배열을 하나씩 비교, 정답 배열과 찍기 패턴 배열의 크기가 다를 수 있기때문에 패턴 배열의 수만큼 반복하여 비교
  • 만약 현재 인덱스의 패턴 배열과 정답 배열의 요소가 같은 값이면 해당 학생 Dictionary 객체에서 해당 학생 인덱스(key)의 값을 +1을시켜준다.
  • 최종 비교 완료 후 학생 Dictionary 객체에서 가장 많은 문제를 맞춘 학생의 리스트만 반환
  • 문제를 많이 맞춘 학생이 여러 명일 경우는 학생의 인덱스의 오르차순 순으로 정렬하여 리스트 반환
  • dic에서 max값을 가져오는데 가장 문제를 많이 맞힌 학생이 여러명일 경우에는 오름차순으로 정렬시켜주면 끝

 

 

 

 

 

 


 

 

 

코드 설명

 

그렇다면 위의 알고리즘에 대해서 하나씩 살펴보면서 코드로 작성을 해보도록 하겠습니다.

 

 

 

  • 각 학생의 찍기 패턴 배열을 생성 => 학생 패턴 배열 생성
let arr1 = [1,2,3,4,5]
let arr2 = [2,1,2,3,2,4,2,5]
let arr3 = [3,3,1,1,2,2,4,4,5,5]

 

 

  • 각 학생들의 번호와 정답 수를 관리하기 위하여 key, value 형태를 가진 Dictionary 객체를 생성
var dic: [Int: Int] = [:]

 

 

  • 학생의 찍기 패턴 배열과 정답 배열을 하나씩 비교, 정답 배열과 찍기 패턴 배열의 크기가 다를 수 있기때문에 패턴 배열의 수만큼 반복하여 비교
  • 만약 현재 인덱스의 패턴 배열과 정답 배열의 요소가 같은 값이면 해당 학생 Dictionary 객체에서 해당 학생 인덱스(key)의 값을 +1을시켜준다.

 

 

for i in 0..<answers.count {
    if answers[i] == arr1[i%arr1.count] { dic[1] = (dic[1] ?? 0) + 1 }
    if answers[i] == arr2[i%arr2.count] { dic[2] = (dic[2] ?? 0) + 1 }
    if answers[i] == arr3[i%arr3.count] { dic[3] = (dic[3] ?? 0) + 1 }
}

 

 

  • 최종 비교 완료 후 학생 Dictionary 객체에서 가장 많은 문제를 맞춘 학생의 리스트만 반환
  • 문제를 많이 맞춘 학생이 여러 명일 경우는 학생의 인덱스의 오르차순 순으로 정렬하여 리스트 반환
let max = dic.values.max()!
let result = dic.filter { $0.value == max }.keys.sorted()

 

 

위의 코드들을 모두 조합하여 최종 코드를 완성하면 아래와 같습니다.

 

 

최종 코드

func solution(_ answers:[Int]) -> [Int] {
    // 학생들의 패턴 배열 생성
    let arr1 = [1,2,3,4,5]
    let arr2 = [2,1,2,3,2,4,2,5]
    let arr3 = [3,3,1,1,2,2,4,4,5,5]
    
    // 학생의 번호와 정답 수를 관리하기 위한 key, value 형태의 Dictionary
    var dic: [Int: Int] = [:]
    
    // 각 학생들의 패턴과 최종 정답과 패턴의 수를 각 패턴의 수만큼 고려하여 하나씩 비교
    for i in 0..<answers.count {
        // 정답과 패턴의 수가 같을 경우 해당 학생 Dictionary의 value 값을 1 증가
        if answers[i] == arr1[i%arr1.count] { dic[1] = (dic[1] ?? 0) + 1 }
        if answers[i] == arr2[i%arr2.count] { dic[2] = (dic[2] ?? 0) + 1 }
        if answers[i] == arr3[i%arr3.count] { dic[3] = (dic[3] ?? 0) + 1 }
    }
    
    // 모든 학생들의 Dictionary의 최대 값을 가져옴 
    let max = dic.values.max()!
    
    // max값과 같은 값을 가지는 객체들만 추려서(필터링) 가져옴(filter)
    // 여러 개일 경우를 고려하여 오름차순 정렬을 실행
    let result = dic.filter { $0.value == max }.keys.sorted()

    return result
}

 

 

 

 


 

 

 

이상으로 오늘 제시한 문제에 대해서 분석 및 코드를 작성해 보았습니다.

 

 

 

감사합니다.

 

 

 

 


[참고 자료(References)]

 

[1] 프로그래머스 - 모의고사 : programmers.co.kr/learn/courses/30/lessons/42840

728x90
반응형
Comments