- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- swift
- datastructure
- 알고리즘
- coding test
- swift 코딩테스트
- sort
- 스위프트
- swift split
- 정렬알고리즘
- Algorithm
- 자료구조
- 코테
- dart
- 정렬
- 프로그래머스 level1
- 다트
- programmer
- 디자인 패턴
- 프로그래머스
- swift 알고리즘
- 디자인패턴
- 정렬 알고리즘
- programmers
- 프로그래머스 swift
- 프로그래머스 레벨2
- 스위프트디자인패턴
- 감성에세이
- 코딩테스트
- Design Pattern
- rxswift
Bill Kim's Life...
[Swift] 프로그래머스 연습 문제(Level 1) : 모의고사 본문
실제 코딩테스트의 문제를 통하여 알고리즘 분석과 코딩 능력을 향상시킵니다.
#. 구독 대상
- 기본 알고리즘을 코딩 테스트 문제를 통하여 학습하고 싶으신 분
- 취업 및 이직을 준비하고 계신 개발자
- Swift를 통하여 코딩 테스트 문제를 살펴보고 이해를 하고 싶으신 분
- 코딩 테스트에 대한 거부감을 없애기 위하여 기초부터 하나씩 공부해보고 싶으신 분
- 기타 알고리즘과 문제 해결 능력에 대해서 관심이 있는 모든 개발자분
참고 사항
본 코딩 테스트 문제에 대한 설명 및 해결 방안은 최적의 답이 아닐 수 있습니다.
본 강의에서 지향하는 목표는 바로 특정 문제에 대한 최적의 해결 방법을 찾기보다는 특정한 문제에 대해서 충분히 이해할 수 있고 다양한 방법을 통하여 해결하는 방법을 찾고 향상시키는데 그 목적이 있습니다.
좀 더 좋은 알고리즘 및 코드가 있으시다면 언제든지 본 게시물의 댓글을 통해서 제시해주시면 감사하겠습니다.
모의고사
먼저 오늘 살펴볼 문제에 대해서 먼저 살펴보겠습니다.
programmers.co.kr/learn/courses/30/lessons/42840
문제 설명
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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
'CS(컴퓨터 과학) > Coding Test' 카테고리의 다른 글
[Swift] 프로그래머스 연습 문제(Level 1) : 가운데 글자 가져오기 (0) | 2020.11.08 |
---|---|
[Swift] 프로그래머스 연습 문제(Level 1) : 2016년 (0) | 2020.11.08 |
[Swift] 프로그래머스 연습 문제(Level 1) : K번째수 (0) | 2020.11.07 |
[Swift] 프로그래머스 연습 문제(Level 1) : 체육복 (2) | 2020.10.25 |
[Swift] 프로그래머스 연습 문제(Level 1) : 두 개 뽑아서 더하기 (0) | 2020.10.18 |