스터디 기록 15

유아현·2022년 12월 9일
0

Study

목록 보기
16/27
post-thumbnail

오늘의 스터디 문제 목록

❤️‍🔥 성격 유형 검사하기

❌ 실패 코드(테스트 케이스 실패)

function solution(survey, choices) {
    //! 1번 지표 라이언형(R), 튜브형(T)
    //! 2번 지표 콘형(C), 프로도형(F)
    //! 3번 지표 제이지형(J), 무지형(M)
    //! 4번 지표 어피치형(A), 네오형(N)
  
    // 각 지표에서 고른 점수를 받아 옴
    let surveyChoices = {};
    for (let i = 0; i < survey.length; i++) {
      surveyChoices[survey[i]] = choices[i];
    }
    //! output = {AN: 5, CF: 3, MJ: 2, RT: 7, NA: 5}

    //? 4를 기준으로 4면 0
    //? 4보다 작으면 0번째인덱스가 점수를 얻는다
    //? 4보다 크면 1번째 인덱스가 점수를 얻는다
  
    //! 1 매우 비동의 3점
    //! 2 비동의 2점
    //! 3 약간 비동의 1점
    //! 4 모르겠음 0점
    //! 5 약간 동의 1 점
    //! 6 동의 2점
    //! 7 매우 동의 3점
  
    let personality = { R: 0, T: 0, C: 0, F: 0, J: 0, M: 0, A: 0, N: 0 };
    for (let key in surveyChoices) {  
      //? 4보다 작으면 0번째인덱스가 점수를 얻는다
      if (surveyChoices[key] < 4) {
        if (surveyChoices[key] === 1)
          personality[key[0]] = personality[key[0]] + 3; //! 매우 비동의
        else if (surveyChoices[key] === 2)
          personality[key[0]] = personality[key[0]] + 2; //! 비동의
        else if (surveyChoices[key] === 3)
          personality[key[0]] = personality[key[0]] + 1; //! 약간 비동의
      }
  
      //? 4보다 크면 1번째 인덱스가 점수를 얻는다
      if (surveyChoices[key] > 4) {
        if (surveyChoices[key] === 5)
          personality[key[1]] = personality[key[1]] + 1; //! 약간 동의
        else if (surveyChoices[key] === 6)
          personality[key[1]] = personality[key[1]] + 2; //! 동의
        else if (surveyChoices[key] === 7)
          personality[key[1]] = personality[key[1]] + 3; //! 매우 동의
      }
    }
    console.log(personality);
    
    let result = "";
    
    //! expected output = {R: 0, T: 3, C: 1, F: 0, J: 0, M: 2, A: 1, N: 1}
    if (personality.R === personality.T) result += "R";
    else {
      personality.R > personality.T ? (result += "R") : (result += "T");
    }
    console.log(personality);
  
    if (personality.C === personality.F) result += "C";
    else {
      personality.C > personality.F ? (result += "C") : (result += "F");
    }
  
    if (personality.J === personality.M) result += "J";
    else {
      personality.J > personality.M ? (result += "J") : (result += "M");
    }
  
    if (personality.A === personality.N) result += "A";
    else {
      personality.A > personality.N ? (result += "A") : (result += "N");
    }
    return result;
  }
  
  solution(["AN", "CF", "MJ", "RT", "NA"], [5, 3, 2, 7, 5]);

