알고리즘이 너무 어려울 땐 - 4일차 회고

도합 10시간이 넘도록 고민한 문제가 있다.
잘 풀고 있다가 이 한 문제부터 갑자기 머릿속이 새하얘졌다.

테스트 케이스를 돌릴 때마다 기도해본적이 없었는데,
이번 문제 만큼은 정말 속을 많이 썩였다..!

어떤 문제?

자바스크립트 풀이 30번

객체와 배열을 인자로 받는 함수를 구현하고

{
  '생활속의회계': 'C',
  '논리적글쓰기': 'B',
  '독일문화의이해': 'B+',
  '기초수학': 'D+',
  '영어회화': 'C+',
  '인지발달심리학': 'A+',
}

['영어회화', '기초수학', '공학수학', '컴퓨터과학개론']
  

아래 기준표에 따라 value값을 수정해
새로운 객체로 반환해주는 문제다.

A+ => 4.5
A => 4
B+ => 3.5
B => 3
C+ => 2.5
C => 2
D+ => 1.5
D => 1
F => 0

예시 결과를 보자면 다음과 같다

{
  '생활속의회계': 2,
  '논리적글쓰기': 3,
  '독일문화의이해': 3.5,
  '기초수학': 1.5,
  '영어회화': 2.5,
  '인지발달심리학': 4.5,
  '공학수학': 0,
  '컴퓨터과학개론': 0,
}

사고 과정 (사용 도구 정리)

우선 문제를 보자마자, 마땅한 방법이 보이지 않았다.
다른 사람들의 답지를 봐도, 머릿속에 들어오지 않았고
내 언어로 쓰여지지 않으니, 과정이 명확하게 그려지지도 않았다.

아무리 좋은 말이 있다 한들, 내 언어로 느끼지 못하면 흘러 나가는 것 처럼 말이다.

객체를 배열로 바꿔보기도 했고,
배열을 다시 객체로 할당해서 풀어보려고도 했다.
그러면서 지나온 과정들을 모두 되돌아보자


객체끼리 비교해보자!

먼저 자바스크립트 object 비교라는 키워드로 검색했고
json으로 된 object를 일반 object에 비교하는 방법을 볼 수 있었다.
좋은 정보였지만,

내가 원하는 것은 obj1의 key와 obj2의 value를 비교하는 걸 원했다.
그러나 모든 문제가 내 입맛에 맞춰서 들어올 순 없기에, 하나하나씩 분리한 후 키워드를 다시 검색했다.


배열로 변환해서 비교하는 건,,?

다음 방법은 기준 표를 sample이라는 이름으로 들고와서 함수 내에 새로운 객체로 선언해주었다.

왜?

해당 자료를 배열로 변환하면 기준이 되는 점수표를 한번씩 검토할 수 있는 반복문 생성이 용이할 듯 했다.
생각해보면 애초에 배열로 들고와도 됐지만, entries()를 써보고 싶기도 했다.

entries()를 사용하면 다차원 배열로 변환될 것이고 이를 인덱스 값으로 접근하면,
내가 아는 코드로 적히면서, 혼선을 줄일 수 있을 듯 했다.

const getExamResult = (scores, requiredClasses) => {
   let Sample = {
       'A+' : 4.5,
       'A' : 4,
       'B+' : 3.5,
       'B' : 3,
       'C+' : 2.5,
       'C' : 2,
       'D+' : 1.5,
       'E' : 1,
       'F' : 0
    }
   
    let sample = Object.entries(Sample);
    let result = {};
}

이렇게 풀어주면 해당 객체가

[
  ['A+' : 4.5]
  ...
	]

이런 배열로 만들어진다.
이제 이 배열을 활용해서 scores의 객체를 훑으며 value 값을 바꿔주는 방법을 찾아보자

객체 수정

JavaScript 객체 수정
objectName[key]를 통해 value 값을 수정할 수 있다는 것을 알 수 있었다.

객체 순환 방법

js 객체 순환이라 검색하니 위해서는 for-in을 통해서 가능하다는 것을 알 수 있었다.
Es6에서 새롭게 추가된 문법으로 자바스크립트 엔진 내부에서 자동으로 결정하고 i를 초기화하고 길이 비교, 1씩 증가시키는 과정을 이 방법으로 퉁칠 수 있다고 한다.


풀이 방법

도구를 모았으니 이제 논리를 세워보자.
문제에 필요한 데이터를 다시 한 번 취합해보자.

