코딩 테스트/프로그래머스

[프로그래머스] 순위 검색

2023. 5. 7. 10:09
목차
  1. 📙 1. 문제
  2. 문제 설명
  3. 🌈 2.시작하며
  4. 풀이 과정 1 (시간 초과 풀이)
  5. 💻 결과
  6. 풀이 과정 2 : 객체 이용 but 시간초과
  7. 풀이 3 : 다른 사람 풀이
  8. 🤔 3. 느낀 점
  9. 🤩 4. 한 번 더 짚고 갈 점

📙 1. 문제

Link : https://school.programmers.co.kr/learn/courses/30/lessons/72412?language=javascript

[프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr](https://school.programmers.co.kr/learn/courses/30/lessons/72412?language=javascript)

문제 설명

🌈 2.시작하며

풀이 과정 1 (시간 초과 풀이)

처음에는 객체를 사용하려다가, 객체를 사용하여 javascript,css.. 등 각각 매칭시키면 javascript-backend등 연관을 못시켜서 객체를 사용하지 않고 노가다로 풀었다.

function solution(info, query) {
    var answer = [];
    info = info.map(it => it.split(' '))
    query.forEach(item=>{
        const needs = item.split('and').map(it=>it.trim())

        const [a,b] = [needs[3].split(' ')[0],needs[3].split(' ')[1]];
        needs[3]=a;
        needs.push(+b)
        let minValue = Infinity
        let infoDup = [...info];
        for(let i=0;i<5;i++){
            if(needs[i]==='-') continue;
            if(i===4){
                infoDup = infoDup.filter(it=>+it[4]>=+needs[i])
                continue;
            }

            infoDup = infoDup.filter(it=>it[i]===needs[i])
        }
        answer.push(infoDup.length)
    })

    return answer;
}

💻 결과

filter를 이용하여 해당하는 요소가 있을 때까지 거르고 걸렀다. 그리고, 걸러진 배열의 크기를 반환하였다. 정확성 테스트는 통과하였지만 역시나 시간초과에 걸려 효율성 테스트는 실패하였다.

풀이 과정 2 : 객체 이용 but 시간초과

시간을 단축시키려면 아무래도 객체 사용하는 것이 최선이라 생각하여 객체를 사용하였다.

function solution(info, query) {
    var answer = [];

//     객체로 저장 -> key: 언어+직군+경력+소울푸드 | value : 점수
//     key로 검색하여 value로 탐색

    const object = {};
    info.forEach(it=>{
        const arr = it.split(' ');
        const score = +arr.pop();
        const name = arr.join('')
        object[name]=!!object[name]?[...object[name],score]:[score];
    })
    query.forEach(item=>{
        let queryArr = item.split('and').map(it=>it.trim());
        const score = +queryArr[3].split(' ')[1]
        queryArr[3] = queryArr[3].split(' ')[0]
        let keyValues = Object.keys(object);
        for(let i=0;i<4;i++){
            if(queryArr[i]==='-')continue;
            keyValues = keyValues.filter(key=>key.includes(queryArr[i]))
        }
        let cnt = 0;
        keyValues=keyValues.filter(key=>{
            object[key].forEach(it=>{
                if(it>=score) cnt++;
            })
        });
        answer.push(cnt)
    })

    return answer;
}

풀이 3 : 다른 사람 풀이

출처 : https://velog.io/@young_pallete/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%9C%EC%9C%84-%EA%B2%80%EC%83%89JavaScript

// 이분 탐색입니다. 해당 값이 어느 인덱스에 있을지를 탐색하여 결과를 반환합니다.
const binarySearch = (arr, target) => {
  let left = 0;
  let right = arr.length - 1;
  let mid = Math.floor((left + right) / 2);
  while(left <= right) {
    if (arr[mid] === target) return mid;
    if (arr[mid] < target) left = mid + 1;
    else right = mid - 1;

    mid = Math.floor((left + right) / 2);
  }
  // 기준이 되는 인덱스는, 여기서 나온 값보다 항상 1이 더 큽니다. 따라서 +1을 해주죠!
  return mid + 1; 
}

const getInfos = (info) => {
  const infos = {}; // object를 생성해줄 거에요.
  info.forEach(infoString => { // 이제 object에 `info`를 처리해줘야겠죠?!
    const arr = infoString.split(" "); // 먼저 " " 기준으로 string을 분리해줍시다.
    const score = parseInt(arr.pop()); // 정수로 바꿔줄 거에요.
    const key = arr.join(""); // key를 javabackendjuniorpizza와 같은 형태로 해줄 거에요.
    if (infos[key]) infos[key].push(score)
    else infos[key] = [score]; // [150]의 형태로 배열에 점수를 넣어줘요.
  });
  for (const key in infos) {
    // 다 처리된 이후에는 각 키의 점수 배열을 정렬해줍니다.
    // 이건 이분탐색을 위한 거에요.
    infos[key].sort((a, b) => a - b); 
  }
  return infos;
}

const getResult = (infos, query, score) => {
  // 키들을 배열 형태로 갖고 옵시다.
  const infosKey = Object.keys(infos);
  // 여기서 이제 키들에 대해 쿼리 조건을 만족하는 것들을 필터링해서 배열로 반환하고 (filter)
  // reduce로 전체 점수 배열의 길이값 - 이분 탐색 결과 인덱스 값을 해줍니다.
  // 그러면 결국 값이 같거나 큰 애들의 수만큼 값이 나오겠죠? (정렬되어 있으니까요)
  // 이를 누산해줍니다.
  return infosKey
    .filter(key => query.every(v => key.includes(v)))
    .reduce((acc, key) => acc + infos[key].length - binarySearch(infos[key], score), 0);
}

const solution = (info, query) => {
  let answer = [];
  const infos = getInfos(info); // solution
  query
    .map(q => q
       .split(/ and | |-/i) //' and '와 ' '와 '-'이 들어가 있는 친구들 기준으로 split 처리해줘요.
       .filter(v => v !== "") // `split`에 의해 값이 "" 처리가 된 친구들을 없애줍니다.
    ) // 쿼리 조건들을 필터링해줄 거에요.
    .forEach(query => {
      const score = query.pop();
      const result = getResult(infos, query, score);
      answer.push(result) // getResult로 인해 누산된 결과값을, answer에 넣어줍시다.
    })
  return answer;
}

필요한 요소들을 함수화시켜서 묶었다. 확실히 함수화시켜주니 main함수가 깔끔하다.

  • 함수
    1. getInfos(info) : 주어진 info배열을 object화 시켜주어 반환하는 함수
    2.getResult(infos,query,score) : 결과를 반환하는 함수 (일치하는 값을 반환)
    함수의 장점은 함수scope를 갖게되어 기존 값을 변경하지 않는다 : 함수형 프로그래밍 - 불변성
    3. binarySearch(arr,target) : 이분 탐색하여 해당 값이 어느 인덱스에 있을지를 탐색하여 결과를 반환
  • 정규표현식을 사용하여 손쉽게 split하였다.
    .split(/ and | |-/i)

🤔 3. 느낀 점

문제를 풀면서, "이게 무슨 변수지"하면서 위에로 돌아가서 코드를 다시 읽은 것이 한 두번이 아니다. 앞으로는 위의 다른사람 풀이처럼 변수명을 직관적으로 "이 변수!"알 수 있도록 변수명을 짓도록 하자.

그리고, 이전에 함수화 시켜서 문제를 풀다가 풀이가 더 복잡해져서 한동안 하지 않았었는데, 다시보니 깔끔하고 실수가 더 줄것이라고 느꼈다. 상황에 따라 함수화를 잘 시켜보도록 하자.

🤩 4. 한 번 더 짚고 갈 점

어려웠다.. 쉽지 않았다. 다음 번에 꼭 이 문제를 다시 풀도록 하자. 그리고, 위의 young_paleete님의 풀이같은 "좋은 코드"를 자주 보도록 하자. 그리고, 따라하자. 따라하고, 변형하다보면 내 것이 될 것이다.

저작자표시 (새창열림)

'코딩 테스트 > 프로그래머스' 카테고리의 다른 글

[프로그래머스] 거리두기 확인하기  (0) 2023.05.14
[프로그래머스] 방금 그곡  (1) 2023.05.13
[프로그래머스] 후보키  (0) 2023.05.12
[프로그래머스] 문자열 압축  (0) 2023.05.11
[프로그래머스] 양궁대회  (1) 2023.04.30
[프로그래머스] 게임 맵 최단거리  (0) 2023.04.29
[프로그래머스] 이모티콘 할인행사  (0) 2023.04.28
[프로그래머스] 택배 배달과 수거하기  (0) 2023.04.27
  1. 📙 1. 문제
  2. 문제 설명
  3. 🌈 2.시작하며
  4. 풀이 과정 1 (시간 초과 풀이)
  5. 💻 결과
  6. 풀이 과정 2 : 객체 이용 but 시간초과
  7. 풀이 3 : 다른 사람 풀이
  8. 🤔 3. 느낀 점
  9. 🤩 4. 한 번 더 짚고 갈 점
'코딩 테스트/프로그래머스' 카테고리의 다른 글
  • [프로그래머스] 후보키
  • [프로그래머스] 문자열 압축
  • [프로그래머스] 양궁대회
  • [프로그래머스] 게임 맵 최단거리
피터s
피터s
1년차 프론트엔드 개발자입니다 😣 아직 열심히 배우는 중이에요! 리액트를 하고있어요 :) - gueit214@naver.com - https://github.com/gueit214
피터s
피터의 성장기록
피터s
전체
오늘
어제
  • 분류 전체보기 (200)
    • 코딩 테스트 (25)
      • 프로그래머스 (16)
      • LeetCode (8)
      • 백준 (1)
    • 개발 독서 일지 (1)
    • 기업 분석 (4)
    • 개발 일지 (19)
      • 최신기술 도전기 (1)
      • 에러 처리 (5)
      • 개발 일지 (12)
    • 개발 일상 (36)
      • 개발 회고 (22)
      • 개발 이야기 (12)
      • 개발 서적 (1)
    • 취업 관련 지식 (11)
    • 알고리즘 (17)
    • WebProgramming (84)
      • WebProgramming (8)
      • HTML (5)
      • CSS (8)
      • JS (21)
      • React (40)

블로그 메뉴

  • About
  • 2022년 개발 성장기
  • 앞으로의 계획
  • github
  • 일상 blog

공지사항

인기 글

태그

  • Kakao Tech Internship
  • 카카오 채용연계형 인턴십
  • 누적합
  • Union-find
  • dfs
  • 1일 1커밋 후기
  • Retry
  • KAKAO BLIND
  • 함수
  • lv3
  • 1년 회고
  • 반복문
  • 구름톤
  • 구름
  • 개발 is life
  • 스터디 후기
  • 개발 일상
  • 해커톤
  • LV2
  • 개발 회고
  • 카카오
  • BFS

최근 댓글

최근 글

hELLO · Designed By 정상우.
피터s
[프로그래머스] 순위 검색
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.