처음에 작성했던 코드이다 무지막지 하나하나 하드코딩으로 되어있고 가독성이 굉장히 좋지 않다,,, 그렇지만 저렇게 말고 풀 방법이 생각나지 않았는걸 😥 코드 실행은 통과했으나 채점 돌려보니 테스트 케이스 절반 정도가 시간초과도 아니고 아예 실패라고 떠서 당황했다 머리가 더 이상 돌아가지 않아서 그냥 이 코드 그대로 스터디 때 들고 갔다. 스터디 코드 리뷰 시간이 끝나고 스터디원분들의 도움을 받아서 실패 이유를 찾을 수 있었다 😊 너무 고마워요! 캬캬 원인은 바로 내가 편하게 코드를 쓰고 싶어서 각 유형에 어떤 번호를 선택했는지 키와 값으로 survey와 choices를 객체로 만든 surveyChoices가 문제였다. surveyChoices를 선언한 후, {AN: 5, CF: 3, MJ: 2, RT: 7, NA: 5} 와 같이 survey를 키로 choices를 값으로 줬다. 그리고surveyChoices를 순회하면서 값만 불러와 choices가 4보다 작으면 키의 0번째 인덱스에 +를 해 주고 4보다 크다면 키의 1번째 인덱스에 +를 해 주는 방식으로 풀었다. 문제는 질문이 AN, AN, AN 나올 경우가 처리가 안 됐다는 것이다. 객체로 해 주었기 때문에 해당 키가 또 나올 경우 값이 재할당으로 바뀌어버리고 2~ 3번 실행해야 되는 질문이라면 최종적으로 한 번만 실행하게 된다는 것이다,,, 객체로 풀어보고 싶어서 도전했다가 크게 한방 당했다!! 그래도 이번에 키와 값에 접근하는 법과 조금 친근해진 기분이 든다,,,

⭕ 성공 코드

function solution(survey, choices) {
  //! 1번 지표 라이언형(R), 튜브형(T)
  //! 2번 지표 콘형(C), 프로도형(F)
  //! 3번 지표 제이지형(J), 무지형(M)
  //! 4번 지표 어피치형(A), 네오형(N)

  //? 4를 기준으로 4면 0
  //? 4보다 작으면 0번째인덱스가 점수를 얻는다
  //? 4보다 크면 1번째 인덱스가 점수를 얻는다
  //? 같으면 지표 첫번째 순서에 있는  유형이 출력

  let personality = { R: 0, T: 0, C: 0, F: 0, J: 0, M: 0, A: 0, N: 0 };
  let i = 0;
  for (let key of survey) {
    console.log(key); //!키
    console.log(choices[i]);

    choices[i] < 4
      ? (personality[key[0]] += 4 - choices[i])
      : (personality[key[1]] += choices[i] - 4);
    i++;
    console.log(personality);
    //! expected output = {R: 0, T: 3, C: 1, F: 0, J: 0, M: 2, A: 1, N: 1}

  }

  let result = '';

  if (personality.R === personality.T) result += 'R';
  else {
    personality.R > personality.T ? (result += 'R') : (result += 'T');
  }
  console.log(personality);

  if (personality.C === personality.F) result += 'C';
  else {
    personality.C > personality.F ? (result += 'C') : (result += 'F');
  }

  if (personality.J === personality.M) result += 'J';
  else {
    personality.J > personality.M ? (result += 'J') : (result += 'M');
  }

  if (personality.A === personality.N) result += 'A';
  else {
    personality.A > personality.N ? (result += 'A') : (result += 'N');
  }

  console.log(result);
  return result;
}

solution(['AN', 'CF', 'MJ', 'RT', 'NA'], [5, 3, 2, 7, 5]);

아무튼!! 저 부분을 수정하기 위해서 surveyChoices 객체는 그냥 삭제해버리고 어차피 survey와 choices의 인덱스 번호와 순서가 동일하기 때문에 i 변수를 새로 선언하여 0을 할당해 survey를 하나씩 순회할 때 choices[i]의 번호에 따라 점수를 부여하는 방식으로 바꾸었다. 점수 얻는 부분도 4 - 선택 번호로 해 주면 됐다는 걸 승연님 덕분에 이해가 팍팍 돼서 바로 바꿔버렸다 삼항연산자로 열 줄이 넘던 코드를 정리해서 기분이 좋군. 하지만 귀찮아서 밑에 결과 출력하는 if 지옥은 그대로 두었다. 나중에 리팩토링 해 보겠다... 메모

❤️‍🔥 신고 결과 받기

⭕ 성공 코드