const getExamResult = (scores, requiredClasses) => {
  	
    }

  let a = {
    '생활속의회계': 'C',
    '논리적글쓰기': 'B',
    '독일문화의이해': 'B+',
    '기초수학': 'D+',
    '영어회화': 'C+',
    '인지발달심리학': 'A+',
  }

  let b = ['영어회화', '기초수학', '공학수학', '컴퓨터과학개론']

  getExamResult(a, b)
  1. 함수 내부에 성적 기준표(sample) 을 객체로 만들어준다.
    이후엔 result라는 빈 객체를 만들어준다.
  • 새로운 객체에 할당해서 반환해야하기 때문에!
  1. sample을 배열로 변환해, 반복문이 순차적으로 먹히게 해준다.
  2. samplescores를 서로 검증하게 한다. for in을 돌려서 객체에 있는 key값과 sample의 [0]을 비교한다
  3. 만약 scores의 value가 sample의 key가 일치할 경우, sample의 인덱스[1]을 들고온다.
  4. 들고온 인덱스 값을 let result 변수에 value로 할당해준다.

다음은 필수 과목을 만들어주기 위한 논리를 짜보자

  1. 반복문을 requiredClasses의 수만큼 돌아가도록 작성
  • 그래야지 과목이 더 추가되도 검증이 가능하니까!
  1. 반복문에서 돌린 requiredClasses[j] 값을 newKey라는 변수에 할당해준다.
  2. 해당 과목이 없는 경우, result에 새로운 프로퍼티를 만들어주고 0을 할당한다.

이렇게 크게 두 파트로 나누고 하나씩 순차적으로 적용했다.


실제 코드

  const getExamResult = (scores, requiredClasses) => {
    let Gsample = {
       'A+' : 4.5,
       'A' : 4,
       'B+' : 3.5,
       'B' : 3,
       'C+' : 2.5,
       'C' : 2,
       'D+' : 1.5,
       'E' : 1,
       'F' : 0
    }

    let sample = Object.entries(Gsample);
    let result = {};

    for (let j = 0; j < requiredClasses.length; j ++){
      let newKey = requiredClasses[j]
      result[newKey] = 0; 
    }

    for (let key in scores){
      let A = scores[key]
        for(let i = 0; i < sample.length; i++){
          if(A == sample[i][0]){
            A = sample[i][1]
            result[key] = A;
          }
        }
      // result[key] = [scores[key]];
      // console.log(result);
    }
  return result

돌아는가지만,,

물론 테스트 케이스가 잘 작동하긴했다.
그러나 마음에 걸리는 것이 있다면, 중복되는 값이나 변형된다면 다시 한번 가로막힐 듯 하다.

시도한 테스트케이스가 한개 밖에 없어서 아무래도 잘 통과된 걸 수 도 있겟다는 생각이 들었다.


회고

동료에게 '잘' 물어보자!

문제를 풀려고 혼자서 끙끙대다, 동기들에게 계속해서 검증해나가는 과정을 거쳤다.
내 생각이 맞는건지, 오류는 없는건지?에 대한 의문이 계속 들 수 밖에 없었다.

"OO님 저는 이런 방법을 사용하면 ~~이런 결과 값이 나와요. 여기서 이렇게 하면 해당 결과값이 바뀐다고 해요. 혹시 아실까요?! "
"혹시 해당 메서드를 사용한 이유가 있을까요?"

혹시라도 풀었다면 어떤 방식으로 접근했고, 왜 그렇게 생각했는지를 물었다.
그리고 내 코드에 대한, 의견에 대한 이상한 점을 지적해달라고 부탁했다.
(시간이 괜찮은 분들에 한해서만..)

정답을 알려달라고 하기 보단,사고의 근거를 물어 보는 것이
J 커브를 그릴 수 있는 방법이라 느꼈다.

무엇보다 내가 뭐때문에 고민하고 있는지,
어떤 접근 법에서 막히는 지를 물어볼 수 있는 역량을 기를 수 있었다.

여러모로 시간이 오래 걸려서 기억에 남는 문제기도 하지만,
해당 문제 덕에, 여러 사람과 폭 넓은 대화를 할 수 있게 만들어준 것이 더 큰 의미로 남았다.

앞으로 비슷한 문제를 마주한다면 ?

빠르게 시도하고 검증한 다음,
모든 시도에 대한 이유를 간략하게나마 메모해두자.

검색어를 찾게된 계기부터, 동료에게 질문하는 이유와 의도까지 기록해야겠다.

빠르게 시도하고 빠르게 실패해서 최대한 많은 케이스를 확보한 다음 질문하자.


좋은 웹페이지 즐겨찾기