From b75922f45d983ab4e3cbc38324b90be6f40260cb Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Tue, 16 Jan 2024 21:44:12 +0900 Subject: [PATCH 01/12] solve: problem-1-1 --- problem-1-1/problem-1-1.test.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/problem-1-1/problem-1-1.test.js b/problem-1-1/problem-1-1.test.js index 6ab9348..37dc8bc 100644 --- a/problem-1-1/problem-1-1.test.js +++ b/problem-1-1/problem-1-1.test.js @@ -1,4 +1,30 @@ class Bag { + #bag = []; + + isEmpty() { + return this.#bag.length === 0; + } + + add(item) { + this.#bag.push(item); + } + + size() { + return this.#bag.length; + } + + [Symbol.iterator]() { + let index = 0; + const bag = [...this.#bag]; + + return { + next() { + return index < bag.length + ? { done: false, value: bag[index++] } + : { done: true }; + }, + }; + } } test('백은 비어있는 상태로 생성된다', () => { From 66bdd23a653a20d8605b44ae418dee970d0f337b Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Tue, 16 Jan 2024 21:44:31 +0900 Subject: [PATCH 02/12] solve: problem-1-2 --- problem-1-2/problem-1-2.test.js | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/problem-1-2/problem-1-2.test.js b/problem-1-2/problem-1-2.test.js index f2956b6..e76829d 100644 --- a/problem-1-2/problem-1-2.test.js +++ b/problem-1-2/problem-1-2.test.js @@ -1,4 +1,49 @@ +class Bag { + #bag = []; + + isEmpty() { + return this.#bag.length === 0; + } + + add(item) { + this.#bag.push(item); + } + + size() { + return this.#bag.length; + } + + sum() { + const initialValue = 0; + return this.#bag.reduce((acc, currentValue) => acc + currentValue, initialValue); + } + + average() { + return Math.floor(this.sum() / this.size()); + } + + [Symbol.iterator]() { + let index = 0; + const bag = [...this.#bag]; + + return { + next() { + return index < bag.length + ? { done: false, value: bag[index++] } + : { done: true }; + }, + }; + } +} + const solution = (numbers) => { + const bag = new Bag(); + + numbers.forEach((number) => { + bag.add(number); + }); + + return bag.average(); }; test('숫자 배열의 평균을 반환한다', () => { From 854651514d03b595d119139e8f080c038387af81 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Thu, 18 Jan 2024 16:31:41 +0900 Subject: [PATCH 03/12] solve: problem-2-1 --- problem-2-1/problem-2-1.test.js | 64 +++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/problem-2-1/problem-2-1.test.js b/problem-2-1/problem-2-1.test.js index 17412df..0c898b2 100644 --- a/problem-2-1/problem-2-1.test.js +++ b/problem-2-1/problem-2-1.test.js @@ -1,4 +1,68 @@ class Stack { + #capacity; + + #numberOfItem; + + #items; + + constructor(capacity) { + this.#capacity = capacity; + this.#numberOfItem = 0; + this.#items = new Array(capacity); + } + + push(item) { + // Last In, First Out = LIFO + // todo: 아이템을 추가할 때 더 이상 추가할 수 없다면 배열의 크기를 2배로 늘리기 + if (this.isFull()) { + this.#capacity = this.#capacity * 2; + } + + this.#items[this.#numberOfItem] = item; + this.#numberOfItem += 1; + } + + pop() { + if (this.isEmpty()) { + throw new Error('스택이 비어있습니다.'); + } + + // todo: 아이템을 제거할 때 아이템의 수가 1 / 4이하라면 배열의 크기를 1/2로 줄이기 + if (this.isLessThanQuarter()) { + this.#capacity = this.#capacity / 2; + } + + this.#numberOfItem -= 1; + return this.#items[this.#numberOfItem]; + } + + isLessThanQuarter() { + return this.#numberOfItem <= this.#capacity / 4; + } + + isEmpty() { + return this.#numberOfItem === 0; + } + + size() { + return this.#numberOfItem; + } + + isFull() { + return this.#numberOfItem === this.#capacity; + } + + [Symbol.iterator]() { + let numberOfItem = this.#numberOfItem; + const items = this.#items; + + return { + next() { + numberOfItem = numberOfItem - 1; + return numberOfItem >= 0 ? { done: false, value: items[numberOfItem] } : { done: true }; + }, + }; + } } test('스택을 생성하면 비어있다', () => { From 1f5e0e9f031b0a3e3e73206671628d1001878d96 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Thu, 18 Jan 2024 16:57:51 +0900 Subject: [PATCH 04/12] solve: problem-2-2 --- problem-2-2/problem-2-2.test.js | 90 +++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/problem-2-2/problem-2-2.test.js b/problem-2-2/problem-2-2.test.js index dab5212..19d1dc5 100644 --- a/problem-2-2/problem-2-2.test.js +++ b/problem-2-2/problem-2-2.test.js @@ -1,4 +1,94 @@ +class Stack { + #capacity; + + #numberOfItem; + + #items; + + constructor(capacity) { + this.#capacity = capacity; + this.#numberOfItem = 0; + this.#items = new Array(capacity); + } + + push(item) { + // Last In, First Out = LIFO + // todo: 아이템을 추가할 때 더 이상 추가할 수 없다면 배열의 크기를 2배로 늘리기 + if (this.isFull()) { + this.#capacity = this.#capacity * 2; + } + + this.#items[this.#numberOfItem] = item; + this.#numberOfItem += 1; + } + + pop() { + if (this.isEmpty()) { + throw new Error('스택이 비어있습니다.'); + } + + // todo: 아이템을 제거할 때 아이템의 수가 1 / 4이하라면 배열의 크기를 1/2로 줄이기 + if (this.isLessThanQuarter()) { + this.#capacity = this.#capacity / 2; + } + + this.#numberOfItem -= 1; + return this.#items[this.#numberOfItem]; + } + + isLessThanQuarter() { + return this.#numberOfItem <= this.#capacity / 4; + } + + isEmpty() { + return this.#numberOfItem === 0; + } + + size() { + return this.#numberOfItem; + } + + isFull() { + return this.#numberOfItem === this.#capacity; + } + + [Symbol.iterator]() { + let numberOfItem = this.#numberOfItem; + const items = this.#items; + + return { + next() { + numberOfItem = numberOfItem - 1; + return numberOfItem >= 0 ? { done: false, value: items[numberOfItem] } : { done: true }; + }, + }; + } +} + const solution = (string) => { + const stack = new Stack(string.length); + const brackets = { '[': ']', '{': '}', '(': ')' }; + + if (string === '') { + return stack.isEmpty(); + } + + for (const char of string) { + if (brackets[char]) { // 현재 문자가 열린 괄호라면 = [, {, ( + stack.push(char); + } else { // 현재 문자가 닫힌 괄호라면 = ], }, ) + if (stack.isEmpty()) { // 현재 스택이 비어 있다면 false + return false; + } + + const topChar = stack.pop(); + if (brackets[topChar] !== char) { // 가장 위의 아이템을 꺼내서 짝이 맞는지 비교한다. + return false; + } + } + } + + return stack.isEmpty(); }; test('문자열에 포함된 괄호의 짝이 맞을 때 true를 반환한다', () => { From 3373ba6ed3019837f6eb2054e39b39c5ab64b863 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Thu, 18 Jan 2024 18:05:27 +0900 Subject: [PATCH 05/12] solve: problem-3-1 --- problem-3-1/problem-3-1.test.js | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/problem-3-1/problem-3-1.test.js b/problem-3-1/problem-3-1.test.js index 6ae251f..c45775f 100644 --- a/problem-3-1/problem-3-1.test.js +++ b/problem-3-1/problem-3-1.test.js @@ -1,4 +1,69 @@ class Queue { + #capacity; + + #numberOfItems; + + #items; + + constructor(capacity) { + this.#capacity = capacity; + this.#numberOfItems = 0; + this.#items = new Array(capacity); + } + + enqueue(item) { + if (this.isFull()) { + throw new Error('용량이 꽉 찼습니다.'); + } + + this.#items[this.#numberOfItems] = item; + this.#numberOfItems += 1; + } + + dequeue() { + if (this.isEmpty()) { + throw new Error('큐가 비어있습니다'); + } + + // First In, First Out = FIFO + const firstItem = this.#items[0]; + + // todo : 남은 item 들을 각각 앞으로 옮겨야 한다. + for (let index = 1; index < this.#numberOfItems; index += 1) { + this.#items[index - 1] = this.#items[index]; + } + + // item 을 하나 꺼냈으므로 아이템 수 - 1 + this.#numberOfItems -= 1; + + return firstItem; + } + + isEmpty() { + return this.#numberOfItems === 0; + } + + size() { + return this.#numberOfItems; + } + + isFull() { + return this.#numberOfItems === this.#capacity; + } + + [Symbol.iterator]() { + let index = 0; + const items = this.#items; + const numberOfItems = this.#numberOfItems; + + return { + next() { + return index < numberOfItems + ? { done: false, value: items[index++] } + : { done: true }; + }, + }; + } } test('큐를 생성하면 비어있다', () => { From 00d0a954f7c53e1c05907c07d817229b93c614d8 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Thu, 18 Jan 2024 20:39:20 +0900 Subject: [PATCH 06/12] solve: problem-3-2 --- problem-3-2/problem-3-2.test.js | 93 +++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/problem-3-2/problem-3-2.test.js b/problem-3-2/problem-3-2.test.js index 21bd836..594fb4e 100644 --- a/problem-3-2/problem-3-2.test.js +++ b/problem-3-2/problem-3-2.test.js @@ -1,4 +1,97 @@ +class Queue { + #capacity; + + #numberOfItems; + + #items; + + constructor(capacity) { + this.#capacity = capacity; + this.#numberOfItems = 0; + this.#items = new Array(capacity); + } + + enqueue(item) { + if (this.isFull()) { + throw new Error('용량이 꽉 찼습니다.'); + } + + this.#items[this.#numberOfItems] = item; + this.#numberOfItems += 1; + } + + dequeue() { + if (this.isEmpty()) { + throw new Error('큐가 비어있습니다'); + } + + const firstItem = this.#items[0]; + + for (let index = 1; index < this.#numberOfItems; index += 1) { + this.#items[index - 1] = this.#items[index]; + } + + this.#numberOfItems -= 1; + + return firstItem; + } + + isEmpty() { + return this.#numberOfItems === 0; + } + + size() { + return this.#numberOfItems; + } + + isFull() { + return this.#numberOfItems === this.#capacity; + } + + [Symbol.iterator]() { + let index = 0; + const items = this.#items; + const numberOfItems = this.#numberOfItems; + + return { + next() { + return index < numberOfItems + ? { done: false, value: items[index++] } + : { done: true }; + }, + }; + } +} + +const createNumberArray = (itemCount) => { + const resultArray = []; + + for (let index = 1; index <= itemCount; index++) { + resultArray.push(index); + } + + return resultArray; +}; + const solution = (N, M) => { + const numberOfPersons = N; + const deathLocation = M; + + const persons = createNumberArray(numberOfPersons); + + const queue = new Queue(); + persons.forEach((person) => queue.enqueue(person)); + + while (queue.size() > 1) { + for (let index = 0; index < deathLocation - 1; index += 1) { + const personToMove = queue.dequeue(); + queue.enqueue(personToMove); + } + + queue.dequeue(); + } + + return queue.dequeue(); }; test('N명의 사람이 있을 때 M번째 사람을 없앨 때 마지막에 죽는 사람의 순서를 반환한다', () => { From 3ecca82455312628ab579bbbbeddcd3ceaa58358 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Fri, 19 Jan 2024 16:14:55 +0900 Subject: [PATCH 07/12] =?UTF-8?q?refactor:=20Bag=20=EC=9D=84=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem-1-1/problem-1-1.test.js | 45 +++++++++++++++++++------- problem-1-2/problem-1-2.test.js | 56 ++++++++++++++++++++++++--------- 2 files changed, 75 insertions(+), 26 deletions(-) diff --git a/problem-1-1/problem-1-1.test.js b/problem-1-1/problem-1-1.test.js index 37dc8bc..dc951f7 100644 --- a/problem-1-1/problem-1-1.test.js +++ b/problem-1-1/problem-1-1.test.js @@ -1,27 +1,48 @@ +class Node { + #item; + + #next; +} + class Bag { - #bag = []; + #first; + + #numberOfItems; + + constructor() { + this.#numberOfItems = 0; + } + + size() { + return this.#numberOfItems; + } isEmpty() { - return this.#bag.length === 0; + return this.#numberOfItems === 0; } add(item) { - this.#bag.push(item); - } + const oldFirst = this.#first; - size() { - return this.#bag.length; + this.#first = new Node(); + this.#first.item = item; + this.#first.next = oldFirst; + + this.#numberOfItems += 1; } [Symbol.iterator]() { - let index = 0; - const bag = [...this.#bag]; - + let current = this.#first; return { next() { - return index < bag.length - ? { done: false, value: bag[index++] } - : { done: true }; + if (current === undefined) { + return { done: true }; + } + + const value = current.item; + current = current.next; + + return { done: false, value }; }, }; } diff --git a/problem-1-2/problem-1-2.test.js b/problem-1-2/problem-1-2.test.js index e76829d..d8bba9d 100644 --- a/problem-1-2/problem-1-2.test.js +++ b/problem-1-2/problem-1-2.test.js @@ -1,21 +1,46 @@ +class Node { + #item; + + #next; +} + class Bag { - #bag = []; + #first; + + #numberOfItems; + + constructor() { + this.#numberOfItems = 0; + } + + size() { + return this.#numberOfItems; + } isEmpty() { - return this.#bag.length === 0; + return this.#numberOfItems === 0; } add(item) { - this.#bag.push(item); - } + const oldFirst = this.#first; - size() { - return this.#bag.length; + this.#first = new Node(); + this.#first.item = item; + this.#first.next = oldFirst; + + this.#numberOfItems += 1; } sum() { - const initialValue = 0; - return this.#bag.reduce((acc, currentValue) => acc + currentValue, initialValue); + let sum = 0; + let current = this.#first; + + while (current !== undefined) { + sum += current.item; + current = current.next; + } + + return sum; } average() { @@ -23,14 +48,17 @@ class Bag { } [Symbol.iterator]() { - let index = 0; - const bag = [...this.#bag]; - + let current = this.#first; return { next() { - return index < bag.length - ? { done: false, value: bag[index++] } - : { done: true }; + if (current === undefined) { + return { done: true }; + } + + const value = current.item; + current = current.next; + + return { done: false, value }; }, }; } From 0a89479d72cfe445ebc4c6ea46ed155403a02aa6 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Fri, 19 Jan 2024 16:16:20 +0900 Subject: [PATCH 08/12] =?UTF-8?q?refactor:=20Stack=20=EC=9D=84=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem-2-1/problem-2-1.test.js | 75 ++++++++++++++++----------------- problem-2-2/problem-2-2.test.js | 75 ++++++++++++++++----------------- 2 files changed, 72 insertions(+), 78 deletions(-) diff --git a/problem-2-1/problem-2-1.test.js b/problem-2-1/problem-2-1.test.js index 0c898b2..d9bb382 100644 --- a/problem-2-1/problem-2-1.test.js +++ b/problem-2-1/problem-2-1.test.js @@ -1,65 +1,62 @@ +class Node { + #item; + + #next; +} + class Stack { - #capacity; + #first; #numberOfItem; - #items; - - constructor(capacity) { - this.#capacity = capacity; + constructor() { this.#numberOfItem = 0; - this.#items = new Array(capacity); + } + + isEmpty() { + return this.#numberOfItem === 0; + } + + size() { + return this.#numberOfItem; } push(item) { - // Last In, First Out = LIFO - // todo: 아이템을 추가할 때 더 이상 추가할 수 없다면 배열의 크기를 2배로 늘리기 - if (this.isFull()) { - this.#capacity = this.#capacity * 2; - } + // todo : 맨 앞에 아이템을 넣는 방식. + const oldFirst = this.#first; + + this.#first = new Node(); + this.#first.item = item; + this.#first.next = oldFirst; - this.#items[this.#numberOfItem] = item; this.#numberOfItem += 1; } pop() { if (this.isEmpty()) { - throw new Error('스택이 비어있습니다.'); - } - - // todo: 아이템을 제거할 때 아이템의 수가 1 / 4이하라면 배열의 크기를 1/2로 줄이기 - if (this.isLessThanQuarter()) { - this.#capacity = this.#capacity / 2; + throw new Error('스택이 비어있습니다'); } + // todo: push 할 때 맨 앞에 가장 최근 아이템이 들어오니까 pop 할 때도 맨 앞에 있는 아이템을 꺼내야 한다. + const latestItem = this.#first.item; + this.#first = this.#first.next; this.#numberOfItem -= 1; - return this.#items[this.#numberOfItem]; - } - - isLessThanQuarter() { - return this.#numberOfItem <= this.#capacity / 4; - } - isEmpty() { - return this.#numberOfItem === 0; - } - - size() { - return this.#numberOfItem; - } - - isFull() { - return this.#numberOfItem === this.#capacity; + return latestItem; } [Symbol.iterator]() { - let numberOfItem = this.#numberOfItem; - const items = this.#items; - + let current = this.#first; return { next() { - numberOfItem = numberOfItem - 1; - return numberOfItem >= 0 ? { done: false, value: items[numberOfItem] } : { done: true }; + if (current === undefined) { + return { done: true }; + } + + const value = current.item; + current = current.next; + + return { done: false, value }; }, }; } diff --git a/problem-2-2/problem-2-2.test.js b/problem-2-2/problem-2-2.test.js index 19d1dc5..f0db977 100644 --- a/problem-2-2/problem-2-2.test.js +++ b/problem-2-2/problem-2-2.test.js @@ -1,65 +1,62 @@ +class Node { + #item; + + #next; +} + class Stack { - #capacity; + #first; #numberOfItem; - #items; - - constructor(capacity) { - this.#capacity = capacity; + constructor() { this.#numberOfItem = 0; - this.#items = new Array(capacity); + } + + isEmpty() { + return this.#numberOfItem === 0; + } + + size() { + return this.#numberOfItem; } push(item) { - // Last In, First Out = LIFO - // todo: 아이템을 추가할 때 더 이상 추가할 수 없다면 배열의 크기를 2배로 늘리기 - if (this.isFull()) { - this.#capacity = this.#capacity * 2; - } + // todo : 맨 앞에 아이템을 넣는 방식. + const oldFirst = this.#first; + + this.#first = new Node(); + this.#first.item = item; + this.#first.next = oldFirst; - this.#items[this.#numberOfItem] = item; this.#numberOfItem += 1; } pop() { if (this.isEmpty()) { - throw new Error('스택이 비어있습니다.'); - } - - // todo: 아이템을 제거할 때 아이템의 수가 1 / 4이하라면 배열의 크기를 1/2로 줄이기 - if (this.isLessThanQuarter()) { - this.#capacity = this.#capacity / 2; + throw new Error('스택이 비어있습니다'); } + // todo: push 할 때 맨 앞에 가장 최근 아이템이 들어오니까 pop 할 때도 맨 앞에 있는 아이템을 꺼내야 한다. + const latestItem = this.#first.item; + this.#first = this.#first.next; this.#numberOfItem -= 1; - return this.#items[this.#numberOfItem]; - } - - isLessThanQuarter() { - return this.#numberOfItem <= this.#capacity / 4; - } - isEmpty() { - return this.#numberOfItem === 0; - } - - size() { - return this.#numberOfItem; - } - - isFull() { - return this.#numberOfItem === this.#capacity; + return latestItem; } [Symbol.iterator]() { - let numberOfItem = this.#numberOfItem; - const items = this.#items; - + let current = this.#first; return { next() { - numberOfItem = numberOfItem - 1; - return numberOfItem >= 0 ? { done: false, value: items[numberOfItem] } : { done: true }; + if (current === undefined) { + return { done: true }; + } + + const value = current.item; + current = current.next; + + return { done: false, value }; }, }; } From 45eac7b7244dfc05d2617e07d6ddb7842b0aab1f Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Fri, 19 Jan 2024 17:08:54 +0900 Subject: [PATCH 09/12] =?UTF-8?q?refactor:=20Queue=20=EB=A5=BC=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem-3-1/problem-3-1.test.js | 72 +++++++++++++++++---------------- problem-3-2/problem-3-2.test.js | 69 ++++++++++++++++--------------- 2 files changed, 74 insertions(+), 67 deletions(-) diff --git a/problem-3-1/problem-3-1.test.js b/problem-3-1/problem-3-1.test.js index c45775f..8960458 100644 --- a/problem-3-1/problem-3-1.test.js +++ b/problem-3-1/problem-3-1.test.js @@ -1,22 +1,39 @@ +class Node { + #item; + + #next; +} + class Queue { - #capacity; + #first; - #numberOfItems; + #last; - #items; + #numberOfItems; - constructor(capacity) { - this.#capacity = capacity; + constructor() { this.#numberOfItems = 0; - this.#items = new Array(capacity); + } + + isEmpty() { + return this.#numberOfItems === 0; + } + + size() { + return this.#numberOfItems; } enqueue(item) { - if (this.isFull()) { - throw new Error('용량이 꽉 찼습니다.'); + const oldLast = this.#last; + this.#last = new Node(); + this.#last.item = item; + + if (this.isEmpty()) { + this.#first = this.#last; + } else { + oldLast.next = this.#last; } - this.#items[this.#numberOfItems] = item; this.#numberOfItems += 1; } @@ -25,42 +42,27 @@ class Queue { throw new Error('큐가 비어있습니다'); } - // First In, First Out = FIFO - const firstItem = this.#items[0]; + const firstItem = this.#first.item; + this.#first = this.#first.next; - // todo : 남은 item 들을 각각 앞으로 옮겨야 한다. - for (let index = 1; index < this.#numberOfItems; index += 1) { - this.#items[index - 1] = this.#items[index]; - } - - // item 을 하나 꺼냈으므로 아이템 수 - 1 this.#numberOfItems -= 1; return firstItem; } - isEmpty() { - return this.#numberOfItems === 0; - } - - size() { - return this.#numberOfItems; - } - - isFull() { - return this.#numberOfItems === this.#capacity; - } - [Symbol.iterator]() { - let index = 0; - const items = this.#items; - const numberOfItems = this.#numberOfItems; + let current = this.#first; return { next() { - return index < numberOfItems - ? { done: false, value: items[index++] } - : { done: true }; + if (current === undefined) { + return { done: true }; + } + + const value = current.item; + current = current.next; + + return { done: false, value }; }, }; } diff --git a/problem-3-2/problem-3-2.test.js b/problem-3-2/problem-3-2.test.js index 594fb4e..e5dd6e0 100644 --- a/problem-3-2/problem-3-2.test.js +++ b/problem-3-2/problem-3-2.test.js @@ -1,22 +1,39 @@ +class Node { + #item; + + #next; +} + class Queue { - #capacity; + #first; - #numberOfItems; + #last; - #items; + #numberOfItems; - constructor(capacity) { - this.#capacity = capacity; + constructor() { this.#numberOfItems = 0; - this.#items = new Array(capacity); + } + + isEmpty() { + return this.#numberOfItems === 0; + } + + size() { + return this.#numberOfItems; } enqueue(item) { - if (this.isFull()) { - throw new Error('용량이 꽉 찼습니다.'); + const oldLast = this.#last; + this.#last = new Node(); + this.#last.item = item; + + if (this.isEmpty()) { + this.#first = this.#last; + } else { + oldLast.next = this.#last; } - this.#items[this.#numberOfItems] = item; this.#numberOfItems += 1; } @@ -25,39 +42,27 @@ class Queue { throw new Error('큐가 비어있습니다'); } - const firstItem = this.#items[0]; - - for (let index = 1; index < this.#numberOfItems; index += 1) { - this.#items[index - 1] = this.#items[index]; - } + const firstItem = this.#first.item; + this.#first = this.#first.next; this.#numberOfItems -= 1; return firstItem; } - isEmpty() { - return this.#numberOfItems === 0; - } - - size() { - return this.#numberOfItems; - } - - isFull() { - return this.#numberOfItems === this.#capacity; - } - [Symbol.iterator]() { - let index = 0; - const items = this.#items; - const numberOfItems = this.#numberOfItems; + let current = this.#first; return { next() { - return index < numberOfItems - ? { done: false, value: items[index++] } - : { done: true }; + if (current === undefined) { + return { done: true }; + } + + const value = current.item; + current = current.next; + + return { done: false, value }; }, }; } From d1936b3dcee6be43ca53aea8514fe27358971145 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Sat, 20 Jan 2024 17:07:32 +0900 Subject: [PATCH 10/12] =?UTF-8?q?docs:=20README=20=EC=88=98=EC=A0=95=20=20?= =?UTF-8?q?-=20=EA=B0=81=20=EC=9E=90=EB=A3=8C=EA=B5=AC=EC=A1=B0=EC=9D=98?= =?UTF-8?q?=20API=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem-1-1/README.md | 9 ++++++--- problem-2-1/README.md | 10 +++++++++- problem-3-1/README.md | 11 ++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/problem-1-1/README.md b/problem-1-1/README.md index 2b698ce..9ae8499 100644 --- a/problem-1-1/README.md +++ b/problem-1-1/README.md @@ -2,9 +2,12 @@ 1. 백의 정의에 따라서 API를 설계해 주세요. -| 함수 시그니처 | 설명 | -| ----------- | ----------- | -| sample(string): number | 문자열을 입력으로 받아 숫자로 변환해서 반환합니다 | +| 함수 시그니처 | 설명 | +|--------------------|----------------------------------------------------| +| `Bag()` | 백을 생성합니다. | +| `size(): number` | 백에 들어있는 아이템 개수를 반환합니다. | +| `isEmpty(): boolean` | 백에 아이템이 없다면 `true`, 아이템이 하나라도 있다면 `false` 를 반환합니다. | +| `add(item: any): void` | 백에 아이템을 추가합니다. | 2. 다음 값들을 백에 추가했을 때 어떻게 되는지 그림으로 그려보세요. diff --git a/problem-2-1/README.md b/problem-2-1/README.md index 2f9a3e6..af8ce40 100644 --- a/problem-2-1/README.md +++ b/problem-2-1/README.md @@ -1,10 +1,18 @@ # 자료구조와 알고리즘 2주차 과제 - 스택 구현하기 1. 스택의 정의에 따라서 API를 설계해 주세요. + - LIFO: Last-In, First-Out (가장 마지막에 담긴 아이템이 가장 먼저 나온다.) + - 입력과 출력이 항상 같은 곳에서 일어난다. + - 순회할 때는 역순으로 순회한다. | 함수 시그니처 | 설명 | | ----------- | ----------- | -| sample(string): number | 문자열을 입력으로 받아 숫자로 변환해서 반환합니다 | +| `Stack()` | 스택을 생성합니다. | +| `isEmpty(): boolean` | 스택에 아이템이 없다면 `true`, 아이템이 하나라도 있다면 `false` 를 반환합니다. | +| `size(): number` | 스택에 담긴 아이템의 개수를 반환합니다. | +| `push(item: any): void` | 스택에 아이템을 추가합니다. | +| `pop(): item` | 스택에 가장 마지막에 담긴 아이템을 반환합니다. | + 2. 다음 값들을 스택에 추가했을 때 어떻게 되는지 그림으로 그려보세요. `(-)`은 값을 꺼내는 것을 의미합니다. diff --git a/problem-3-1/README.md b/problem-3-1/README.md index 4d27b95..e7cd238 100644 --- a/problem-3-1/README.md +++ b/problem-3-1/README.md @@ -2,9 +2,14 @@ 1. 큐의 정의에 따라서 API를 설계해 주세요. -| 함수 시그니처 | 설명 | -| ----------- | ----------- | -| sample(string): number | 문자열을 입력으로 받아 숫자로 변환해서 반환합니다 | +| 함수 시그니처 | 설명 | +|----------------------------|----------------------------------------------------| +| `Queue()` | 큐를 생성합니다. | +| `isEmpty(): void` | 큐에 아이템이 없다면 `true` 를, 아이템이 하나라도 있다면 `false` 를 반환합니다. | +| `size(): number` | 큐에 담긴 아이템의 개수를 반환합니다. | +| `enqueue(item: any): void` | 큐에 아이템을 추가합니다. | +| `dequeue(): item` | 큐의 첫 번째 아이템을 꺼냅니다. | + 2. 다음 값들을 큐에 추가했을 때 어떻게 되는지 그림으로 그려보세요. `(-)`은 값을 꺼내는 것을 의미합니다. From 4d40e62842d060cae5983dca41559b8975da9a44 Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Sat, 20 Jan 2024 17:46:01 +0900 Subject: [PATCH 11/12] =?UTF-8?q?refactor:=20dequeue=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95=20=20-=20dequeue()=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=20=ED=9B=84=20queue=20=EC=97=90=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=ED=85=9C=EC=9D=B4=20=EB=82=A8=EC=95=84=20=EC=9E=88=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8B=A4=EB=A9=B4=20#last=20=EB=8A=94=20undefined=20?= =?UTF-8?q?=EB=A5=BC=20=EA=B0=80=EB=A6=AC=EC=BC=9C=EC=95=BC=20=ED=95=9C?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem-3-1/problem-3-1.test.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/problem-3-1/problem-3-1.test.js b/problem-3-1/problem-3-1.test.js index 8960458..e6cccb7 100644 --- a/problem-3-1/problem-3-1.test.js +++ b/problem-3-1/problem-3-1.test.js @@ -45,11 +45,24 @@ class Queue { const firstItem = this.#first.item; this.#first = this.#first.next; + // todo: 아이템 개수를 먼저 줄인 다음, isEmpty() 를 확인해서 #last 를 undefined 처리한다. this.#numberOfItems -= 1; + if (this.isEmpty()) { + this.#last = undefined; + } + return firstItem; } + first() { + return this.#first; + } + + last() { + return this.#last; + } + [Symbol.iterator]() { let current = this.#first; @@ -100,7 +113,22 @@ test('큐에서 요소를 제거하면 개수가 감소한다', () => { expect(newSize - oldSize).toEqual(-1); }); -test('가장 나중에 삽입한게 먼저 나온다', () => { +test('가장 먼저 삽입한게 먼저 나온다', () => { + const queue = new Queue(); + + queue.enqueue('D'); + queue.enqueue('S'); + queue.enqueue('A'); + + expect(queue.dequeue()).toBe('D'); + expect(queue.dequeue()).toBe('S'); + expect(queue.dequeue()).toBe('A'); + + expect(queue.first()).toBeUndefined(); + expect(queue.last()).toBeUndefined(); +}); + +test('아이템을 모두 제거하면 first, last 는 모두 undefined 를 가리켜야 한다.', () => { const queue = new Queue(); queue.enqueue('D'); @@ -110,6 +138,9 @@ test('가장 나중에 삽입한게 먼저 나온다', () => { expect(queue.dequeue()).toBe('D'); expect(queue.dequeue()).toBe('S'); expect(queue.dequeue()).toBe('A'); + + expect(queue.first()).toBeUndefined(); + expect(queue.last()).toBeUndefined(); }); test('큐이 비어있는데 dequeue을 하면 예외를 던진다', () => { From 5d4afc23964954f62238af15e6e6cea9c7f4c09d Mon Sep 17 00:00:00 2001 From: whoodongpyo Date: Mon, 22 Jan 2024 12:16:53 +0900 Subject: [PATCH 12/12] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problem-1-1/problem-1-1.test.js | 4 ++-- problem-1-2/problem-1-2.test.js | 4 ++-- problem-2-1/problem-2-1.test.js | 4 ++-- problem-2-2/problem-2-2.test.js | 4 ++-- problem-3-1/problem-3-1.test.js | 4 ++-- problem-3-2/problem-3-2.test.js | 13 ++++++------- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/problem-1-1/problem-1-1.test.js b/problem-1-1/problem-1-1.test.js index dc951f7..2d9a596 100644 --- a/problem-1-1/problem-1-1.test.js +++ b/problem-1-1/problem-1-1.test.js @@ -1,7 +1,7 @@ class Node { - #item; + item; - #next; + next; } class Bag { diff --git a/problem-1-2/problem-1-2.test.js b/problem-1-2/problem-1-2.test.js index d8bba9d..c4c710e 100644 --- a/problem-1-2/problem-1-2.test.js +++ b/problem-1-2/problem-1-2.test.js @@ -1,7 +1,7 @@ class Node { - #item; + item; - #next; + next; } class Bag { diff --git a/problem-2-1/problem-2-1.test.js b/problem-2-1/problem-2-1.test.js index d9bb382..2393dba 100644 --- a/problem-2-1/problem-2-1.test.js +++ b/problem-2-1/problem-2-1.test.js @@ -1,7 +1,7 @@ class Node { - #item; + item; - #next; + next; } class Stack { diff --git a/problem-2-2/problem-2-2.test.js b/problem-2-2/problem-2-2.test.js index f0db977..0e5b231 100644 --- a/problem-2-2/problem-2-2.test.js +++ b/problem-2-2/problem-2-2.test.js @@ -1,7 +1,7 @@ class Node { - #item; + item; - #next; + next; } class Stack { diff --git a/problem-3-1/problem-3-1.test.js b/problem-3-1/problem-3-1.test.js index e6cccb7..3e86be4 100644 --- a/problem-3-1/problem-3-1.test.js +++ b/problem-3-1/problem-3-1.test.js @@ -1,7 +1,7 @@ class Node { - #item; + item; - #next; + next; } class Queue { diff --git a/problem-3-2/problem-3-2.test.js b/problem-3-2/problem-3-2.test.js index e5dd6e0..8180ade 100644 --- a/problem-3-2/problem-3-2.test.js +++ b/problem-3-2/problem-3-2.test.js @@ -1,7 +1,7 @@ class Node { - #item; + item; - #next; + next; } class Queue { @@ -78,14 +78,13 @@ const createNumberArray = (itemCount) => { return resultArray; }; -const solution = (N, M) => { - const numberOfPersons = N; - const deathLocation = M; - +const solution = (numberOfPersons, deathLocation) => { const persons = createNumberArray(numberOfPersons); const queue = new Queue(); - persons.forEach((person) => queue.enqueue(person)); + persons.forEach((person) => { + queue.enqueue(person); + }); while (queue.size() > 1) { for (let index = 0; index < deathLocation - 1; index += 1) {