본문 바로가기
알고리즘 문제풀이/Programmers

코딩테스트 연습 - 13일차

by 코도꼬마 2023. 11. 21.
  JAVA SCRIPT SQL
13일차 2 2 2
12일차 1개 5개 2개
11일차 3개 4개 3개
10일차 3개 3개 4개
9일차 5개 4개 4개
8일차 2개 7개 3개
7일차 3개 6개 4개
6일차 4개 8개 6개
5일차 7개 8개 9개
4일차 9개 10개 9개
3일차 11개 10개 8개
2일차 10개 8개 7개
1일차 9개 7개 14개

 

 

JAVA 

1. 치킨 쿠폰

프로그래머스 치킨은 치킨을 시켜먹으면 한 마리당 쿠폰을 한 장 발급합니다. 쿠폰을 열 장 모으면 치킨을 한 마리 서비스로 받을 수 있고, 서비스 치킨에도 쿠폰이 발급됩니다. 시켜먹은 치킨의 수 chicken이 매개변수로 주어질 때 받을 수 있는 최대 서비스 치킨의 수를 return하도록 solution 함수를 완성해주세요.

class Solution {
    public int solution(int chicken) {
        int answer = 0;
        
        //쿠폰으로 받을 수 있는 치킨 수 count
        int cnt = chicken/10;
        //쿠폰 수 count
        int coupon = cnt + chicken%10;
        
        //쿠폰이 10개 이상일 동안 while문 돌기
        while (true) {
            //answer에 치킨 수 +
            answer += cnt;

            //쿠폰이 10개 미만이면 break
            if (coupon < 10) {
                break;
            }

            //쿠폰으로 시킨 치킨 수
            cnt = coupon / 10;
            //남은 쿠폰 수 계산
            coupon = cnt + coupon % 10;
        }
        
        return answer;
    }
}

 

2. 문자열 밀기

문자열 "hello"에서 각 문자를 오른쪽으로 한 칸씩 밀고 마지막 문자는 맨 앞으로 이동시키면 "ohell"이 됩니다. 이것을 문자열을 민다고 정의한다면 문자열 A B가 매개변수로 주어질 때, A를 밀어서 B가 될 수 있다면 밀어야 하는 최소 횟수를 return하고 밀어서 B가 될 수 없으면 -1을 return 하도록 solution 함수를 완성해보세요.

import java.util.*;

class Solution {
    public int solution(String A, String B) {
        int answer = 0;
        
        //a와 b를 비교하여 같지 않는 동안 while문 돌기
        while(!A.equals(B)){
            //answer이 a의 길이보다 크면 return -1
            if(answer > A.length()){
                return -1;
            }else {
                //a문자열 한칸씩 밀기
                A = push(A);
                //answer++
                answer++;                
            }
        }
        
        return answer;
    }
    
    public String push (String A){
        return A.substring(A.length()-1,A.length())+A.substring(0,A.length()-1);  
    }
    
}

 

 

 

SCRIPT

1. 리스트 자르기

정수 n과 정수 3개가 담긴 리스트 slicer 그리고 정수 여러 개가 담긴 리스트 num_list가 주어집니다. slicer에 담긴 정수를 차례대로 a, b, c라고 할 때, n에 따라 다음과 같이 num_list를 슬라이싱 하려고 합니다.

  • n = 1 : num_list의 0번 인덱스부터 b번 인덱스까지
  • n = 2 : num_list의 a번 인덱스부터 마지막 인덱스까지
  • n = 3 : num_list의 a번 인덱스부터 b번 인덱스까지
  • n = 4 : num_list의 a번 인덱스부터 b번 인덱스까지 c 간격으로

올바르게 슬라이싱한 리스트를 return하도록 solution 함수를 완성해주세요.

function solution(n, slicer, num_list) {
    var answer = [];
    
    //n = 1
    if(n == 1){
        //0번 인덱스부터 b번 인덱스까지 answer에 저장
        answer = num_list.slice(0,slicer[1]+1);
    }
    //n = 2
    if(n == 2){
        //a번 인덱스부터 마지막 인덱스까지 answer에 저장
        answer = num_list.slice(slicer[0]);        
    }
    //n = 3
    if(n == 3){
        //a번 인덱스부터 b번 인덱스까지 answer에 저장
        answer = num_list.slice(slicer[0],slicer[1]+1);               
    }
    //n = 4
    if(n == 4){
        //a번 인덱스부터 b번 인덱스까지 c 간격으로 answer에 저장
        answer = num_list.slice(slicer[0],slicer[1]+1).filter((_,i)=>i%slicer[2]==0);           
    }
    
    return answer;
}

 