function solution(id_list, report, k) {
  // 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템 개발
  //! 각 유저는 한번에 1명 유저 신고 ㄱㄴ
  //! 신고 횟수 제한 없음 서로 다른 유저 신고 ㄱㄴ
  //! k번 째 이상 신고 유저 정지 먹음 근데? 얘를 신고한 모든 유저한테 얘 정지했다고 메일 발송함

  //? 한 사람이 같은 사람을 여러번 신고한 경우는 신고 횟수가 1회니까 report의 중복을 제거
  const onlyReport = [...new Set(report)];
  //? id_list 수만큼 새 배열에 0 채우기
  const cnt = Array(id_list.length).fill(0);
  // console.log(cnt);
  // console.log(onlyReport);

  for (let i of onlyReport) {
    // 유저와 유저가 신고한 유저 구분
    i = i.split(" ");

    // 그 중 신고받은 유저만 추출
    let getReport = i[1];
    //   console.log(getReport);

    let getReportIdx = id_list.indexOf(getReport); //! 신고 받은 유저 IDX 찾아서 해당 인덱스 카운트
    cnt[getReportIdx]++; //! 신고 횟수 카운트
  }
  // console.log(id_list);
  // console.log(cnt);

  //! K번 이상이면 게시판 이용 정지
  let unavailable = []; //? 게시판 이용 정지를 당한 유저를 담을 배열 선언
  for (let i = 0; i < cnt.length; i++) {
    if (cnt[i] >= k) unavailable.push(id_list[i]);
  }
  // console.log(cnt);
  // console.log(unavailable);

  //! 정지당한 유저를 신고한 유저에게 메일을 발송
  //? id_list 수만큼 새 배열에 0 채우기
  const mail = Array(id_list.length).fill(0);

  for (let i of onlyReport) {
    i = i.split(" ");
    //! 유저
    let id = i[0];
    //   console.log(id);
    //! 신고한 유저
    let getReport = i[1];
    //   console.log(getReport);
    //! 신고한 유저의 indexOf 했을 때 인덱스가 추출된다면 유저가 신고했다는 것
    if (unavailable.indexOf(getReport) >= 0) {
      //! 유저의 인덱스 가져오기
      let userIdx = id_list.indexOf(id);
      //! 해당 유저에 count
      mail[userIdx]++;
    }
  }
  // console.log(mail);

  return mail;
}

solution(
  ["muzi", "frodo", "apeach", "neo"],
  [
    "muzi frodo",
    "muzi frodo",
    "muzi frodo",
    "apeach frodo",
    "frodo neo",
    "muzi neo",
    "apeach muzi",
  ],
  2
);
// solution(["con", "ryan"],["ryan con", "ryan con", "ryan con", "ryan con"], 3)

한 유저가 다른 한 유저를 여러 번 신고할 경우 2, 3번을 하든 그 이상을 신고해도 1회로 처리하기 때문에 Set 객체를 통해서 중복을 제거해 준다. 유저의 수만큼 0을 채운 배열 cnt을 선언해 이 인덱스 위치는 곧 id_list의 인덱스 위치와 같기 때문에 신고당한 유저의 인덱스에 카운트를 해 주어 카운트를 다 끝내고 K보다 큰 유저들은 게시판 이용 정지 대상 유저로 unavailable에 push 해 주었다. 이제 정지 유저를 신고한 유저들에게 메일을 보내기 위해 신고당한 유저에 인덱스에 카운트 해 준 것과 같이 유저의 수만큼 0을 채운 배열 mail을 선언하고 유저가 정지 유저를 신고했다면 해당 유저의 인덱스를 추출해 mail에 적용해 카운트 시켜 해당 mail 배열을 리턴시켜주었다.

❤️‍🔥 햄버거 만들기

