본문 바로가기
codingtest

[programmers] 이진수 더하기, 치킨 쿠폰, 로그인 성공?, 등수 매기기, 특이한 정렬

by 안자두 2023. 3. 11.

📝 [Lv0] 이진수 더하기

👀 문제 설명

이진수를 의미하는 두 개의 문자열 bin1과 bin2가 매개변수로 주어질 때, 두 이진수의 합을 return하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • return 값은 이진수를 의미하는 문자열입니다.
  • 1 ≤ bin1, bin2의 길이 ≤ 10
  • bin1과 bin2는 0과 1로만 이루어져 있습니다.
  • bin1과 bin2는 "0"을 제외하고 0으로 시작하지 않습니다.

 

💻 입출력 예

bin1 bin2 result
"10" "11" "101"
"1001" "1111" "11000"

 

✨ 풀이 설명

각 2진수를 parseInt()를 사용해 10진수로 변환한 다음, 두 수의 합을 다시 2진수로 변환해 주었다.

parseInt()은 문자열 인자를 파싱하여 특정 진수(수의 진법 체계에서 기준이 되는 값)의 정수를 반환한다.
toString()은 숫자를 특정 진수의 문자열 리터럴로 변환해 준다.

 

🕵️‍♂️ 코드

function solution(bin1, bin2) {
  return (parseInt(bin1, 2) + parseInt(bin2, 2)).toString(2);
}

 


📝 [Lv0] 치킨 쿠폰

👀 문제 설명

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

 

🚨 제한 사항

  • chicken은 정수입니다.
  • 0 ≤ chicken ≤ 1,000,000

 

💻 입출력 예

chicken result
100 11
1,081 120

 

✨ 풀이 설명

어떻게 풀까 고민을 하다 재귀 함수로 풀기로 했다.
우선 calc()에서 서비스로 받을 수 있는 개수를 구한다. service는 service로 받는 치킨의 개수도 될 수 있지만, 해당 치킨에 대한 쿠폰의 개수도 될 수 있다.
만약 서비스가 없다면, 전체 서비스 개수를 반환하며 재귀를 종료시키면 되고,
서비스가 있다면, 전체에서 현재 주문한 개수를 제외한 수와, 서비스를 받은 개수를 누적해 다시 재귀 함수를 돌려준다.

전체 개수에서 주문한 개수(service * 10)를 빼고, 새로 받은 쿠폰의 개수(service)를 더해주면 남은 쿠폰의 개수가 되는데,
이를 식으로 변환하면, n - 9 * service가 된다.

total에는 처음 0개에서 서비스를 받을 때마다 누적하여, 마지막 서비스가 없을 때 전체 받은 서비스를 반환해 값을 도출할 수 있다.

 

🕵️‍♂️ 코드

const calc = (n, total) => {
  const service = Math.floor(n / 10);
 
  return service ? calc(n - 9 * service, service + total) : total;
}

function solution(chicken) {
  return calc(chicken, 0);
}

 


📝 [Lv0] 로그인 성공?

👀 문제 설명

머쓱이는 프로그래머스에 로그인하려고 합니다. 머쓱이가 입력한 아이디와 패스워드가 담긴 배열 id_pw와 회원들의 정보가 담긴 2차원 배열 db가 주어질 때, 다음과 같이 로그인 성공, 실패에 따른 메시지를 return하도록 solution 함수를 완성해주세요.

  • 아이디와 비밀번호가 모두 일치하는 회원정보가 있으면 "login"을 return합니다.
  • 로그인이 실패했을 때 아이디가 일치하는 회원이 없다면 “fail”를, 아이디는 일치하지만 비밀번호가 일치하는 회원이 없다면 “wrong pw”를 return 합니다.

 

🚨 제한 사항

  • 회원들의 아이디는 문자열입니다.
  • 회원들의 아이디는 알파벳 소문자와 숫자로만 이루어져 있습니다.
  • 회원들의 패스워드는 숫자로 구성된 문자열입니다.
  • 회원들의 비밀번호는 같을 수 있지만 아이디는 같을 수 없습니다.
  • id_pw의 길이는 2입니다.
  • id_pw와 db의 원소는 [아이디, 패스워드] 형태입니다.
  • 1 ≤ 아이디의 길이 ≤ 15
  • 1 ≤ 비밀번호의 길이 ≤ 6
  • 1 ≤ db의 길이 ≤ 10
  • db의 원소의 길이는 2입니다.

 

💻 입출력 예

id_pw db result
["meosseugi", "1234"] [["rardss", "123"], ["yyoom", "1234"], ["meosseugi", "1234"]] "login"
["programmer01", "15789"] [["programmer02", "111111"], ["programmer00", "134"], ["programmer01", "1145"]] "wrong pw"
["rabbit04", "98761"] [["jaja11", "98761"], ["krong0313", "29440"], ["rabbit00", "111333"]] "fail"

 

✨ 풀이 설명

우선 쉽게 보기 위해 디스트럭처링 할당을 해 명명해 주었다.
db 안의 id는 고유하다고 했으니, filter로 걸러주면 0 또는 1개의 데이터가 나올 것이다.
이 또한 디스트럭처링을 통해 sameData라는 이름으로 분리해 주었다.
sameData에는 undefined 또는 같은 아이디와 비밀번호가 있는 배열이 나올 것이다.