2. 조건에 맞게 수열 변환하기 2

정수 배열 arr가 주어집니다. arr의 각 원소에 대해 값이 50보다 크거나 같은 짝수라면 2로 나누고, 50보다 작은 홀수라면 2를 곱하고 다시 1을 더합니다.

이러한 작업을 x번 반복한 결과인 배열을 arr(x)라고 표현했을 때, arr(x) = arr(x + 1)인 x가 항상 존재합니다. 이러한 x 중 가장 작은 값을 return 하는 solution 함수를 완성해 주세요.

단, 두 배열에 대한 "="는 두 배열의 크기가 서로 같으며, 같은 인덱스의 원소가 각각 서로 같음을 의미합니다.

function solution(arr) {
    var answer = 0;
    
    //연산 전 배열을 저장할 변수
    let copyArr = arr.slice();
    //arr 배열 연산
    arr = arrX(arr);  
    
    //두 배열을 비교해서 모든 값이 같을 경우 answer 리턴
    //아닐 경우 재연산 
    while(!eq(arr,copyArr)){
        //answer++
        answer++;
        //연산된 arr 복사
        copyArr = arr.slice();
        //arr 재연산
        arr = arrX(arr);  
    }    
    
    return answer;
}

//연산 함수
function arrX(arr){
    return arr.map((e,_) => e >= 50 && e%2 === 0 ? e/2 : e < 50 && e%2 !== 0 ? e*2+1 : e);
}

//두 배열 일치 여부 확인 함수
function eq(arr,copyArr){
    return arr.length === copyArr.length && arr.every((e,i) => e === copyArr[i]);
}

 

 

 

SQL

1. 자동차 대여 기록 별 대여 금액 구하기

WITH SUB AS (
    SELECT 
        H.HISTORY_ID
        ,C.CAR_TYPE
        ,C.DAILY_FEE*(H.END_DATE - H.START_DATE + 1) AS "DC",
        (CASE
            WHEN H.END_DATE - H.START_DATE + 1 >= 90 THEN '90일 이상'
            WHEN H.END_DATE - H.START_DATE + 1 < 90 AND H.END_DATE - H.START_DATE + 1>= 30 THEN '30일 이상'
            WHEN H.END_DATE - H.START_DATE + 1 < 30 AND H.END_DATE - H.START_DATE + 1>= 7 THEN '7일 이상'
            ELSE '7일 미만'
        END) AS DURATION_TYPE
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H 
    LEFT JOIN CAR_RENTAL_COMPANY_CAR C ON H.CAR_ID = C.CAR_ID
    WHERE C.CAR_TYPE = '트럭'
)

SELECT
    S.HISTORY_ID
    ,(S.DC*(100-NVL(D.DISCOUNT_RATE, 0))/100) AS FEE
FROM SUB S
LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN D 
ON S.DURATION_TYPE = D.DURATION_TYPE
AND S.CAR_TYPE = D.CAR_TYPE
ORDER BY FEE DESC, HISTORY_ID DESC;

 

2. 상품을 구매한 회원 비율 구하기

WITH SUB AS (
    SELECT 
        COUNT(USER_ID) AS TOTAL
    FROM USER_INFO
    WHERE TO_CHAR(JOINED,'YYYY') = '2021'
)

SELECT 
    TO_CHAR(S.SALES_DATE, 'YYYY') AS YEAR
    ,TO_NUMBER(TO_CHAR(S.SALES_DATE, 'MM')) AS MONTH
    ,COUNT(DISTINCT S.USER_ID) AS PUCHASED_USERS
    ,ROUND(COUNT(DISTINCT S.USER_ID) / (SELECT TOTAL FROM SUB), 1) AS PURCHASED_RATIO
FROM USER_INFO I
INNER JOIN ONLINE_SALE S ON I.USER_ID = S.USER_ID
WHERE TO_CHAR(I.JOINED, 'YYYY') = '2021'
GROUP BY TO_CHAR(S.SALES_DATE, 'YYYY'), TO_NUMBER(TO_CHAR(S.SALES_DATE, 'MM'))
ORDER BY 1, 2;