From 906418dd155be0fa28d5dd1785fdb61cd0dd14ab Mon Sep 17 00:00:00 2001 From: SeungHun6450 Date: Thu, 6 Mar 2025 17:52:27 +0900 Subject: [PATCH] week39 --- ...30\353\205\270\354\235\264\355\203\221.js" | 33 -------- ...34\352\261\260\355\225\230\352\270\260.js" | 37 +++++++++ ...40\354\235\270\355\226\211\354\202\254.js" | 74 ----------------- ...35\353\260\260\354\203\201\354\236\220.js" | 48 +++++++++++ ...04\353\241\234\354\204\270\354\212\244.js" | 50 ------------ "week36/64065_\355\212\234\355\224\214.js" | 79 +++++++++++++++++++ 6 files changed, 164 insertions(+), 157 deletions(-) delete mode 100644 "week36/12946_\355\225\230\353\205\270\354\235\264\355\203\221.js" create mode 100644 "week36/12973_\354\247\235\354\247\200\354\226\264 \354\240\234\352\261\260\355\225\230\352\270\260.js" delete mode 100644 "week36/131127_\355\225\240\354\235\270\355\226\211\354\202\254.js" create mode 100644 "week36/131704_\355\203\235\353\260\260\354\203\201\354\236\220.js" delete mode 100644 "week36/42587_\355\224\204\353\241\234\354\204\270\354\212\244.js" create mode 100644 "week36/64065_\355\212\234\355\224\214.js" diff --git "a/week36/12946_\355\225\230\353\205\270\354\235\264\355\203\221.js" "b/week36/12946_\355\225\230\353\205\270\354\235\264\355\203\221.js" deleted file mode 100644 index cc97b6b..0000000 --- "a/week36/12946_\355\225\230\353\205\270\354\235\264\355\203\221.js" +++ /dev/null @@ -1,33 +0,0 @@ -/* -문제 설명 -하노이 탑(Tower of Hanoi)은 퍼즐의 일종입니다. 세 개의 기둥과 이 기동에 꽂을 수 있는 크기가 다양한 원판들이 있고, 퍼즐을 시작하기 전에는 한 기둥에 원판들이 작은 것이 위에 있도록 순서대로 쌓여 있습니다. 게임의 목적은 다음 두 가지 조건을 만족시키면서, 한 기둥에 꽂힌 원판들을 그 순서 그대로 다른 기둥으로 옮겨서 다시 쌓는 것입니다. - -한 번에 하나의 원판만 옮길 수 있습니다. -큰 원판이 작은 원판 위에 있어서는 안됩니다. -하노이 탑의 세 개의 기둥을 왼쪽 부터 1번, 2번, 3번이라고 하겠습니다. 1번에는 n개의 원판이 있고 이 n개의 원판을 3번 원판으로 최소 횟수로 옮기려고 합니다. - -1번 기둥에 있는 원판의 개수 n이 매개변수로 주어질 때, n개의 원판을 3번 원판으로 최소로 옮기는 방법을 return하는 solution를 완성해주세요. - -제한사항 -n은 15이하의 자연수 입니다. -입출력 예 -n result -2 [ [1,2], [1,3], [2,3] ] - */ - -function solution(n) { - const result = []; - - function hanoi(n, first, third, second) { - if (n === 1) { - result.push([first, third]); - return; - } - hanoi(n - 1, first, second, third); // n-1개를 가운데 기둥으로 이동 - result.push([first, third]); // 가장 큰 원판을 마지막 기둥으로 이동 - hanoi(n - 1, second, third, first); // n-1개를 마지막 기둥으로 이동 - } - - hanoi(n, 1, 3, 2); - return result; -} diff --git "a/week36/12973_\354\247\235\354\247\200\354\226\264 \354\240\234\352\261\260\355\225\230\352\270\260.js" "b/week36/12973_\354\247\235\354\247\200\354\226\264 \354\240\234\352\261\260\355\225\230\352\270\260.js" new file mode 100644 index 0000000..5422c69 --- /dev/null +++ "b/week36/12973_\354\247\235\354\247\200\354\226\264 \354\240\234\352\261\260\355\225\230\352\270\260.js" @@ -0,0 +1,37 @@ +/* +문제 설명 +짝지어 제거하기는, 알파벳 소문자로 이루어진 문자열을 가지고 시작합니다. 먼저 문자열에서 같은 알파벳이 2개 붙어 있는 짝을 찾습니다. 그다음, 그 둘을 제거한 뒤, 앞뒤로 문자열을 이어 붙입니다. 이 과정을 반복해서 문자열을 모두 제거한다면 짝지어 제거하기가 종료됩니다. 문자열 S가 주어졌을 때, 짝지어 제거하기를 성공적으로 수행할 수 있는지 반환하는 함수를 완성해 주세요. 성공적으로 수행할 수 있으면 1을, 아닐 경우 0을 리턴해주면 됩니다. + +예를 들어, 문자열 S = baabaa 라면 + +b aa baa → bb aa → aa → + +의 순서로 문자열을 모두 제거할 수 있으므로 1을 반환합니다. + +제한사항 +문자열의 길이 : 1,000,000이하의 자연수 +문자열은 모두 소문자로 이루어져 있습니다. +입출력 예 +s result +baabaa 1 +cdcd 0 +입출력 예 설명 +입출력 예 #1 +위의 예시와 같습니다. +입출력 예 #2 +문자열이 남아있지만 짝지어 제거할 수 있는 문자열이 더 이상 존재하지 않기 때문에 0을 반환합니다. + */ + +function solution(s) { + const stack = []; + + for (let char of s) { + if (stack.length > 0 && stack[stack.length - 1] === char) { + stack.pop(); + } else { + stack.push(char); + } + } + + return stack.length === 0 ? 1 : 0; +} diff --git "a/week36/131127_\355\225\240\354\235\270\355\226\211\354\202\254.js" "b/week36/131127_\355\225\240\354\235\270\355\226\211\354\202\254.js" deleted file mode 100644 index e99049b..0000000 --- "a/week36/131127_\355\225\240\354\235\270\355\226\211\354\202\254.js" +++ /dev/null @@ -1,74 +0,0 @@ -/* -문제 설명 -XYZ 마트는 일정한 금액을 지불하면 10일 동안 회원 자격을 부여합니다. XYZ 마트에서는 회원을 대상으로 매일 한 가지 제품을 할인하는 행사를 합니다. 할인하는 제품은 하루에 하나씩만 구매할 수 있습니다. 알뜰한 정현이는 자신이 원하는 제품과 수량이 할인하는 날짜와 10일 연속으로 일치할 경우에 맞춰서 회원가입을 하려 합니다. - -예를 들어, 정현이가 원하는 제품이 바나나 3개, 사과 2개, 쌀 2개, 돼지고기 2개, 냄비 1개이며, XYZ 마트에서 14일간 회원을 대상으로 할인하는 제품이 날짜 순서대로 치킨, 사과, 사과, 바나나, 쌀, 사과, 돼지고기, 바나나, 돼지고기, 쌀, 냄비, 바나나, 사과, 바나나인 경우에 대해 알아봅시다. 첫째 날부터 열흘 간에는 냄비가 할인하지 않기 때문에 첫째 날에는 회원가입을 하지 않습니다. 둘째 날부터 열흘 간에는 바나나를 원하는 만큼 할인구매할 수 없기 때문에 둘째 날에도 회원가입을 하지 않습니다. 셋째 날, 넷째 날, 다섯째 날부터 각각 열흘은 원하는 제품과 수량이 일치하기 때문에 셋 중 하루에 회원가입을 하려 합니다. - -정현이가 원하는 제품을 나타내는 문자열 배열 want와 정현이가 원하는 제품의 수량을 나타내는 정수 배열 number, XYZ 마트에서 할인하는 제품을 나타내는 문자열 배열 discount가 주어졌을 때, 회원등록시 정현이가 원하는 제품을 모두 할인 받을 수 있는 회원등록 날짜의 총 일수를 return 하는 solution 함수를 완성하시오. 가능한 날이 없으면 0을 return 합니다. - -제한사항 -1 ≤ want의 길이 = number의 길이 ≤ 10 -1 ≤ number의 원소 ≤ 10 -number[i]는 want[i]의 수량을 의미하며, number의 원소의 합은 10입니다. -10 ≤ discount의 길이 ≤ 100,000 -want와 discount의 원소들은 알파벳 소문자로 이루어진 문자열입니다. -1 ≤ want의 원소의 길이, discount의 원소의 길이 ≤ 12 -입출력 예 -want number discount result -["banana", "apple", "rice", "pork", "pot"] [3, 2, 2, 2, 1] ["chicken", "apple", "apple", "banana", "rice", "apple", "pork", "banana", "pork", "rice", "pot", "banana", "apple", "banana"] 3 -["apple"] [10] ["banana", "banana", "banana", "banana", "banana", "banana", "banana", "banana", "banana", "banana"] 0 -입출력 예 설명 -입출력 예 #1 - -문제 예시와 같습니다. -입출력 예 #2 - -사과가 할인하는 날이 없으므로 0을 return 합니다. -*/ -function solution(want, number, discount) { - let count = 0; - - const need = new Map(); // 원하는 제품 목록을 저장할 맵 - for (let i = 0; i < want.length; i++) { - need.set(want[i], number[i]); - } - - const current = new Map(); // 10일간의 제품 개수 저장 - for (let i = 0; i < 10; i++) { - current.set(discount[i], (current.get(discount[i]) || 0) + 1); - } - - // 현재 10일간 제품과 원하는 제품이 일치하는지 확인하는 함수 - function Match() { - for (let [key, value] of need) { - if (current.get(key) !== value) return false; - } - return true; - } - - // 첫 번째 10일 체크 - if (Match()) count++; - - // 하루씩 비교 - for (let i = 10; i < discount.length; i++) { - const start = discount[i - 10]; // 빠지는 값 - const end = discount[i]; // 추가되는 값 - - // 빠지는 값 제거 - if (current.get(start) === 1) { - // 상품 1개만 존재 시 삭제 - current.delete(start); - } else { - // 상품 개수 감소 - current.set(start, current.get(start) - 1); - } - - // 새로 추가되는 값 추가, 기존에 없는 상품이면 기본 값은 0, 있으면 + 1 - current.set(end, (current.get(end) || 0) + 1); - - // 현재 원하는 제품과 일치하는지 여부 - if (Match()) count++; - } - - return count; -} diff --git "a/week36/131704_\355\203\235\353\260\260\354\203\201\354\236\220.js" "b/week36/131704_\355\203\235\353\260\260\354\203\201\354\236\220.js" new file mode 100644 index 0000000..2c53441 --- /dev/null +++ "b/week36/131704_\355\203\235\353\260\260\354\203\201\354\236\220.js" @@ -0,0 +1,48 @@ +/* +문제 설명 +영재는 택배상자를 트럭에 싣는 일을 합니다. 영재가 실어야 하는 택배상자는 크기가 모두 같으며 1번 상자부터 n번 상자까지 번호가 증가하는 순서대로 컨테이너 벨트에 일렬로 놓여 영재에게 전달됩니다. 컨테이너 벨트는 한 방향으로만 진행이 가능해서 벨트에 놓인 순서대로(1번 상자부터) 상자를 내릴 수 있습니다. 하지만 컨테이너 벨트에 놓인 순서대로 택배상자를 내려 바로 트럭에 싣게 되면 택배 기사님이 배달하는 순서와 택배상자가 실려 있는 순서가 맞지 않아 배달에 차질이 생깁니다. 따라서 택배 기사님이 미리 알려준 순서에 맞게 영재가 택배상자를 실어야 합니다. + +만약 컨테이너 벨트의 맨 앞에 놓인 상자가 현재 트럭에 실어야 하는 순서가 아니라면 그 상자를 트럭에 실을 순서가 될 때까지 잠시 다른 곳에 보관해야 합니다. 하지만 고객의 물건을 함부로 땅에 둘 수 없어 보조 컨테이너 벨트를 추가로 설치하였습니다. 보조 컨테이너 벨트는 앞 뒤로 이동이 가능하지만 입구 외에 다른 면이 막혀 있어서 맨 앞의 상자만 뺄 수 있습니다(즉, 가장 마지막에 보조 컨테이너 벨트에 보관한 상자부터 꺼내게 됩니다). 보조 컨테이너 벨트를 이용해도 기사님이 원하는 순서대로 상자를 싣지 못 한다면, 더 이상 상자를 싣지 않습니다. + +예를 들어, 영재가 5개의 상자를 실어야 하며, 택배 기사님이 알려준 순서가 기존의 컨테이너 벨트에 네 번째, 세 번째, 첫 번째, 두 번째, 다섯 번째 놓인 택배상자 순서인 경우, 영재는 우선 첫 번째, 두 번째, 세 번째 상자를 보조 컨테이너 벨트에 보관합니다. 그 후 네 번째 상자를 트럭에 싣고 보조 컨테이너 벨트에서 세 번째 상자 빼서 트럭에싣습니다. 다음으로 첫 번째 상자를 실어야 하지만 보조 컨테이너 벨트에서는 두 번째 상자를, 기존의 컨테이너 벨트에는 다섯 번째 상자를 꺼낼 수 있기 때문에 더이상의 상자는 실을 수 없습니다. 따라서 트럭에는 2개의 상자만 실리게 됩니다. + +택배 기사님이 원하는 상자 순서를 나타내는 정수 배열 order가 주어졌을 때, 영재가 몇 개의 상자를 실을 수 있는지 return 하는 solution 함수를 완성하세요. + +제한사항 +1 ≤ order의 길이 ≤ 1,000,000 +order는 1이상 order의 길이 이하의 모든 정수가 한번씩 등장합니다. +order[i]는 기존의 컨테이너 벨트에 order[i]번째 상자를 i+1번째로 트럭에 실어야 함을 의미합니다. +입출력 예 +order result +[4, 3, 1, 2, 5] 2 +[5, 4, 3, 2, 1] 5 +입출력 예 설명 +입출력 예 #1 + +문제 예시와 같습니다. +입출력 예 #2 + +모든 상자를 보조 컨테이너 벨트에 모두 넣고, 역순으로 하나씩 빼서 트럭에 싣습니다. +*/ +function solution(order) { + let stack = []; + let current = 1; + let count = 0; + + for (let i = 0; i < order.length; i++) { + let target = order[i]; + + while (current <= target) { + stack.push(current++); + } + + if (stack[stack.length - 1] === target) { + stack.pop(); + count++; + } else { + break; + } + } + + return count; +} diff --git "a/week36/42587_\355\224\204\353\241\234\354\204\270\354\212\244.js" "b/week36/42587_\355\224\204\353\241\234\354\204\270\354\212\244.js" deleted file mode 100644 index 6bad7d2..0000000 --- "a/week36/42587_\355\224\204\353\241\234\354\204\270\354\212\244.js" +++ /dev/null @@ -1,50 +0,0 @@ -/* -문제 설명 -운영체제의 역할 중 하나는 컴퓨터 시스템의 자원을 효율적으로 관리하는 것입니다. 이 문제에서는 운영체제가 다음 규칙에 따라 프로세스를 관리할 경우 특정 프로세스가 몇 번째로 실행되는지 알아내면 됩니다. - -1. 실행 대기 큐(Queue)에서 대기중인 프로세스 하나를 꺼냅니다. -2. 큐에 대기중인 프로세스 중 우선순위가 더 높은 프로세스가 있다면 방금 꺼낸 프로세스를 다시 큐에 넣습니다. -3. 만약 그런 프로세스가 없다면 방금 꺼낸 프로세스를 실행합니다. - 3.1 한 번 실행한 프로세스는 다시 큐에 넣지 않고 그대로 종료됩니다. -예를 들어 프로세스 4개 [A, B, C, D]가 순서대로 실행 대기 큐에 들어있고, 우선순위가 [2, 1, 3, 2]라면 [C, D, A, B] 순으로 실행하게 됩니다. - -현재 실행 대기 큐(Queue)에 있는 프로세스의 중요도가 순서대로 담긴 배열 priorities와, 몇 번째로 실행되는지 알고싶은 프로세스의 위치를 알려주는 location이 매개변수로 주어질 때, 해당 프로세스가 몇 번째로 실행되는지 return 하도록 solution 함수를 작성해주세요. - -제한사항 -priorities의 길이는 1 이상 100 이하입니다. -priorities의 원소는 1 이상 9 이하의 정수입니다. -priorities의 원소는 우선순위를 나타내며 숫자가 클 수록 우선순위가 높습니다. -location은 0 이상 (대기 큐에 있는 프로세스 수 - 1) 이하의 값을 가집니다. -priorities의 가장 앞에 있으면 0, 두 번째에 있으면 1 … 과 같이 표현합니다. -입출력 예 -priorities location return -[2, 1, 3, 2] 2 1 -[1, 1, 9, 1, 1, 1] 0 5 -입출력 예 설명 -예제 #1 - -문제에 나온 예와 같습니다. - -예제 #2 - -6개의 프로세스 [A, B, C, D, E, F]가 대기 큐에 있고 중요도가 [1, 1, 9, 1, 1, 1] 이므로 [C, D, E, F, A, B] 순으로 실행됩니다. 따라서 A는 5번째로 실행됩니다. - - -*/ - -function solution(priorities, location) { - let queue = priorities.map((priority, index) => [priority, index]); // [우선순위, 초기 위치] 저장 - let count = 0; // 실행 순서 카운트 - - while (queue.length) { - let current = queue.shift(); // 첫 번째 요소 꺼내기 - - // 현재 요소보다 우선순위가 높은 프로세스가 남아있는지 확인 - if (queue.some(([priority]) => priority > current[0])) { - queue.push(current); // 우선순위가 높은 게 있으면 다시 큐에 넣기 - } else { - count++; // 실행됨 - if (current[1] === location) return count; // 목표 프로세스 실행 시 반환 - } - } -} diff --git "a/week36/64065_\355\212\234\355\224\214.js" "b/week36/64065_\355\212\234\355\224\214.js" new file mode 100644 index 0000000..efef164 --- /dev/null +++ "b/week36/64065_\355\212\234\355\224\214.js" @@ -0,0 +1,79 @@ +/* +문제 설명 +셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다. n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다. + +(a1, a2, a3, ..., an) +튜플은 다음과 같은 성질을 가지고 있습니다. + +중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2) +원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2) +튜플의 원소 개수는 유한합니다. +원소의 개수가 n개이고, 중복되는 원소가 없는 튜플 (a1, a2, a3, ..., an)이 주어질 때(단, a1, a2, ..., an은 자연수), 이는 다음과 같이 집합 기호 '{', '}'를 이용해 표현할 수 있습니다. + +{{a1}, {a1, a2}, {a1, a2, a3}, {a1, a2, a3, a4}, ... {a1, a2, a3, a4, ..., an}} +예를 들어 튜플이 (2, 1, 3, 4)인 경우 이는 + +{{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}} +와 같이 표현할 수 있습니다. 이때, 집합은 원소의 순서가 바뀌어도 상관없으므로 + +{{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}} +{{2, 1, 3, 4}, {2}, {2, 1, 3}, {2, 1}} +{{1, 2, 3}, {2, 1}, {1, 2, 4, 3}, {2}} +는 모두 같은 튜플 (2, 1, 3, 4)를 나타냅니다. + +특정 튜플을 표현하는 집합이 담긴 문자열 s가 매개변수로 주어질 때, s가 표현하는 튜플을 배열에 담아 return 하도록 solution 함수를 완성해주세요. + +[제한사항] +s의 길이는 5 이상 1,000,000 이하입니다. +s는 숫자와 '{', '}', ',' 로만 이루어져 있습니다. +숫자가 0으로 시작하는 경우는 없습니다. +s는 항상 중복되는 원소가 없는 튜플을 올바르게 표현하고 있습니다. +s가 표현하는 튜플의 원소는 1 이상 100,000 이하인 자연수입니다. +return 하는 배열의 길이가 1 이상 500 이하인 경우만 입력으로 주어집니다. +[입출력 예] +s result +"{{2},{2,1},{2,1,3},{2,1,3,4}}" [2, 1, 3, 4] +"{{1,2,3},{2,1},{1,2,4,3},{2}}" [2, 1, 3, 4] +"{{20,111},{111}}" [111, 20] +"{{123}}" [123] +"{{4,2,3},{3},{2,3,4,1},{2,3}}" [3, 2, 4, 1] +입출력 예에 대한 설명 +입출력 예 #1 +문제 예시와 같습니다. + +입출력 예 #2 +문제 예시와 같습니다. + +입출력 예 #3 +(111, 20)을 집합 기호를 이용해 표현하면 {{111}, {111,20}}이 되며, 이는 {{20,111},{111}}과 같습니다. + +입출력 예 #4 +(123)을 집합 기호를 이용해 표현하면 {{123}} 입니다. + +입출력 예 #5 +(3, 2, 4, 1)을 집합 기호를 이용해 표현하면 {{3},{3,2},{3,2,4},{3,2,4,1}}이 되며, 이는 {{4,2,3},{3},{2,3,4,1},{2,3}}과 같습니다. + +*/ + +function solution(s) { + let sets = s + .slice(2, -2) + .split("},{") + .map((set) => set.split(",").map(Number)); + + sets.sort((a, b) => a.length - b.length); + + let result = []; + let seen = new Set(); + + for (let set of sets) { + for (let num of set) { + if (!seen.has(num)) { + seen.add(num); + result.push(num); + } + } + } + + return result; +}