만약 이 sameData에 데이터가 있으면서, 비밀번호 또한 일치하다면 "login"을, 비밀번호는 다르다면 "wrong pw"를, sameData가 없다면 "fail"을 반환해 주었다.

 

🕵️‍♂️ 코드

function solution(id_pw, db) {
  const [myId, myPw] = id_pw;
  const [sameData] = db.filter(([dbId, _]) => myId === dbId);
  return sameData ? sameData[1] === myPw ? "login" : "wrong pw" : "fail";
}

 


📝 [Lv0] 등수 매기기

👀 문제 설명

영어 점수와 수학 점수의 평균 점수를 기준으로 학생들의 등수를 매기려고 합니다. 영어 점수와 수학 점수를 담은 2차원 정수 배열 score가 주어질 때, 영어 점수와 수학 점수의 평균을 기준으로 매긴 등수를 담은 배열을 return하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • 0 ≤ score[0], score[1] ≤ 100
  • 1 ≤ score의 길이 ≤ 10
  • score의 원소 길이는 2입니다.
  • score는 중복된 원소를 갖지 않습니다.

 

💻 입출력 예

score result
[[80, 70], [90, 50], [40, 70], [50, 80]] [1, 2, 4, 3]
[[80, 70], [70, 80], [30, 50], [90, 100], [100, 90], [100, 100], [10, 30]] [4, 4, 6, 2, 2, 1, 7]

 

✨ 풀이 설명

너무 복잡하게 푼 것 같아서... 조금 그렇지만 일단 내 풀이를 먼저 설명한 후, 신박했던 다른 분의 풀이와 비교해 보겠다.

우선, 전체 점수를 평균과 원래 위치(인덱스)로 새로운 배열을 만든 다음, 성적을 기준으로 정렬해 주었다.
그다음, 같은 길이의 새 배열은 만들어, 원래 위치 자리에 현재 등수를 넣어주는 방식으로 해결하였다.

그래서 코드가 길고 복잡해진 것 같아서 다른 사람들은 어떻게 풀었나 확인해 보았다.
가장 상단 분의 코드는 score.map()으로 각 점수를 더한 값이, 내부적으로 score.filter()를 통해 다른 모든 점수들을 확인하며 map()의 점수보다 높은 지를 확인하였다. filter는 해당 값만 반환되므로 반환된 배열의 길이가 곧, 해당 점수보다 높은 사람의 수가 된다.
이를 이용해서 이 길이에 1을 더해 반환해 주면 현재 등수를 알 수 있게끔 풀이되어 있었다.
코드 👇

더보기
function solution(score) {
  return score.map((el) => {
    return (
      score.filter((v) => (v[0] + v[1]) / 2 > (el[0] + el[1]) / 2).length + 1
    );
  });
}

시간과 효율성에 맞춰 풀이방법을 선택할 필요가 있을 것 같다.

 

🕵️‍♂️ 코드

function solution(score) {
  const result = new Array(score.length).fill(0);
  const total = score.map(([eng, math], idx) => [(eng + math) / 2, idx]).sort((prev, next) => next[0] - prev[0]);

  result[total[0][1]] = 1;
  for (let i = 1; i < score.length; i++) {
    const [avg, originIdx] = total[i];
    if (total[i - 1][0] === avg) result[originIdx] = result[total[i - 1][1]];
    else result[originIdx] = i + 1;
  }
  return result;
}

 


📝 [Lv0] 특이한 정렬

👀 문제 설명

정수 n을 기준으로 n과 가까운 수부터 정렬하려고 합니다. 이때 n으로부터의 거리가 같다면 더 큰 수를 앞에 오도록 배치합니다. 정수가 담긴 배열 numlist와 정수 n이 주어질 때 numlist의 원소를 n으로부터 가까운 순서대로 정렬한 배열을 return하도록 solution 함수를 완성해주세요.

 

🚨 제한 사항

  • 1 ≤ n ≤ 10,000
  • 1 ≤ numlist의 원소 ≤ 10,000
  • 1 ≤ numlist의 길이 ≤ 100
  • numlist는 중복된 원소를 갖지 않습니다.

 

💻 입출력 예

numlist n result
[1, 2, 3, 4, 5, 6] 4 [4, 5, 3, 6, 2, 1]
[10000,20,36,47,40,6,10,7000] 30 [36, 40, 20, 47, 10, 6, 7000, 10000]

 

✨ 풀이 설명

sort()를 사용해 풀이하였다. 우선, sort()는 return 값이 1(양수)일 경우, 순서를 바꿔주고 -1(음수)일 경우, 현재 순서를 유지한다.
이를 이용하여 비교할 두 값이 n과 가까울수록 앞에 위치하도록 하고, 만약 두 거리가 같다면, 큰 수를 앞으로 가도록 해주었다. 만약 next - prev에서 next가 prev 보다 크다면 계산 값은 양수가 되기 때문에 두 위치를 바꿔 next가 앞에 오게 된다.

 

🕵️‍♂️ 코드

function solution(numlist, n) {
  return numlist.sort((prev, next) => {
    if (Math.abs(prev - n) > Math.abs(next - n)) return 1;
    if (Math.abs(prev - n) < Math.abs(next - n)) return -1;
    return next - prev;
  })
}

 

728x90