diff --git a/problem-1-1/problem-1-1.test.js b/problem-1-1/problem-1-1.test.js index 6ab9348..2cc3ab6 100644 --- a/problem-1-1/problem-1-1.test.js +++ b/problem-1-1/problem-1-1.test.js @@ -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(); diff --git a/problem-1-2/problem-1-2.test.js b/problem-1-2/problem-1-2.test.js index f2956b6..8536c91 100644 --- a/problem-1-2/problem-1-2.test.js +++ b/problem-1-2/problem-1-2.test.js @@ -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); + }; test('숫자 배열의 평균을 반환한다', () => { diff --git a/problem-2-1/problem-2-1.test.js b/problem-2-1/problem-2-1.test.js index 17412df..f9b654b 100644 --- a/problem-2-1/problem-2-1.test.js +++ b/problem-2-1/problem-2-1.test.js @@ -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('스택을 생성하면 비어있다', () => { diff --git a/problem-2-2/problem-2-2.test.js b/problem-2-2/problem-2-2.test.js index dab5212..df31cf1 100644 --- a/problem-2-2/problem-2-2.test.js +++ b/problem-2-2/problem-2-2.test.js @@ -1,6 +1,67 @@ -const solution = (string) => { +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(); + + return { + next(){ + return index < stack.length ? {done : false, value : stack[index++]} : {done : true} + } + } + + } +} + +const solution = (string = '') => { + if(string.length % 2 === 1 || string.length === 0) return false; + + const stack = new Stack(); + const brackets = { '[': ']', '{': '}', '(': ')' }; + + for (const bracket of string) { + if(brackets[bracket]){ + stack.push(bracket); + }else{ + + if(stack.isEmpty()) return false; + + const savedBracket = stack.pop(); + + if(brackets[savedBracket] !== bracket) return false; + } + } + + return true; + }; +test('문자열에 포함된 괄호의 짝이 맞지 않을 때 false를 반환한다', () => { + expect(solution('()(')).toBe(false); +}); + test('문자열에 포함된 괄호의 짝이 맞을 때 true를 반환한다', () => { expect(solution('{([])}')).toBe(true); }); diff --git a/problem-3-1/problem-3-1.test.js b/problem-3-1/problem-3-1.test.js index 6ae251f..d6800be 100644 --- a/problem-3-1/problem-3-1.test.js +++ b/problem-3-1/problem-3-1.test.js @@ -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('큐를 생성하면 비어있다', () => { diff --git a/problem-3-2/problem-3-2.test.js b/problem-3-2/problem-3-2.test.js index 21bd836..c1e2042 100644 --- a/problem-3-2/problem-3-2.test.js +++ b/problem-3-2/problem-3-2.test.js @@ -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); + } + } + + [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번째 사람을 없앨 때 마지막에 죽는 사람의 순서를 반환한다', () => {