이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
- 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
- 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
- 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
- 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.
https://programmers.co.kr/learn/courses/30/lessons/67256
코딩테스트 연습 - 키패드 누르기
[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] "right" "LRLLLRLLRRL" [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] "left" "LRLLRRLLLRR" [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] "right" "LLRLLRLLRL"
programmers.co.kr
푸는 걸 시도한 흔적
function solution(numbers, hand) {
let pad = [[1,2,3],[4,5,6],[7,8,9],['x',0,'x']];
console.log(pad);
if(hand === 'right') hand = 'R';
else hand = "L";
var answer = '';
let left = [3,0];
let right = [3,2];
for(let i = 0; i<numbers.length; ++i) {
if(numbers[i]===1||numbers[i]===4||numbers[i]===7) {
answer += 'L';
left = [(numbers[i]-1)/3,0]; // 2차원 배열로 봤을 때 인덱스 저장
} else if(numbers[i]===3||numbers[i]===6||numbers[i]===9){
answer += 'R';
right = [(numbers[i]-3)/3,2];
// 오른손이 3을 찍었으면 right는 [0,2]가 찍혀야해
// 6을 찍었으면 right는 [1,2] , 9를 찍으면 [2,2]
} else { // 2,5,8,0
console.log("2,5,8,0",numbers[i])
// 이전 손들의 위치, 지금 찍어야할 숫자
if(numbers[i]===0) {
if(Math.abs(Math.abs(left[0]-3+Math.abs(left[1]-1), Math.abs(right[0]-3)+Math.abs(right[1]-1)))>0) {
answer += 'L';
right = [(numbers[i]-2)/3,1];
} else if(Math.abs(Math.abs(left[0]-3)+Math.abs(left[1]-1), Math.abs(right[0]-3+Math.abs(right[1]-1)))<0) {
answer += 'R';
left = [(numbers[i]-2)/3,1];
} else {
answer += hand;
}
}
console.log(left, right, numbers[i]);
console.log([(numbers[i]-2)/3,1]) // 이걸 이차원 배열로 나타내면?
console.log(Math.abs(left[0]-(numbers[i]-2)/3)+Math.abs(left[1]-1), Math.abs(right[0]-(numbers[i]-2)/3+Math.abs(right[1]-1))) // 빼기 했을 때 0보다 크면 오른쪽이 누른다.
if(Math.abs(Math.abs(left[0]-(numbers[i]-2)/3)+Math.abs(left[1]-1), Math.abs(right[0]-(numbers[i]-2)/3+Math.abs(right[1]-1)))>0) {
answer += 'L';
right = [(numbers[i]-2)/3,1];
} else if(Math.abs(Math.abs(left[0]-(numbers[i]-2)/3)+Math.abs(left[1]-1), Math.abs(right[0]-(numbers[i]-2)/3+Math.abs(right[1]-1)))<0) {
answer += 'R';
left = [(numbers[i]-2)/3,1];
} else {
answer += hand;
}
}
}
console.log(answer, "이게?")
return answer;
}
solution([1, 0, 3, 4, 5, 6, 7, 8, 9, 0], "right");
let sum = 1+'1';
console.log(sum);
마지막 문제.. 40일 도전의 마지막 ~~~
왼쪽으로 세 칸 이동한 것은 위로 한 칸 이동한 것과 같다 ,, 헉 충 격 . . . .
3으로 나누고 한 칸 남으면 그 나머지 값으로 왼쪽이나 오른쪽으로 이동해야겠지.
// 멘토님 풀이
const leftNumbers = [1, 4, 7]; // 왼쪽 키패드에 해당하는 숫자들을 배치
const rightNumbers = [3, 6, 9];
function solution(numbers, hand) {
let answer = "";
// 두 엄지손가락이 어떤 위치에 있는지를 저장
// 1번에서 얼마나 떨어져있는지를 볼 것임
const current = {
left : 10, // 9칸 + 자기 자신1
right : 12,
}
for(let i = 0; i < numbers.length; ++i) {
console.log(numbers[i]);
if(leftNumbers.includes(numbers[i])) {
// 누를 번호가 왼쪽 키패드에 해당된다면 (= 왼손 엄지손가락으로 누른다.)
answer += "L";
current["left"] = numbers[i];
} else if(rightNumbers.includes(numbers[i])) {
answer += "R";
current["right"]= numbers[i];
} else {
// 가운데 키패드
const locationObj = {...current}; // 왼손과 오른손의 위치 저장
// 객체를 반복할거야
for(let hand in locationObj) {
numbers[i] = numbers[i] === 0 ? 11 : numbers[i]
let location = Math.abs(numbers[i]-locationObj[hand])
// 가운데 키패드로부터 얼마나 떨어져있는지 구한다.
console.log(hand, locationObj[hand]) // hand라는 이름으로 key를 가져옴 왼쪽과 오른쪽의 위치를 차례대로 가져와본다.
// 거리 차이가 3칸 이상일 때는 위 아래로 이동할 수 있다!!!
if(location>=3) {
location = Math.trunc(location / 3) + location%3; // 소수점 제거
}
locationObj[hand] = location;
}
if(locationObj["left"]===locationObj["right"]) {
answer += hand === "left" ? "L" : "R";
current[hand] = numbers[i];
// console.log(numbers[i], locationObj, hand)
} else {
// 오른손 엄지손가락이 더 가까운 경우
if(locationObj["left"]>locationObj["right"]) {
answer += "R";
current["right"] = numbers[i];
} else { // 왼손 엄지가 더 가까운 경우
answer += "L";
current["left"] = numbers[i];
}
}
}
}
return answer;
}
solution([1, 0, 3, 4, 5, 6, 7, 8, 9, 0], "right");
키 : arr[0][0], arr[1][0]
밸류 : arr[1][0], arr[1][1]
entries
values, keys (밸류만/키만 뽑는다)
// 멘토님 풀이 메서드
// const leftNumbers = [1, 4, 7]; // 왼쪽 키패드에 해당하는 숫자들을 배치
// const rightNumbers = [3, 6, 9];
const [leftNumbers, rightNumbers] = [[1,4,7],[3,6,9]]; // 비구조화 할당
function solution(numbers, hand) {
const current = {
left : 10, // 9칸 + 자기 자신1
right : 12,
}
return numbers.reduce((acc, cur)=> {
// 어떤 손가락으로 눌렀는지에 대한 최종 결과값("L","R")
// 어떤 손으로 눌렀는지에 대한 결과값("left", "right")
let [useFinger, target] = [ "", "" ];
if(leftNumbers.includes(cur)) {
[useFinger,target] = ["L", "left"];
} else if(rightNumbers.includes(cur)) {
[useFinger,target] ["R", "right"];
} else {
const locationObj = Object.entries(current).reduce((acc2,cur2)=> {
cur = cur === 0 ? 11 : cur;
console.log(acc2,cur2, cur); // cur은 눌러야 할 번호
let location = Math.abs(cur - cur2[1]);
// console.log(acc2, cur2, cur, location);
if(location >= 3) {
location = Math.trunc(location / 3) + location%3;
}
acc2[cur2[0]] = location;
return acc2;
},{})
console.log(locationObj,cur); // cur를 눌러야할 때의 왼쪽손과 오른쪽 손이 있는 곳과 타겟이 몇 칸 차이나는지
if(locationObj["left"]===locationObj["right"]) {
[useFinger, target] = [ hand === "left" ? "L" : "R", hand]
}
console.log(locationObj);
} else if(locationObj["left"]>locationObj["right"]) {
[useFinger, target] = ["R", "right"]
} else {
[useFinger, target] = ["L","left"];
}
current[target] = cur;
return acc + useFinger;
},"")
}
solution([1, 0, 3, 4, 5, 6, 7, 8, 9, 0], "right");
멘토님이 접근법은 괜찮은 것 같은데 중복된 코드가 일단 너무 많아서 정리해보면 좋을 것 같다고 하셨다.
그리고 객체로 접근하는게 더 쉬울 수도 있다고..!!
여기서 객체로 접근한 이유는 왼손이랑 오른손 위치 둘 다 해결하기 위해서고,
첫번째 풀이방법에서 current는 현재 손의 위치고 그걸 복사해서 얼마나 떨어져있는지 구하는 것
'프론트엔드✏️ > 코드캠프' 카테고리의 다른 글
중첩된 배열구조 - flatten, unflatten (0) | 2022.06.30 |
---|---|
재귀 함수(recursive function) (0) | 2022.06.30 |
220630 프론트엔드 부트캠프 51일차 : 동적 배포 마무리, Docker (0) | 2022.06.30 |
도커(Docker) 고래 모양 그거 (0) | 2022.06.30 |
Javascript vs TypeScript (0) | 2022.06.30 |