아래 4개의 문제에 대해 문제 풀이를 작성하였습니다.
프로그래머스 - 연습문제 - 직사각형 별찍기
프로그래머스 - 연습문제 - 두 정수 사이의 합
프로그래머스 - 월간 코드 챌린지 시즌2 - 음양 더하기
프로그래머스 - 연습문제 - 행렬의 덧셈
이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.
n과 m은 각각 1000 이하인 자연수입니다.
입력
5, 3
출력
*****
*****
*****
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
const n = data.split(" ");
const a = Number(n[0]), b = Number(n[1]);
var width = ''
var result = ''
for (let j = 0; j < b; j++) {
for (let i = 0; i < a; i++) {
width += '*';
}
width += '\n'
result += width;
width=''
}
console.log(result);
});
직사각형에 대해 첫번째 입력값 a
를 가로, 두번째 입력값을 b
를 세로로 두고 이중 for
문을 수행한다.
세로로 한 줄씩 가로 a
값의 크기만큼 * 문자를 추가하여 width
변수에 저장한 후, 한 줄이 모두 끝났을때 개행문자 \n
을 추가하고 다음 줄로 이동하여 result
값에 저장한다.
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
const n = data.split(" ");
const a = Number(n[0]), b = Number(n[1]);
const star = `${'*'.repeat(a)}\n`;
console.log(star.repeat(b));
});
다른 사람의 풀이를 살펴보며 repeat
라는 함수를 확인할 수 있었고, 사용 예는 아래와 같다.
string.repeat(n)
-string
문자열을n
번 반복합니다.
두 정수 a, b가 주어졌을 때 a와 b 사이에 속한 모든 정수의 합을 리턴하는 함수, solution을 완성하세요.
예를 들어 a = 3, b = 5인 경우, 3 + 4 + 5 = 12이므로 12를 리턴합니다.
- a와 b가 같은 경우는 둘 중 아무 수나 리턴하세요.
- a와 b는 -10,000,000 이상 10,000,000 이하인 정수입니다.
- a와 b의 대소관계는 정해져있지 않습니다.
입력
a=3, b=5
a=3, b=3
a=5, b=3
출력
return=12
return=3
return=12
function solution(a, b) {
var answer = 0;
// a가 b보다 큰 경우
if (a > b){
for (let j = b; j <= a; j++){
answer += j
}
} else if (b > a) { // b가 a보다 큰 경우
for (let i = a; i <= b; i++){
answer += i
}
} else { // a === b 인 경우
answer = a
}
return answer;
}
a
와 b
의 대소 관계가 정해지지 않았으므로, 경우의 수는 3가지
a > b
, b > a
, a === b
세 가지 케이스에 대해 if~else
문을 작성하고, for
문을 돌며 answer
변수에 a
와 b
사이의 값을 모두 더한다.
이 때, 두 가지 숫자 중 더 큰 값을 포함해야 하므로 a > b
인 for
문에서
for (let j = b; j < a; j++)
가 아닌,
for (let j = b; j <= a; j++)
로 a
값을 포함하여 계산한다.
다만 이 방식으로 문제를 풀 경우, 정수 입력값이
-10,000,000
에서10,000,000
사이 이기 때문에, 예제의 최대 입력값과 최소 입력값이 입력될 경우 시간이 오래 걸리는 것을 확인하였다(프로그래머스 채점 기준 소요시간0.04ms ~ 28.23ms
까지 다양했음).
다른 방법이 필요해 추가로 검색을 진행했다.
function solution(a, b){
return (a+b)*(Math.abs(b-a)+1)/2;
}
1부터 100까지의 합을 공식화 했을때 100 * (100+1)/2 = 5050
형태인것을 응용하여, 아주 깔끔하게 풀어낸 예시였다. 그리고 이 예시는 사실 아래와 같이 풀어 쓸 수 있다.
등차수열의 제1항 a
, 마지막n항 b
, a와 b사이의 정수 개수 n
.
answer = (a+b) * n / 2
n
을 구하기 위해선, 주어진 두 정수 중에서 큰 수에서 작은 수를 뺀 후 +1을 하면 나온다. a
와 b
의 크기 비교를 진행하고 a
가 클 경우 a-b
를, b
가 클 경우 b-a
를 수행하려고 하였으나 위 풀이에서는 아래 함수를 사용해 해결하였다.
Math.abs(number)
는 주어진 숫자 number
의 절대값을 반환한다.
따라서, a
와 b
의 대소 비교를 할 필요 없이 한쪽에서 값을 뺀 후 절대값을 취해준 뒤, +1
을 하면 갯수가 정확하게 나온다.
어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.
absolutes의 길이는 1 이상 1,000 이하입니다.
- absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.
signs의 길이는 absolutes의 길이와 같습니다.
signs[i]
가 참이면absolutes[i]
의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.
입력
absolutes
: [4,7,12]
signs
: [true, false, true]
absolutes
: [1,2,3]
signs
: [false, false, true]
출력
result
: 9
+4 -7 +12
)result
: 0
-1 -2 +3
)function solution(absolutes, signs) {
var answer = 0;
for (let i = 0; i < signs.length; i++){
if (signs[i] === true){
answer += absolutes[i];
} else {
answer += absolutes[i]*-1;
}
}
return answer;
}
absolutes
배열과 signs
배열의 크기는 같다고 주어졌기 때문에, for
문을 돌며 signs
배열 내의 값을 가져와 true
일 경우엔 양의 정수 그대로 answer
에 더하고, false
인 경우는 absolutes[i]
값에 -1
을 곱하여 answer
에 더해 결과값을 도출하였다.
function solution(absolutes, signs) {
let answer = 0;
for (let i = 0; i < signs.length; i++) {
signs[i] ? answer += absolutes[i] : answer -= absolutes[i]
}
return answer;
}
삼항 연산자를 사용하고, signs[i]
값이 false
인 경우 -1
을 곱해서 더하지 않고 그냥 빼게끔 구현되었다. MDN Web Docs 에 제시된 예시가 이해가 빨랐다.
function getFee(isMember) {
return (isMember ? '$2.00' : '$10.00');
}
isMember
함수를 통해, isMember
가 true
인 경우 '$2.00' 를 리턴값으로 주고 false
, null
인 경우 '$10.00' 을 리턴값으로 반환한다.
행렬의 덧셈은 행과 열의 크기가 같은 두 행렬의 같은 행, 같은 열의 값을 서로 더한 결과가 됩니다. 2개의 행렬 arr1과 arr2를 입력받아, 행렬 덧셈의 결과를 반환하는 함수, solution을 완성해주세요.
- 행렬 arr1, arr2의 행과 열의 길이는 500을 넘지 않습니다.
입력
arr1
: [[1,2],[2,3]]
, arr2
: [[3,4],[5,6]]
arr1
: [[1],[2]]
, arr2
: [[3],[4]]
출력
result
: [[4,6],[7,9]]
result
: [[4],[6]]
function solution(arr1, arr2) {
// 리턴 값을 배열 리터럴 []; 로 미리 생성. Array() 생성자 함수로 선언한 것과 동일
var answer = [];
// 행렬 덧셈 시작
for (var i=0; i<arr1.length; i++) {
answer[i] = []; // 생성한 배열 안에 배열을 추가하여 중첩 배열 생성
for (var j=0; j<arr1[i].length; j++) {
answer[i][j] = arr1[i][j] + arr2[i][j];
}
}
return answer;
}
자바스크립트에서의 배열은 다른 언어와 다른 점 2가지를 들었다.
- 배열 내부의 데이터 타입은 서로 다를 수 있다.
- 배열의 크기는 동적으로 변경될 수 있다.
따라서 배열 내부에 배열을 담을 수 있다. 배열 안의 배열 요소에 대한 접근은 array[0][1];
과 같이 접근할 수 있는데, 아래 console.table(array);
함수를 사용하면 시각적으로 볼 수 있어서 배열 요소를 탐색하는데 도움이 많이 되었다.
var array = solution([[1, 2], [2, 3]], [[3, 4], [5, 6]]);
console.table(array);
console.log(array([0][1])); // 1행 2열의 = 6 반환
(index) | 0 | 1 |
---|---|---|
0 | 4 | 6 |
1 | 7 | 9 |
function solution(A, B){
let answer_array = new Array();
answer_array = A.map((a, i) => a.map((b, j) => b + B[i][j]));
return answer_array;
}
// 아래는 테스트로 출력해 보기 위한 코드입니다.
console.log(solution([[1,2], [2,3]], [[3,4],[5,6]]))
Array.map
, =>
등의 못보던 함수를 사용하여 구현됐다.
Array.map
은 주어진 3개의 인자 (currentValue, index => function)
를 사용해 .map
을 호출한 배열의 내부 값을 순차적으로 탐색하며 function
을 수행한 뒤, 새로운 배열을 만들어서 리턴한다고 한다. 아래 예제로 확인해보면,
const numbers = [2, 3, 4];
numbers.map((number, index) => {
// number: 현재 처리중인 배열의 element(요소값)
// index: 현재 처리중인 source배열의 index
console.log(number, index); // 2, 0
return number * number;
});
// return : [4, 9, 16]
위 코드는 아래와 같이 풀어 쓸수 있다.
const numbers = [2, 3, 4];
function Mathpow(number){
return number * number; // Math.pow(number,2);
}
let newNumbers = numbers.map((number, index)=> Mathpow(number));
// index를 생략할경우 : let newNumbers = numbers.map(number => Mathpow(number));
console.log(newNumbers)
log를 찍어보면 처음 표시되는 것은 배열의 index[0]
번째 요소값 2
, 현재의 index
값과 현재 처리중인 배열인 numbers
배열이다.
위 예제에서 console.log(number, index);
만 실행시켰다면 배열을 순차적으로 탐색하며 요소값과 index값이 나오게 된다. 2 0 / 3 1 / 4 2
순으로 콘솔에 찍히게 된다.
다른사람의 풀이를 하나씩 분리해보면 아래와 같다.
A 배열 [[1,2],[2,3]]
Array A | 0 | 1 |
---|---|---|
0 | [1,2] | [2,3] |
B 배열 [[3,4],[5,6]]
Array B | 0 | 1 |
---|---|---|
0 | [3,4] | [5,6] |
A.map((a, i) => ... // a=Array[1,2], i=0
중첩배열 Array A
의 첫번째 요소(A[i]
) a=[1,2]
에 처음 도달한다.
Array "A" | 0 | 1 |
---|---|---|
0 | [1,2] | [2,3] |
A.map((a, i) => a.map((b, j) => // b=1, j=0
배열 Array A[i]
의 첫번째 요소(A[i][j]
) b=1
을 찾는다.
Array "A[0]" | 0 | 1 |
---|---|---|
0 | 1 | 2 |
A.map((a, i) => a.map((b, j) => b + B[i][j])) // b + B[0][0]
위에서 찾아둔 b와 Array B
의 [i][j]
, 즉 B[0][0] = 3
값을 b
와 더한다.
Array "B" | 0 | 1 |
---|---|---|
0 | [3,4] | [5,6] |
answer_array = A.map((a, i) => a.map((b, j) => b + B[i][j]));
Array answer_array
의 [0][0]
값에 b + B[0][0]
값을 더해서 넣는다. 이후 다른 행렬에도 반복 작업 수행.
Array "answer_array" | 0 | 1 |
---|---|---|
0 | 4 |
결과
Array "answer_array" | 0 | 1 |
---|---|---|
0 | 4 | 6 |
1 | 7 | 9 |