❓ 모의고사
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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 함수를 작성해주세요.
제한 조건
1. 시험은 최대 10,000 문제로 구성되어있습니다.
2. 문제의 정답은 1, 2, 3, 4, 5중 하나입니다.
3. 가장 높은 점수를 받은 사람이 여럿일 경우, return하는 값을 오름차순 정렬해주세요.
💡 풀이
class Solution {
fun solution(answers: IntArray): IntArray {
val answer: MutableList<Int> = mutableListOf<Int>()
val studentsAnswer = arrayOf<IntArray>(
intArrayOf(1, 2, 3, 4, 5),
intArrayOf(2, 1, 2, 3, 2, 4, 2, 5),
intArrayOf(3, 3, 1, 1, 2, 2, 4, 4, 5, 5),
)
val result = intArrayOf(0, 0, 0)
for(i: Int in 0..2){
var cnt = 0 //누적 점수
for(j:Int in answers.indices){
// studentsAnswer[i][j % studentsAnswer[i].size] 는 0,1,2,3,4...
if(answers[j] == studentsAnswer[i][j % studentsAnswer[i].size]) cnt += 1
}
result[i] = cnt // 5,0,0 / 2,2,2
}
val max:Int = result.maxOrNull()!!
for(i: Int in result.indices){
if(max == result[i]) answer.add(i+1)
}
return answer.toIntArray()
}
}
- answer를 MutableList로 선언해준다.
- 학생들의 답안이 담긴 이중 배열을 선언해준다.
- 학생들이 맞춘 답안 개수를 담을 배열 result를 선언해준다.
- 반복문을 3회만 순회한다.
- 각각의 누적 점수를 0으로 명시한다.
- answers의 범위 만큼 반복문을 순회하며, 만약 answers의 j번째 값이 studentsAnswer의 i번째 배열 안의 j번째 값이 같다면 cnt += 1해준다. 이 부분에 대해서는 아래에서 다시 한 번 더 설명하겠다.
- cnt를 result 배열 안에 넣는다.
- result 배열 안에서 가장 큰 값을 분별해 선언한다.
- result의 범위 만큼 반복문을 순회하여 max값과 result의 i번째 값이 같으면 answer에 index를 넣어준다.
- answer을 반환타입값에 맞추어 변환해준 뒤 리턴한다.
4-2번에 대한 부분은 여기서 더 자세히 설명하겠다. 처음에는 반복문 작성하는 코드를 아래와 같이 작성했었다.
for(i: Int in 0..2){
var cnt = 0 //누적 점수
for(j:Int in answers.indices){
println(j % studentsAnswer[i].size)
if(answers[j] == studentsAnswer[i][j]) cnt += 1
}
result[i] = cnt // 5,0,0 / 2,2,2
}
studentsAnswer의 i번째 배열의 j번째 값으로 편하게 접근하면 되는데, 웬일인걸. 아래처럼 아래처럼 오류가 나는 정답들이 많았다.
제한 조건을 보면 문제의 정답은 1,000문제나 되는데 j번째 순회를 하며 이중반복문 순회를 하니 아무래도 러닝타임을 초과한 것으로 추정된다. 문제를 제출하고 나니 프로그래머스에서 ai 코드 피드백이 사용가능하다고 해서 한 번 써봤더니
이러한 피드백을 주었다.
대충 요약하자면 학생들의 찍기 패턴은 반복되고 있으므로 answers의 배열 길이가 각 패턴의 길이보다 길어질 때도 대응할 수 있어야한다는 것이다. 아무튼 학생의 찍기 패턴과 answers의 배열 길이가 맞지 않아서 발생하는 에러로 이를 맞춰줄 필요가 있다는 뜻이다.
고로, studentsAnswer[i][j]처럼 편하게 접근하는 것이 아니라 studentsAnswer[i][j % studentsAnswer[i].size]로 접근하여 j를 각 수포자의 답안 배열 길이로 나눈 나머지 값을 사용해 비교해야한다. 말로 풀어 설명하니 뭔가 더 어렵지만 길이를 맞춰줘야한다는 것만 이해하면 된다.
문제 하나하나 푸는 게 힘겹다... 너무 어렵다...
저렇게 길이를 맞춰줘야한다는 건 생각도 못 해봤는데 아무래도 로직 짤 때 정말 유용한 방법이 될 것 같아 기억에 남는다.
'코딩테스트' 카테고리의 다른 글
[프로그래머스] 옹알이 (2) (Kotlin) (0) | 2024.06.26 |
---|---|
[프로그래머스] 기사단원의 무기 (Kotlin) (0) | 2024.06.24 |
[프로그래머스] 행렬의 곱셈 (Kotlin) (0) | 2024.06.20 |
[프로그래머스] 과일 장수 (Kotlin) (0) | 2024.06.18 |
[프로그래머스] 명예의 전당 (1) (Kotlin) (2) | 2024.06.15 |