문제 33: 로또의 최고순위와 최저순위
로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1
순위당첨 내용
1 | 6개 번호가 모두 일치 |
2 | 5개 번호가 일치 |
3 | 4개 번호가 일치 |
4 | 3개 번호가 일치 |
5 | 2개 번호가 일치 |
6(낙첨) | 그 외 |
로또를 구매한 민우는 당첨 번호 발표일을 학수고대하고 있었습니다. 하지만, 민우의 동생이 로또에 낙서를 하여, 일부 번호를 알아볼 수 없게 되었습니다. 당첨 번호 발표 후, 민우는 자신이 구매했던 로또로 당첨이 가능했던 최고 순위와 최저 순위를 알아보고 싶어 졌습니다.
알아볼 수 없는 번호를 0으로 표기하기로 하고, 민우가 구매한 로또 번호 6개가 44, 1, 0, 0, 31 25라고 가정해보겠습니다. 당첨 번호 6개가 31, 10, 45, 1, 6, 19라면, 당첨 가능한 최고 순위와 최저 순위의 한 예는 아래와 같습니다.
당첨 번호3110451619결과
최고 순위 번호 | 31 | 0→10 | 44 | 1 | 0→6 | 25 | 4개 번호 일치, 3등 |
최저 순위 번호 | 31 | 0→11 | 44 | 1 | 0→7 | 25 | 2개 번호 일치, 5등 |
- 순서와 상관없이, 구매한 로또에 당첨 번호와 일치하는 번호가 있으면 맞힌 걸로 인정됩니다.
- 알아볼 수 없는 두 개의 번호를 각각 10, 6이라고 가정하면 3등에 당첨될 수 있습니다.
- 3등을 만드는 다른 방법들도 존재합니다. 하지만, 2등 이상으로 만드는 것은 불가능합니다.
- 알아볼 수 없는 두 개의 번호를 각각 11, 7이라고 가정하면 5등에 당첨될 수 있습니다.
- 5등을 만드는 다른 방법들도 존재합니다. 하지만, 6등(낙첨)으로 만드는 것은 불가능합니다.
민우가 구매한 로또 번호를 담은 배열 lottos, 당첨 번호를 담은 배열 win_nums가 매개변수로 주어집니다. 이때, 당첨 가능한 최고 순위와 최저 순위를 차례대로 배열에 담아서 return 하도록 solution 함수를 완성해주세요.
제한사항
- lottos는 길이 6인 정수 배열입니다.
- lottos의 모든 원소는 0 이상 45 이하인 정수입니다.
- 0은 알아볼 수 없는 숫자를 의미합니다.
- 0을 제외한 다른 숫자들은 lottos에 2개 이상 담겨있지 않습니다.
- lottos의 원소들은 정렬되어 있지 않을 수도 있습니다.
- win_nums은 길이 6인 정수 배열입니다.
- win_nums의 모든 원소는 1 이상 45 이하인 정수입니다.
- win_nums에는 같은 숫자가 2개 이상 담겨있지 않습니다.
- win_nums의 원소들은 정렬되어 있지 않을 수도 있습니다.
입출력 예
lottoswin_numsresult
[44, 1, 0, 0, 31, 25] | [31, 10, 45, 1, 6, 19] | [3, 5] |
[0, 0, 0, 0, 0, 0] | [38, 19, 20, 40, 15, 25] | [1, 6] |
[45, 4, 35, 20, 3, 9] | [20, 9, 3, 45, 4, 35] | [1, 1] |
나의코드
function solution(lottos, win_nums) {
var answer = [];
let correct=[];
let zeros=[];
for(i=0;i<lottos.length;i++){
if(win_nums.includes(lottos[i])){
correct.push(lottos[i])
}
}
for(i=0;i<lottos.length;i++){
if(lottos[i]==0){
zeros.push(lottos[i])
}
}
let a=correct.length;
let b=zeros.length;
answer.push(Math.min(6,7-(a+b)))
answer.push(Math.min(6,(7-a)))
return answer;
}
나의풀이
문제의 가장 핵심 포인트는 1개를 맞추든 0개를 맞추는 최저 순위는 7이 아니라 6등이라는 것에 있다. <= 여기를 조심하지 않으면 열몇개의 테스트를 모두 통과할 수가 없다. correct와 zoro라는 이름으로 각각 빈 배열을 만들어 준다. 그리고 correct에는 확실하게 맞은 로또 번호를 담고, zeros에는 내가 산 로또에서 0의 개수를 넣는다. a는 확실하게 맞는 로또의 개수이고, b는 0의 개수이다. 먼저 최고 순위의 경우에는 내가 확실하게 맞은 로또의 개수인 a와 아직 알 수 없는 0의 개수를 합한것을 7에서 빼주었을 때의 순위이다. 그러나 이때도 Math.min(6,7-(a+b))를 넣어줘서 혹시라도 7이 반환되는 경우를 방지한다. 아무리 등수가 낮다고 해도 7등은 존재하지 않기 때문이다. 그리고 최저순위의 경우에는 zero가 다 틀리고 a만큼을 7에서 빼주는데 이 때도 마찬가지로 Math.min(6,(7-a))를 돌려 최소값은 6이 되도록 설정해준다.
문제 34: 모의고사
수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 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)
function solution(answers) {
var answer = [];
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]
let corr1=[]
let corr2=[]
let corr3=[]
let a=0;
let b=0;
let c=0;
for(i=0;i<answers.length;i++){
if(answers[i]==arr1[i%5]){
corr1.push(arr1[i])
}
if(answers[i]==arr2[i%8]){
corr2.push(arr2[i]).length
}
if(answers[i]==arr3[i%10]){
corr3.push(arr3[i]).length
}
}
a=corr1.length;
b=corr2.length;
c=corr3.length;
let max=Math.max(a,b,c)
if(a==max){
answer.push(1)
}
if(b==max){
answer.push(2)
}
if(c==max){
answer.push(3)
}
return answer;
}
나의코드2)
function solution(answers) {
var answer = [];
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];
let s1 = answers.filter( (a, i) => a === arr1[i%5] ).length;
let s2 = answers.filter( (a, i) => a === arr2[i%8] ).length;
let s3 = answers.filter( (a, i) => a === arr3[i%10] ).length;
let max = Math.max(s1, s2, s3);
if(s1 === max) answer.push(1);
if(s2 === max) answer.push(2);
if(s3 === max) answer.push(3);
return answer; }
나의풀이
먼저 수포자 1,2,3명의 답안 패턴을 각각 arr1,arr2,arr3에 배열한다. 수포자들의 답안은 각 배열이 반복되는 형식으로 진행된다. 그리고 s1,s2,s3에 답안들중 각 배열의 i번째를 각 배열의 길이값으로 나눈 값들이 일치하는 정답의 개수를 걸러낸다. 이 과정을 진행하는 동안 코드1은 for문으로 코드2는 filter를 통해 진행해봤는데 확연히 filter을 이용한 답안이 길이도 짧고 깔끔하다. s1,s2,s3들중 가장 최고값을 max에 할당한 뒤, 만약 s1이 최고이면 1을 answer에 넣는식이다. 동일한 개수로 정답이 맞춘 경우에는 오름차순으로 1,2,3과 같이 적으면 되는데, push의 순서가 이미 1부터 3까지 순차적으로 적었기 떄문에 무방하다. 이 때 한가지 중요한 포인트는
if(a==max){
answer.push(1)}
else if(b==max){
answer.push(2)}
else{
answer.push(3)
}
위와 같이 코드를 작성하면, if문은 원하는 조건을 찾으면 뒤의 조건을 찾아보지 않기 때문에 a=b인 경우와 같이 max의 값이 여러개인 경우에도 push(1)만 실행될 수 있다. 따라서 반드시 if문을 각각 분리해서 써줘야 한다.
문제 35: 문자열 내 마음대로 정렬하기
문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.제한 조건
- strings는 길이 1 이상, 50이하인 배열입니다.
- strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
- strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
- 모든 strings의 원소의 길이는 n보다 큽니다.
- 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
입출력 예
strings n return
["sun", "bed", "car"] | 1 | ["car", "bed", "sun"] |
["abce", "abcd", "cdx"] | 2 | ["abcd", "abce", "cdx"] |
나의코드
function solution(strings, n) {
let answer = strings.sort((a, b) => {
if(a[n] > b[n]) {
return 1;
}
if(a[n] < b[n]) {
return -1;
}
if(a[n] === b[n]) {
if(a > b) {
return 1;
}
if(a < b) {
return -1;
}
return 0;
}
})
return answer;
}
나의풀이
이번에도 다른 사람이 푼 답안 중 가장 내가 이해할 수 있는 답안으로 가져왔다. 각 단어들의 n번째 인덱스 요소들의 순서대로 배열을하고 만약에 값이 같을때에는 단어들의 값을 각각 비교해 오름차순으로 정렬하는 것이다.
제대로 이해하기 위해서는 sort()에 대한 분석이 조금 더 필요하다.
https://change-words.tistory.com/64 << sort()의 원리에 대한 글
문제 36: 내림차순으로 배치하기
문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요.
s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 간주합니다.제한 사항
- str은 길이 1 이상인 문자열입니다.
입출력 예
s return
"Zbcdefg" | "gfedcbZ" |
나의코드
function solution(s) {
let arr=s.split("")
let answer=[];
let uppers=[];
let lowers=[];
for(i=0;i<arr.length;i++){
if(arr[i].toUpperCase()==arr[i]){
uppers.push(arr[i])
}else{
lowers.push(arr[i])
}
}
answer.push(lowers.sort().reverse().join(""))
answer.push(uppers.sort().reverse().join(""))
return answer.join("")
}
나의풀이
먼저 문자s를 공백 단위로 잘라 한 단어씩 배열에 넣은 뒤에 uppers와 lowers라는 빈 배열을 만든뒤 대문자로 이루어져 있는 단어들은 uppers에 분류하고 소문자 단어들은 lowers에 분류하였다. 각 lowers와 uppers의 배열을 내림차순으로 만든다음에 배열이 아니라 단어로 만들어주기위해 join("")을 해준뒤 answer에 넣어준다. answer역시 배열이 아니라 문자로 나와야하기때문에 마지막으로 한번도 join("")을 해줘서 값을 리턴한다.
'알고리즘' 카테고리의 다른 글
[알고리즘 코딩테스트](1):코딩 테스트 준비하기 (0) | 2023.02.05 |
---|---|
프로그래머스 알고리즘 스터디 [문37-40] (0) | 2022.03.24 |
3월 15일 알고리즘 모의고사 2번 풀이 (0) | 2022.03.15 |
프로그래머스 자바스크립트 알고리즘 스터디[문29~문32] (0) | 2022.03.14 |
프로그래머스 자바스크립트 알고리즘 스터디[문25~문28] (0) | 2022.03.14 |