Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dsa-week1-assignment 윤영서 #2

Merged
merged 15 commits into from
Sep 4, 2023
Merged
49 changes: 44 additions & 5 deletions problem-1/problem-1.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,57 @@
//1.가장 익숙한 방법으로 문제를 해결해 주세요.

Check failure on line 1 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment

Check failure on line 1 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment
{

Check failure on line 2 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Block is redundant

Check failure on line 2 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Block is redundant
/*

Check failure on line 3 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected space or tab before '*/' in comment

Check failure on line 3 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected space or tab before '*/' in comment
const solution = (numbers) => {
let sum = 0;
if (numbers.length === 0) {
return 0;
}
for (let i = 0; i < numbers.length; i++) {
sum += parseInt(numbers[i], 10);
}

return sum;
};*/
}
//2.이번에는 재귀 함수로 문제를 해결해 주세요.

Check failure on line 16 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment

Check failure on line 16 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment
{

Check failure on line 17 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Block is redundant

Check failure on line 17 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Block is redundant
/*
const solution = (numbers, index = 0) => {
if (index >= numbers.length) {
return 0;
} else {
return numbers[index] + solution(numbers, index + 1);
}
};
Comment on lines +19 to 25
Copy link
Contributor

Choose a reason for hiding this comment

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

아마 for문이 지금 제일 익숙해서 index를 이용해서 해결해주신 것 같아요. 빈 배열이 주어진 경우와, 배열이 하나씩 줄어둔다는 것을 이용할 수 있다는 것도 알아두시면 좋을 것 같습니다.

const solution = (numbers) => {
  if (numbers.length === 0) {
    return 0;
  }

  return numbers[0] + solution(numbers.slice(1));
};

Copy link
Contributor Author

Choose a reason for hiding this comment

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

slice 메소드를 사용할 수 있다는건 생각도 안했네요 ㅠㅠ 감사합니다 ㅎㅎ

*/
}

//3. 꼬리 재귀 함수로 바꿔보세요.

Check failure on line 29 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment

Check failure on line 29 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment
//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요.

Check failure on line 30 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment

