Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions problem-1-1/problem-1-1.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,47 @@

//1. 백의 정의에 따라서 API를 설계해 주세요.
// | 함수 시그니처 | 설명 |
// | ----------- | ----------- | ----------- | ----------- | ----------- |
// | isEmpty(): boolean | 배열 빈값 여부에 따라 값을 boolean형태로 반환합니다 |
// | add(string): void | 아이템을 받아 배열에 추가합니다. |
// | size(): number | 배열의 길이를 반환합니다. |
// | ----------- | ----------- | ----------- | ----------- | ----------- |


//3. 클라이언트 코드가 올바르게 동작하도록 백 자료구조를 만들어 주세요.
class Bag {
constructor(){
this.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('백은 비어있는 상태로 생성된다', () => {
const bag = new Bag();

Expand Down
9 changes: 8 additions & 1 deletion problem-1-2/problem-1-2.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const solution = (numbers) => {
const solution = (numbers = []) => {
if(numbers.length === 0) return 0;

const total = numbers.reduce((acc, curr) => acc + curr, 0),
average = total / numbers.length;

return Math.floor(average);

};
Comment on lines +1 to 9
Copy link
Contributor

Choose a reason for hiding this comment

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

이 문제가 Bag 자료구조를 사용해서 문제를 해결하는 것이 의도였습니다.


test('숫자 배열의 평균을 반환한다', () => {
Expand Down
66 changes: 66 additions & 0 deletions problem-2-1/problem-2-1.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,70 @@
// 1. 스택의 정의에 따라서 API를 설계해 주세요.

// | 함수 시그니처 | 설명 |
// | ----------- | ----------- | ----------- | ----------- |
// | Stack(): 스택을 생성합니다. |
// | isEmpty(): boolean | stack 배열의 빈값 여부에 따라 boolean 타입을 반환합니다. |
// | push(item): void | stack 배열에 아이템을 추가합니다. |
// | size(): number | stack 배열의 길이를 반환합니다. |
// | pop(): string | Error | stack 배열에 가장 최근에 삽입한 값을 반환합니다. |
class Node {
#item;
#next;
}

class Stack {
#first;
#n;

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

isEmpty(){
return this.#first === undefined;
}


//resize를 왜 private함수로 했는지 궁금합니다
push(item){
const oldFirst = this.#first;

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

this.#n++;
}

size(){
return this.#n;
}

pop(){
if(this.#first === undefined) throw new Error('스택이 비어있습니다');

const item = this.#first.item;
this.#n--;

this.#first = this.#first.next;

return item;
}

[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
54 changes: 54 additions & 0 deletions problem-2-2/problem-2-2.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,58 @@
class Stack {
constructor(){
this.stack = [];
}

isEmpty(){
return this.stack.length === 0;
}

push(item){
this.stack.push(item);
}

size(){
return this.stack.length;
}

pop(){
if(this.isEmpty()) throw new Error('스택이 비어있습니다');

return this.stack.pop();
}

[Symbol.iterator](){
let index = 0,
stack = [...this.stack];
stack = stack.reverse();
Comment on lines +25 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

reverse메서드가 원본 배열을 수정하다보니, 스택에 있는 값들을 복사한 후 reverse를 실행하셨군요.
toReversed를 사용하면 원본 배열을 수정하지 않고 순서를 바꿀 수 있습니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed


return {
next(){
return index < stack.length ? {done : false, value : stack[index++]} : {done : true}
}
}

}
}

const solution = (string) => {
const stack = new Stack();
const brackets = { '[': ']', '{': '}', '(': ')' };

for (const bracket of string) {
if(brackets[bracket]){
stack.push(bracket);
}else{

if(stack.isEmpty()) return false;

const savedBrackets = stack.pop();
Copy link
Contributor

Choose a reason for hiding this comment

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

�스택에서 가장 위에 요소를 하나 pop해서 현재 괄호의 짝과 같은지 비교하고 있네요. 변수 이름이 복수라서 마치 배열이나 리스트를 가리킬것 처럼 보이네요. 하나를 나타낼때는 savedBracket이라고만 해도 좋습니다.

if(brackets[savedBrackets] !== bracket) return false;
}
}

return true;
Copy link
Contributor

Choose a reason for hiding this comment

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

검사를 모두 통과한 경우 true를 반환하고 있습니다. 만약 이런 경우의 인풋이 들어온 경우는 어떻게 될까요?

"()("

Copy link
Author

Choose a reason for hiding this comment

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

false를 반환해야 하는데 true를 반환하네요 ㅠ


};

test('문자열에 포함된 괄호의 짝이 맞을 때 true를 반환한다', () => {
Expand Down
76 changes: 76 additions & 0 deletions problem-3-1/problem-3-1.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,80 @@
// 1. 큐의 정의에 따라서 API를 설계해 주세요.
// | 함수 시그니처 | 설명 |
// | ----------- | ----------- |
// | Queue() | 큐를 생성합니다.|
// | isEmpty(): boolean | items 배열의 빈값 여부에 따라 boolean타입을 반환합니다.|
// | size(): number | items의 배열의 길이를 반환합니다. |
// | enqueue(item): void | items배열에 item을 추가합니다.|
// | dequeue(): string | items배열에 가장 먼저 추가 된 item을 제거하고 제거된 item을 반환합니다.|

class Node{
#item;
#next;
}

class Queue {
#n;
#first;
#last;

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

isEmpty(){
return this.#first === undefined;
}

size(){
return this.#n;
}

enqueue(item){
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.#n++;
}

dequeue(){
if(this.isEmpty()) throw new Error('큐가 비어있습니다');

const item = this.#first.item;
this.#first = this.#first.next;

if(this.isEmpty()){
this.#last = undefined;
}

this.#n--;

return item;
}

[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
58 changes: 58 additions & 0 deletions problem-3-2/problem-3-2.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,62 @@
class Queue {
constructor(){
this.items = [];
}

isEmpty(){
return this.items.length === 0;
}

size(){
return this.items.length;
}

enqueue(item){
this.items.push(item);
}

dequeue(){
if(this.size() === 0) throw new Error('큐가 비어있습니다');

const item = this.items.shift();
return item;
}

setNumbers(number){
for(let i = 1; i <= number; i++){
this.enqueue(i);
}
}
Comment on lines +25 to +29
Copy link
Contributor

Choose a reason for hiding this comment

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

Queue자료구조에 메서드를 추가하셨네요. 1주차에서 배운 추상 데이터 타입을 떠올리면서, 이 문제를 위한 추상 데이터 타입을 만들어 볼 수도 있을 것 같습니다.

class People {
  constructor(peopleCount) {
    this.queue = new Queue();
    for(let i = 1; i <= peopleCount; i++){
      this.queue.enqueue(i);
    }
  }

  lastLivePositionOf(M) {
    while (this.queue.size() > 1) {
      for (let index = 0; index < M - 1; index += 1) {
        const dequeuedNumber = this.queue.dequeue();
        this.queue.enqueue(dequeuedNumber);
      }
      this.queue.dequeue();
    }
  
    return this.queue.dequeue();
  }
}

const solution = (N, M) => {
  const people = new People(N);
  return people.lastLivePositionOf(M);
};

이렇게 하면 M번째 사람을 없앨 때 가장 오래 살아남는 사람을 구할 때 내부적으로 어떤 자료구조를 사용하는지 드러나지 않습니다.

도메인으로 기술된 내용이 많이 없어서 표현력을 좋게 못 끌어올렸는데, 최대한 표현해봤습니다

Copy link
Contributor

Choose a reason for hiding this comment

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

이런.. 문제를 다시 읽어보니 결국 마지막 사람도 죽게 되는 거군요. 최대한 오래 살아남을 수 있는 위치를 알고 싶은 거니까 longLivePosition도 괜찮겠네요. (결국 죽지만)


[Symbol.iterator](){
let index = 0;
const queue = [...this.items];

return {
next() {
return index < queue.length
? { done: false, value: queue[index++] }
: { done: true };
},
};
}


}

const solution = (N, M) => {
const queue = new Queue();
queue.setNumbers(N);

while (queue.size() > 1) {
for (let index = 0; index < M - 1; index += 1) {
const dequeuedNumber = queue.dequeue();
queue.enqueue(dequeuedNumber);
}
queue.dequeue();
}

return queue.dequeue();
};

test('N명의 사람이 있을 때 M번째 사람을 없앨 때 마지막에 죽는 사람의 순서를 반환한다', () => {
Expand Down