![](https://velog.velcdn.com/images/youa7878/post/4da6ba1f-cc8b-4321-ad40-bb549b9fbf02/image.png

❌ 시간 초과 코드(테스트 케이스 시간 초과)

function solution(ingredient) {
  //! 빵 - 야채 - 고기 - 빵
  //! 1 === 빵
  //! 2 === 야채
  //! 3 === 고기
  //? 1-2-3-1 순으로 쌓인 햄버거만 포장해야 됨

  ingredient = ingredient.join("");
  console.log(ingredient);
  // ingredient = ingredient.replace(/1231/g, "") 1231을 삭제해 주는 걸 반복

  let cnt = 0;

  for (let i = 0; i < ingredient.length; i++) {
    let before = ingredient;

    ingredient = ingredient.replace(/1231/g, "");
    // 처음 들어온 상태에서 replace가 먹혔다면 문자열 길이의 변화가 있다는 것, 1231이 존재한다는 의미
    // 햄버거 포잠했으니 cnt++ 해 줌
    if (before.length !== ingredient.length) cnt++;
  }

  console.log(cnt);
  console.log(ingredient);

  return cnt;
}

solution([2, 1, 1, 2, 3, 1, 2, 3, 1]);

// solution([1,  3,  2,  1,  2,  1, 3,  1, 2])

처음엔 인자로 배열을 받고 있어 join을 해 주고 정규식을 사용하여 1231이 있다면 삭제해 주는 식으로 풀었다. 근데 replace를 몇 번 해 줘야 될지 모르겠어서 ingredient의 길이만큼만 돌려도 충분하므로 해당 길이만큼 해줬더니 테스트는 통과했지만 시간 초과로 정답 처리가 안 됐다 속상~ 그래서 이 방법말고 스택으로 해야겠다 싶어서 스택으로 다시 풀어 보았다.

⭕ 성공 코드

function solution(ingredient) {
  // 조인하고 넣은 재료 수만큼 반복 돌려서 정규식으로 거르자 (실패! 시간 초과)
  // 조인하고 split 기준으로 1231 나눠보자 (위랑 똑같을 것 같음)
  // 스택? 으로 풀어보셈
  // 하나씩 넣어서 마지막 -4번째 인덱스까지가 1231이면 pop 4번 ㄱ

  //! 빵 - 야채 - 고기 - 빵
  //! 1 === 빵
  //! 2 === 야채
  //! 3 === 고기
  //? 1-2-3-1 순으로 쌓인 햄버거만 포장해야 됨

  const pack = [];
  let cnt = 0;

  // let i = ingredient.slice(-4);
  // console.log(i)

  for (let i of ingredient) {
    //! 재료를 하나씩 넣는다
    pack.push(i);
    //! 4가지 이상의 재료가 들어가면 마지막 -4번째 인덱스까지가 1231이면 pop 4번
    if (pack.length >= 4) {
      const hamburger = pack.slice(-4).join("");
      // console.log(hamburger);
      if (hamburger === "1231") {
        cnt++;
        pack.pop();
        pack.pop();
        pack.pop();
        pack.pop();
      }
    }
  }
  console.log(cnt);
  return cnt;
}

solution([2, 1, 1, 2, 3, 1, 2, 3, 1]);

pack에 하나씩 재료를 push 하여 담고 pack에 담긴 재료가 4 이상이라면 slice를 사용해 -4 인덱스 위치까지 잘라낸(제일 마지막부터 4번째까지)가 1231이라면 pop을 4번 시켜 주어 빼주고 카운트를 시켜 주었다.

function solution(ingredient) {
    // 아래부터, 1 빵 - 2 야채 - 3 고기 - 1 빵
    // if 버거 -> splice, bugerCnt++, i = stack.pop() || 0
    // else -> 빵 index를 stack에 저장하고 i++
    const burger = [1, 2, 3, 1];
    let burgerCnt = 0;
    let breadIdxStack = [];
    for (let i = 0; i <= ingredient.length - 4;) {
        if (burger.every((el, idx) => el === ingredient[i + idx])) {
            ingredient.splice(i, 4);
            burgerCnt++;
            i = breadIdxStack.pop() || 0;
            continue;
        } else {
            if (ingredient[i] === 1) breadIdxStack.push(i);
            i++;
        }
    }
    return burgerCnt;
}

해당 코드는 민혁님의 코드이며 접근 방법이 좋아서 가지고 왔다...!


스터디를 진행한 지 한 달이 넘어가는 시점에서 벌써 프로그래머스 1단계 완주에 성공했다! (새로운 문제가 하나 추가됐긴 하지만) 알고리즘 스터디를 진행하면서 많이 성장했다고 생각하고 있고 스터디를 하길 잘했다는 만족감이 있어서 좋당 ㅎㅎ 2단계를 이어서 도전하는데 이번에는 정답률 높은 순서가 아닌 최신순으로 풀기로 했어서 난이도가 들쑥날쑥 할 것 같다 매일 긴장해야 될 듯,,, ㅋㅋㅋ 풀지 못하더라도 도전하는 것에 의미를 두기로 했다 앞으로도 파이팅~😊

0개의 댓글