Check failure on line 30 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Expected exception block, space or tab after '//' in comment
const solution = (numbers) => {
let index = 0;
let acc = 0;

test('빈 배열은 0을 반환한다', () => {
while (index < numbers.length) {
acc = acc + numbers[index];
index++;

Check failure on line 37 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Unary operator '++' used

Check failure on line 37 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Unary operator '++' used
}

return acc;
};
test("빈 배열은 0을 반환한다", () => {

Check failure on line 42 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote

Check failure on line 42 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote
expect(solution([])).toBe(0);
});

test('배열의 합을 반환한다', () => {
test("배열의 합을 반환한다", () => {

Check failure on line 46 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote

Check failure on line 46 in problem-1/problem-1.test.js

View workflow job for this annotation

GitHub Actions / build

Strings must use singlequote
expect(solution([1, 2, 3, 4])).toBe(10);
expect(solution([-1, 3, 8, 9, 10, 11])).toBe(40);
});

test('큰 배열이 입력으로 주어져도 RangeError를 던지지 않는다', () => {
test("큰 배열이 입력으로 주어져도 RangeError를 던지지 않는다", () => {
const input = Array.from({ length: 10000 }, (_, i) => i + 1);

expect(() => solution(input))
.not.toThrowError(new RangeError('Maximum call stack size exceeded'));
expect(() => solution(input)).not.toThrowError(
new RangeError("Maximum call stack size exceeded")
);
});
45 changes: 39 additions & 6 deletions problem-2/problem-2.test.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,59 @@
//1. 가장 익숙한 방법으로 문제를 해결해 주세요.
//2. 이번에는 재귀 함수로 문제를 해결해 주세요.
{
/*
const solution = (n) => {
if (n <= -1) {
return 0;
} else if (n === 0 || n === 1) {
return n;
} else {
return solution(n - 1) + solution(n - 2);
}
};
*/
}
//3. 꼬리 재귀 함수로 바꿔보세요.
//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요.
const solution = (n) => {
let pre = 0;
let curr = 1;
let temp = 0;
if (n <= -1) {
return 0;
} else if (n === 0 || n === 1) {
return n;
}
while (n >= 2) {
temp = pre;
pre = pre + curr;
curr = temp;
n--;
}
return pre + curr;
};
Comment on lines +18 to 34
Copy link
Contributor

Choose a reason for hiding this comment

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

프로그램을 더 이상 실행할 필요가 없을 경우 빠르게 종료하도록 하면, 아래 코드를 더 이상 읽지 않아도 되기도 하고 불필요한 코드 실행도 막을 수 있어요. 게다가 진짜 코드의 의도는 아래에 배치하여 의도를 드러낼 수도 있습니다.

const solution = (n) => {
  if (n <= -1) {
    return 0;
  }
  
  if (n === 0 || n === 1) {
    return n;
  }
  
  let pre = 0;
  let curr = 1;
  let temp = 0;

  while (n >= 2) {
    temp = pre;
    pre = pre + curr;
    curr = temp;
    n--;
  }

  return pre + curr;
};

See also

Copy link
Contributor Author

Choose a reason for hiding this comment

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

얼리리턴을 생각해놓고는 할당을 하고 얼리리턴을 해줘버렸네요 ㅎㅎ 감사합니다!!


test('음수가 주어지면 0을 반환한다', () => {
test("음수가 주어지면 0을 반환한다", () => {
expect(solution(-1)).toBe(0);
});

test('0부터 1까지는 정해진 수를 반환한다', () => {
test("0부터 1까지는 정해진 수를 반환한다", () => {
expect(solution(0)).toBe(0);
expect(solution(1)).toBe(1);
});

test('2이상 주어지면 앞 두 항의 합을 반환한다', () => {
test("2이상 주어지면 앞 두 항의 합을 반환한다", () => {
expect(solution(2)).toBe(1);
expect(solution(3)).toBe(2);
expect(solution(4)).toBe(3);
expect(solution(5)).toBe(5);
expect(solution(6)).toBe(8);
});

test('큰 입력이 주어져도 RangeError를 던지지 않는다', () => {
test("큰 입력이 주어져도 RangeError를 던지지 않는다", () => {
const input = 100000;

expect(() => solution(input))
.not.toThrowError(new RangeError('Maximum call stack size exceeded'));
expect(() => solution(input)).not.toThrowError(
new RangeError("Maximum call stack size exceeded")
);
});
69 changes: 56 additions & 13 deletions problem-3/problem-3.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,64 @@
//1. 가장 익숙한 방법으로 문제를 해결해 주세요.
{
/*
const solution = (n) => {
let binaryString = "";
if (n <= 1) {
return "" + n;
}
while (n >= 1) {
binaryString += (n % 2).toString();
n = parseInt(n / 2);
}
return binaryString.split("").reverse().join("");
};*/
}
//2. 이번에는 재귀 함수로 문제를 해결해 주세요.
{
/*
const solution = (n, binaryString = "") => {
if (n <= 1) {
return n + binaryString;
}

const remainder = n % 2;
binaryString = remainder + binaryString;
return solution(parseInt(n / 2, 10), binaryString);
};
*/
}

//3. 꼬리 재귀 함수로 바꿔보세요.
//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요.
const solution = (n) => {
let binaryString = "";
if (n <= 1) {
return n + binaryString;
}
while (n >= 1) {
const remainder = n % 2;
binaryString = remainder + binaryString;
n = parseInt(n / 2);
}
return binaryString;
};

test('이진수 문자열을 반환한다', () => {
expect(solution(0)).toBe('0');
expect(solution(1)).toBe('1');
expect(solution(2)).toBe('10');
expect(solution(3)).toBe('11');
expect(solution(4)).toBe('100');
expect(solution(5)).toBe('101');
expect(solution(6)).toBe('110');
expect(solution(7)).toBe('111');
expect(solution(8)).toBe('1000');
test("이진수 문자열을 반환한다", () => {
expect(solution(0)).toBe("0");
expect(solution(1)).toBe("1");
expect(solution(2)).toBe("10");
expect(solution(3)).toBe("11");
expect(solution(4)).toBe("100");
expect(solution(5)).toBe("101");
expect(solution(6)).toBe("110");
expect(solution(7)).toBe("111");
expect(solution(8)).toBe("1000");
});

test('큰 입력이 주어져도 RangeError를 던지지 않는다', () => {
test("큰 입력이 주어져도 RangeError를 던지지 않는다", () => {
const input = Number.MAX_VALUE;

expect(() => solution(input))
.not.toThrowError(new RangeError('Maximum call stack size exceeded'));
expect(() => solution(input)).not.toThrowError(
new RangeError("Maximum call stack size exceeded")
);
});
77 changes: 63 additions & 14 deletions problem-4/problem-4.test.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,70 @@
const solution = () => {
//1. 가장 익숙한 방법으로 문제를 해결해 주세요.
{
/*
const solution = (n) => {
let decimal = 0;
let exponent = 0;
if (n === "0" || n === "1") {
return parseInt(n, 10);
}
const length = n.length;
while (exponent <= length - 1) {
decimal += parseInt(n.charAt(n.length - 1), 10) * 2 ** exponent;

exponent++;
n = n.slice(0, -1);
}
return decimal;
};*/
}
//2. 이번에는 재귀 함수로 문제를 해결해 주세요.
{
/*
const solution = (n, acc = 0, exponent = 0) => {
if (n.length === 1) {
return acc + parseInt(n, 10) * 2 ** exponent;
}
acc += parseInt(n.charAt(n.length - 1), 10) * 2 ** exponent;
return solution(n.slice(0, -1), acc, exponent + 1);
};*/
}

//3. 꼬리 재귀 함수로 바꿔보세요.
//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요.
const solution = (n) => {
let acc = 0;
let exponent = 0;

const length = n.length;
if (length === 1) {
return acc + parseInt(n, 10) * 2 ** exponent;
}
Copy link
Contributor

@hannut91 hannut91 Aug 14, 2023

Choose a reason for hiding this comment

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

연산자의 우선순위는 프로그래밍 언어마다 다를수도 있어요. 그래서 a + b + c같이 아주 자명한 경우가 아니라면 적절히 괄호로 묶어주는 것이 좋습니다.

    return acc + parseInt(n, 10) * (2 ** exponent);


while (exponent <= length - 1) {
acc += parseInt(n.charAt(n.length - 1), 10) * 2 ** exponent;

Copy link
Contributor

Choose a reason for hiding this comment

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

문자열 마지막 문자를 숫자로 변경한 후에 제곱을 더해주고 있는 것 같아요. 문자열 마지막이라면 index로 접근해도 좋을 것 같아요

Suggested change
acc += parseInt(n.charAt(n.length - 1), 10) * 2 ** exponent;
acc += parseInt(n.charAt(n.length - 1), 10) * 2 ** exponent;

exponent++;
n = n.slice(0, -1);
}
return acc;
};

test('10진수 숫자를 반환한다', () => {
expect(solution('0')).toBe(0);
expect(solution('1')).toBe(1);
expect(solution('10')).toBe(2);
expect(solution('11')).toBe(3);
expect(solution('100')).toBe(4);
expect(solution('101')).toBe(5);
expect(solution('110')).toBe(6);
expect(solution('111')).toBe(7);
expect(solution('1000')).toBe(8);
test("10진수 숫자를 반환한다", () => {
expect(solution("0")).toBe(0);
expect(solution("1")).toBe(1);
expect(solution("10")).toBe(2);
expect(solution("11")).toBe(3);
expect(solution("100")).toBe(4);
expect(solution("101")).toBe(5);
expect(solution("110")).toBe(6);
expect(solution("111")).toBe(7);
expect(solution("1000")).toBe(8);
});

test('큰 입력이 주어져도 RangeError를 던지지 않는다', () => {
test("큰 입력이 주어져도 RangeError를 던지지 않는다", () => {
const input = Number.MAX_VALUE.toString(2);

expect(() => solution(input))
.not.toThrowError(new RangeError('Maximum call stack size exceeded'));
expect(() => solution(input)).not.toThrowError(
new RangeError("Maximum call stack size exceeded")
);
});
36 changes: 31 additions & 5 deletions problem-5/problem-5.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
const solution = () => {
//1. 가장 익숙한 방법으로 문제를 해결해 주세요.
//2. 이번에는 재귀 함수로 문제를 해결해 주세요.
{
/*
const solution = (b, a) => {
if (a === 0) {
return b;
}
return solution(a, b % a);
};
*/
}

test('최대 공약수를 반환한다', () => {
//3. 꼬리 재귀 함수로 바꿔보세요.
//4. 꼬리 재귀 최적화를 통해서 최적화해 보세요.
const solution = (b, a) => {
let temp;
while (true) {

Check warning on line 18 in problem-5/problem-5.test.js

View workflow job for this annotation

GitHub Actions / build

Unexpected constant condition

Check warning on line 18 in problem-5/problem-5.test.js

View workflow job for this annotation

GitHub Actions / build

Unexpected constant condition
if (a === 0) {
return b;
}
temp = a;
a = b % temp;
b = temp;
console.log(b + " " + a);

Check warning on line 25 in problem-5/problem-5.test.js

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement

Check warning on line 25 in problem-5/problem-5.test.js

View workflow job for this annotation

GitHub Actions / build

Unexpected console statement
}
};

test("최대 공약수를 반환한다", () => {
expect(solution(4, 12)).toBe(4);
expect(solution(3, 7)).toBe(1);
expect(solution(16, 72)).toBe(8);
expect(solution(9, 12)).toBe(3);
});

test('큰 입력이 주어져도 RangeError를 던지지 않는다', () => {
test("큰 입력이 주어져도 RangeError를 던지지 않는다", () => {
const a = Number.MAX_VALUE;
const b = 1213;

expect(() => solution(a, b))
.not.toThrowError(new RangeError('Maximum call stack size exceeded'));
expect(() => solution(a, b)).not.toThrowError(
new RangeError("Maximum call stack size exceeded")
);
});
44 changes: 41 additions & 3 deletions problem-6/problem-6.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,45 @@
const solution = (n) => {
//1. 재귀 함수로 문제를 해결해 주세요.
{
/*const solution = (n) => {
if (n === 1) {
return 1;
}

if (n === 2) {
return 2;
}

if (n === 3) {
return 4;
}

return solution(n - 1) + solution(n - 2) + solution(n - 3);
};*/
}

//2. 다이나믹 프로그래밍으로 최적화 해주세요.
const solution = (n, memo = []) => {
if (n === 1) {
return 1;
}

if (n === 2) {
return 2;
}

if (n === 3) {
return 4;
}

if (!memo[n]) {
memo[n] =
solution(n - 1, memo) + solution(n - 2, memo) + solution(n - 3, memo);
}

return memo[n];
};

test('계단에 오를 수 있는 가지 수를 반환한다', () => {
test("계단에 오를 수 있는 가지 수를 반환한다", () => {
expect(solution(1)).toBe(1);
expect(solution(2)).toBe(2);
expect(solution(3)).toBe(4);
Expand All @@ -14,6 +52,6 @@ test('계단에 오를 수 있는 가지 수를 반환한다', () => {
expect(solution(10)).toBe(274);
});

test('큰 입력이 주어져도 시간안에 실행된다', async () => {
test("큰 입력이 주어져도 시간안에 실행된다", async () => {
expect(solution(40)).toBe(23837527729);
});