diff --git a/bona1122/[week4]Hash/Discount_event.js b/bona1122/[week4]Hash/Discount_event.js new file mode 100644 index 0000000..25fc92f --- /dev/null +++ b/bona1122/[week4]Hash/Discount_event.js @@ -0,0 +1,60 @@ +// 방법 1: 매번 slice로 새 배열과 객체를 생성 +function solution1(want, number, discount) { + let answer = 0 + const map = want.reduce((map, name, idx) => { + map[name] = number[idx] + return map + }, {}) + + const check = (sale) => { + for (let item in map) { + if (map[item] !== sale[item]) return false + } + return true + } + + for (let i = 0; i <= discount.length - 10; i++) { + const sliced = discount.slice(i, i + 10) + const sale = sliced.reduce((map, name) => { + map[name] = (map[name] || 0) + 1 + return map + }, {}) + + if (check(sale)) answer++ + } + + return answer +} + +// 방법 2: 슬라이딩 윈도우 +function solution2(want, number, discount) { + const need = want.reduce((obj, name, idx) => { + obj[name] = number[idx] + return obj + }, {}) + + // 초기 윈도우(첫 10일) 설정 + const sale = {} + for (let i = 0; i < 10; i++) { + sale[discount[i]] = (sale[discount[i]] || 0) + 1 + } + + const check = () => { + for (let item in need) { + if (need[item] !== sale[item]) return false + } + return true + } + + let answer = check() ? 1 : 0 + + // 슬라이딩 윈도우 이동 + for (let i = 10; i < discount.length; i++) { + sale[discount[i]] = (sale[discount[i]] || 0) + 1 // 새로운 것 추가 + sale[discount[i - 10]]-- // 이전 것 제거 + + if (check()) answer++ + } + + return answer +} diff --git a/bona1122/[week4]Hash/Incomplete_runner.js b/bona1122/[week4]Hash/Incomplete_runner.js new file mode 100644 index 0000000..3089e1c --- /dev/null +++ b/bona1122/[week4]Hash/Incomplete_runner.js @@ -0,0 +1,15 @@ +// 완주자 목록으로 해시맵 생성 +const solution = (participant, completion) => { + const completionMap = completion.reduce((map, person) => { + map[person] = (map[person] || 0) + 1 + return map + }, {}) + + return participant.find((person) => { + if (completionMap[person]) { + completionMap[person]-- + return false + } + return true + }) +} diff --git a/bona1122/[week4]Hash/Keypad_press.js b/bona1122/[week4]Hash/Keypad_press.js new file mode 100644 index 0000000..e9845b0 --- /dev/null +++ b/bona1122/[week4]Hash/Keypad_press.js @@ -0,0 +1,119 @@ +// 방법 1: 객체기반 접근(각 숫자의 좌표 직접 매핑 - 하드코딩) +function solution1(numbers, hand) { + const keypad = { + 1: [0, 0], + 2: [0, 1], + 3: [0, 2], + 4: [1, 0], + 5: [1, 1], + 6: [1, 2], + 7: [2, 0], + 8: [2, 1], + 9: [2, 2], + "*": [3, 0], + 0: [3, 1], + "#": [3, 2], + } + + let left = keypad["*"] + let right = keypad["#"] + + const getDist = ([y1, x1], [y2, x2]) => Math.abs(y1 - y2) + Math.abs(x1 - x2) + + return numbers + .map((num) => { + const target = keypad[num] + + // 왼쪽 열이면, 왼손 + if (target[1] === 0) { + left = target + return "L" + } + // 오른쪽 열이면, 오른손 + if (target[1] === 2) { + right = target + return "R" + } + + // 가운데열의 경우, 거리 비교 + const leftDist = getDist(left, target) + const rightDist = getDist(right, target) + + if (leftDist === rightDist) { + if (hand === "right") { + right = target + return "R" + } + left = target + return "L" + } + + if (leftDist < rightDist) { + left = target + return "L" + } else { + right = target + return "R" + } + }) + .join("") +} + +// 방법 2: 2차원 배열로 실제 키패드 모양 표현 후, 좌표 매핑 +function solution2(numbers, hand) { + // 키패드를 2차원 배열로 정의 + const keypad = [ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9], + ["*", 0, "#"], + ] + + // 키패드를 좌표로 매핑 + const getPos = new Map( + keypad.flatMap((row, y) => row.map((num, x) => [num, [y, x]])) + ) + + let left = getPos.get("*") + let right = getPos.get("#") + + const getDist = ([y1, x1], [y2, x2]) => Math.abs(y1 - y2) + Math.abs(x1 - x2) + + return numbers + .map((num) => { + const target = getPos.get(num) + + // 왼쪽 열이면, 왼손 + if (target[1] === 0) { + left = target + return "L" + } + // 오른쪽 열이면, 오른손 + if (target[1] === 2) { + right = target + return "R" + } + + // 가운데 열 + const leftDist = getDist(left, target) + const rightDist = getDist(right, target) + + if (leftDist === rightDist) { + if (hand === "right") { + right = target + return "R" + } + left = target + return "L" + } + + if (leftDist < rightDist) { + left = target + return "L" + } else { + right = target + return "R" + } + }) + .join("") +} diff --git a/bona1122/[week4]Hash/Memory_score.js b/bona1122/[week4]Hash/Memory_score.js new file mode 100644 index 0000000..dc0ef45 --- /dev/null +++ b/bona1122/[week4]Hash/Memory_score.js @@ -0,0 +1,8 @@ +const solution = (name, yearning, photo) => { + const map = name.reduce((map, name, idx) => { + map[name] = yearning[idx] + return map + }, {}) + + return photo.map((p) => p.reduce((acc, cur) => (acc += map[cur] || 0), 0)) +} diff --git a/bona1122/[week4]Hash/Open_chat.js b/bona1122/[week4]Hash/Open_chat.js new file mode 100644 index 0000000..e65f816 --- /dev/null +++ b/bona1122/[week4]Hash/Open_chat.js @@ -0,0 +1,18 @@ +function solution(record) { + const userInfo = {} + const result = [] + const MESSAGES = { + Enter: "님이 들어왔습니다.", + Leave: "님이 나갔습니다.", + } + + record.forEach((r) => { + const [action, id, name] = r.split(" ") + if (name) userInfo[id] = name + if (action !== "Change") { + result.push([id, MESSAGES[action]]) + } + }) + + return result.map(([id, message]) => userInfo[id] + message) +} diff --git a/bona1122/[week4]Hash/Phonekemon.js b/bona1122/[week4]Hash/Phonekemon.js new file mode 100644 index 0000000..0476659 --- /dev/null +++ b/bona1122/[week4]Hash/Phonekemon.js @@ -0,0 +1,21 @@ +// 1. 해시맵을 이용한 풀이 +const solution1 = (nums) => { + let max = 0 + const can = nums.length / 2 + const map = nums.reduce((map, num) => { + if (map[num] === undefined) { + max++ + map[num] = 1 + } + return map + }, {}) + return can < max ? can : max +} + +// 2. Set을 이용한 풀이 +const solution2 = (nums) => { + const can = nums.length / 2 + const max = [...new Set(nums)].length + + return can < max ? can : max +}