Skip to content
9 changes: 6 additions & 3 deletions problem-1-1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

1. 백의 정의에 따라서 API를 설계해 주세요.

| 함수 시그니처 | 설명 |
| ----------- | ----------- |
| sample(string): number | 문자열을 입력으로 받아 숫자로 변환해서 반환합니다 |
| 함수 시그니처 | 설명 |
|--------------------|----------------------------------------------------|
| `Bag()` | 백을 생성합니다. |
| `size(): number` | 백에 들어있는 아이템 개수를 반환합니다. |
| `isEmpty(): boolean` | 백에 아이템이 없다면 `true`, 아이템이 하나라도 있다면 `false` 를 반환합니다. |
| `add(item: any): void` | 백에 아이템을 추가합니다. |

2. 다음 값들을 백에 추가했을 때 어떻게 되는지 그림으로 그려보세요.

Expand Down
47 changes: 47 additions & 0 deletions problem-1-1/problem-1-1.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,51 @@
class Node {
#item;

#next;
}

class Bag {
#first;

#numberOfItems;

constructor() {
this.#numberOfItems = 0;
}

size() {
return this.#numberOfItems;
}

isEmpty() {
return this.#numberOfItems === 0;
}

add(item) {
const oldFirst = this.#first;

this.#first = new Node();
this.#first.item = item;
this.#first.next = oldFirst;

this.#numberOfItems += 1;
}

[Symbol.iterator]() {
let current = this.#first;
return {
next() {
if (current === undefined) {
return { done: true };
}

const value = current.item;
current = current.next;

return { done: false, value };
},
};
}
}

test('백은 비어있는 상태로 생성된다', () => {
Expand Down
73 changes: 73 additions & 0 deletions problem-1-2/problem-1-2.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,77 @@
class Node {
#item;

#next;
}

class Bag {
#first;

#numberOfItems;

constructor() {
this.#numberOfItems = 0;
}

size() {
return this.#numberOfItems;
}

isEmpty() {
return this.#numberOfItems === 0;
}

add(item) {
const oldFirst = this.#first;

this.#first = new Node();
this.#first.item = item;
this.#first.next = oldFirst;

this.#numberOfItems += 1;
}

sum() {
let sum = 0;
let current = this.#first;

while (current !== undefined) {
sum += current.item;
current = current.next;
}

return sum;
}

average() {
return Math.floor(this.sum() / this.size());
}

[Symbol.iterator]() {
let current = this.#first;
return {
next() {
if (current === undefined) {
return { done: true };
}

const value = current.item;
current = current.next;

return { done: false, value };
},
};
}
}

const solution = (numbers) => {
const bag = new Bag();

numbers.forEach((number) => {
bag.add(number);
});

return bag.average();
};

test('숫자 배열의 평균을 반환한다', () => {
Expand Down
10 changes: 9 additions & 1 deletion problem-2-1/README.md
Original file line number Diff line number Diff line change
@@ -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. 다음 값들을 스택에 추가했을 때 어떻게 되는지 그림으로 그려보세요. `(-)`은 값을 꺼내는 것을 의미합니다.

Expand Down
61 changes: 61 additions & 0 deletions problem-2-1/problem-2-1.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,65 @@
class Node {
#item;

#next;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node 객체를 선언할 때 item과 next를 private으로 선언하셨네요. 하지만 코드를 사용하는 곳을 보면 이렇게 사용하고 있습니다.

this.#first.item = item;

그래서 원래 의도와는 다르게 퍼블릭 item속성에 접근하고 있는 것 같습니다. 자바스크립트가 타입이 없다보니 이런 실수가 일어난 것 같네요.

그리고 여기서 Node의 속성들은 private일 필요는 없습니다. 왜냐하면 단순한 자료 구조를 나타내는 객체라서 캡슐화가 필요 없기 때문이에요. Stack은 외부에서 first속성을 건드리면 안되기 떄문에 접근하지 못하도록 private으로 선언했지만, Node는 그렇지 않습니다.


class Stack {
#first;

#numberOfItem;

constructor() {
this.#numberOfItem = 0;
}

isEmpty() {
return this.#numberOfItem === 0;
}

size() {
return this.#numberOfItem;
}

push(item) {
// todo : 맨 앞에 아이템을 넣는 방식.
const oldFirst = this.#first;

this.#first = new Node();
this.#first.item = item;
this.#first.next = oldFirst;

this.#numberOfItem += 1;
}

pop() {
if (this.isEmpty()) {
throw new Error('스택이 비어있습니다');
}
// todo: push 할 때 맨 앞에 가장 최근 아이템이 들어오니까 pop 할 때도 맨 앞에 있는 아이템을 꺼내야 한다.
const latestItem = this.#first.item;
this.#first = this.#first.next;

this.#numberOfItem -= 1;

return latestItem;
}

[Symbol.iterator]() {
let current = this.#first;
return {
next() {
if (current === undefined) {
return { done: true };
}

const value = current.item;
current = current.next;

return { done: false, value };
},
};
}
}

test('스택을 생성하면 비어있다', () => {
Expand Down
87 changes: 87 additions & 0 deletions problem-2-2/problem-2-2.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,91 @@
class Node {
#item;

#next;
}

class Stack {
#first;

#numberOfItem;

constructor() {
this.#numberOfItem = 0;
}

isEmpty() {
return this.#numberOfItem === 0;
}

size() {
return this.#numberOfItem;
}

push(item) {
// todo : 맨 앞에 아이템을 넣는 방식.
const oldFirst = this.#first;

this.#first = new Node();
this.#first.item = item;
this.#first.next = oldFirst;

this.#numberOfItem += 1;
}

pop() {
if (this.isEmpty()) {
throw new Error('스택이 비어있습니다');
}
// todo: push 할 때 맨 앞에 가장 최근 아이템이 들어오니까 pop 할 때도 맨 앞에 있는 아이템을 꺼내야 한다.
const latestItem = this.#first.item;
this.#first = this.#first.next;

this.#numberOfItem -= 1;

return latestItem;
}

[Symbol.iterator]() {
let current = this.#first;
return {
next() {
if (current === undefined) {
return { done: true };
}

const value = current.item;
current = current.next;

return { done: false, value };
},
};
}
}

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를 반환한다', () => {
Expand Down
11 changes: 8 additions & 3 deletions problem-3-1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

1. 큐의 정의에 따라서 API를 설계해 주세요.

| 함수 시그니처 | 설명 |
| ----------- | ----------- |
| sample(string): number | 문자열을 입력으로 받아 숫자로 변환해서 반환합니다 |
| 함수 시그니처 | 설명 |
|----------------------------|----------------------------------------------------|
| `Queue()` | 큐를 생성합니다. |
| `isEmpty(): void` | 큐에 아이템이 없다면 `true` 를, 아이템이 하나라도 있다면 `false` 를 반환합니다. |
| `size(): number` | 큐에 담긴 아이템의 개수를 반환합니다. |
| `enqueue(item: any): void` | 큐에 아이템을 추가합니다. |
| `dequeue(): item` | 큐의 첫 번째 아이템을 꺼냅니다. |


2. 다음 값들을 큐에 추가했을 때 어떻게 되는지 그림으로 그려보세요. `(-)`은 값을 꺼내는 것을 의미합니다.

Expand Down
Loading