이번 주는 알고리즘 및 언어 학습 주차라 알고리즘 문제를 많이 풀게 되었다.
오늘은 개인적으로는 1문제만 풀었고
스터디 팀원들끼리 풀었던 문제들에 대해 대화를 나누고 코드리뷰하는 시간을 가졌다.
재밌는 문제라 간단하게 리뷰해보려 한다.
문제를 요약하면 우리가 잘 알고 있는 핸드폰 키패드가 있고
오른손잡이 또는 왼손잡이인 사람이 그걸 누르는데
눌러야하는 숫자가 주어지고 무슨 손가락으로 눌렀는지를 구하는 문제이다.
중앙에 있는 버튼들은 현재 왼손/오른손 중 가까운 위치에 있는 손으로 누르거나 거리가 같을 경우 본인의 주요 손을 사용해 눌러야 한다.
const PHONE = {
"1": {"hand": "L", "loc": [0,0]},
"2": {"hand": "", "loc": [0,1]},
"3": {"hand": "R", "loc": [0,2]},
"4": {"hand": "L", "loc": [1,0]},
"5": {"hand": "", "loc": [1,1]},
"6": {"hand": "R", "loc": [1,2]},
"7": {"hand": "L", "loc": [2,0]},
"8": {"hand": "", "loc": [2,1]},
"9": {"hand": "R", "loc": [2,2]},
"0": {"hand": "", "loc": [3,1]},
};
const handState = (hand) => {
const hands = {"L": [3, 0], "R": [3,2]};
const history = [];
const defaultHand = hand[0].toUpperCase();
function push(pad) {
const hand = PHONE[pad].hand || findNearHand(PHONE[pad].loc);
history.push(hand);
hands[hand] = PHONE[pad].loc;
}
function getHistory() {
return history;
}
function findNearHand(loc) {
const leftDist = Math.abs(loc[0] - hands.L[0]) + Math.abs(loc[1] - hands.L[1]);
const rightDist = Math.abs(loc[0] - hands.R[0]) + Math.abs(loc[1] - hands.R[1]);
if(leftDist > rightDist) {
return "R";
}
if(leftDist < rightDist) {
return "L";
}
return defaultHand;
}
return {getHistory, push}
}
function solution(numbers, hand) {
const myHand = handState(hand);
numbers.forEach(v => myHand.push(v));
return myHand.getHistory().join("");
}
복잡한 로직 자체는 없지만 문제가 꽤 길고 요구하는 것을 세심하게 읽은 뒤 코드로 옮겨야 하는 시간이 오래걸리는 문제였다.
키패드 정보는 절대 변하지 않는 부분이기 때문에 상수로 직접 한땀한땀 정의해주었다.
주어지는 주요 손(왼쪽/오른쪽) 정보를 입력받아 handState
라는 현재 손 위치
, 키패드 클릭 기록
, 주요 손
이라는 속성을 가지고 동작을 처리하는 클로저 함수를 할당해 사용했다.
주어지는 눌러야되는 키패드 정보를 순회하며 클로저 내부의 history 기록을 쌓아가고 이를 리턴하도록 구현했다.
자바로 이런 문제를 풀 때는 항상 클래스나 열거형 자료를 사용해서 풀었었는데
자바스크립트의 클로저 함수로 클래스 역할을 시키고 상수 오브젝트로 열거형 객체 역할을 시키도록 하여 해결한 것 같다.
간단하게 풀기 어려웠던 문제라던가 이런 부분들을 이야기하고 어떻게 풀었는지 공유하는 시간을 가졌다.
아직 자바스크립트 코드는 다른사람의 코드를 보고 의도를 파악하는데 시간이 너무 오래걸리는 것 같다.
얼른 익숙해져서 한 문제에 대해 접근하는 또 다른 방법들을 빠르게 익혀가고
코드에서 잘 안되는 부분을 찾아 해결해나갈 수 있도록 강해져야겠다.
사실 알고리즘 문제는 프로그래밍 시험인지 국어 독해 시험인지 헷갈릴만한 문제들이 많다.
멘토님께서 지문이 긴 문제의 경우 따로 캡쳐한다던가 해서 두고 구문 하나하나 확인하며 중요한 부분들을 체크해두고 확인해보며 풀이해보라고 팁을 주셨다.
항상 한두군데 지문을 놓쳐서 케이스 몇 개 틀리고 그런적이 많았는데
긴 지문인 문제를 풀 때 주요 내용들을 기록해두는 습관을 들여봐야겠다.
스타일 연습하기
사실 프론트쪽 UI 만들때 flex
나 그리드 만들기에 대한 지식이 없어서 늘 고통받았던 기억이 있다.
멘토님께서 이것들을 연습할 수 있는 유용한 사이트를 소개해주셨다.
잠깐 머리식히고 싶을 때 들어가서 연습해봐야겠다!