본문 바로가기
개발일지 TIL(Today I Learned)

[2023.06.20] 개발일지

자바스크립트의 기본적인 문법을 공부한 후 마주하게 된 알고리즘 문제.

바위에 계란치기로 일단 부딪혀 보며 완성한 코드들 중 다시 한 번 풀어보고 싶거나 다른 방법으로 풀면 좋은 문제들, 그리고 풀면서 정말 이해 안 가고 어려웠던 문제들을 정리해보려 한다.

 

 

 

◈ 문제 설명

이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.

 

◈ 제한조건

  • n과 m은 각각 1000 이하인 자연수입니다.

예시

입력

5  3

출력

*****
*****
*****

 

 

 

이제 막 JavaScript를 입문한 나로서는 도저히 어떻게 해결해야할지 감도 잡히지 않은 상황이었다.

 

하지만 오랜 고민끝에 문득 떠올린 생각이 있었으니

그것은 바로 얼마 전 웹개발종합반 강의에서 스치듯이 지나갔던 repeat() 메서드!

 

1
2
3
4
5
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]);
});
cs

 

문제에서 우선적으로 주어진 코드는 이러하다.

처음 접하는 알고리즘 문제부터 한 번도 본 적이 없는 문법들이 나와 당황했다.

서둘러 구글링을 통해 알아보니...

 

process.stdin.setEncoding('utf8')

: 표준 입력 스트림의 인코딩을 UTF-8로 설정한다.

 

무슨 말인가 싶어 쉽게 설명하자면 사용자로부터 받은 입력을 문자열로 처리하기 위해서 하는 설정이라고 한다.

 

process.stdin.on('data', data => { ... })

: 사용자가 입력을 완료하고 엔터키를 누르면 해당 이벤트가 발생하게끔 만드는 설정.

 

이 두 설정을 통해 사용자가 값을 입력하면 그 데이터를 변수에 할당하게 끔 했다.

 

그 후

const n = data.split(" ") 

       를 이용해 공백을 기준으로 데이터를 분리하여 배열로 변환한 값을 변수 'n'에 할당하고

const a = Number(n[0]), b = Number(n[1])

       로 n(array)값의 [0] 값(첫번째 값)을 a라고 선언, n값의 [1] 값(두번째 값)을 b라고 선언했다.

 

여기까지 문제에서 주어진 코드였고

지금부터가 본격적으로 repeat() 메서드를 이용해 문제를 풀어나갈 시간이다.

 

repeat() 메서드의 기본 구조는 이러하다.

1
string.repeat(count)
cs

 

풀어 설명하자면 문자열을 count한만큼 반복한다는 뜻이다.

기본적으로 문제를 풀기 위해 필요한 것은 '*' 이란 문자열을 가로로 한 번, 세로로 한 번 반복하는 것.

그렇기에 반복 수단을 두 번 사용하면 될 것이다.

 

이를 바탕으로 내가 처음 완성한 코드는 이렇다.

 

1
2
3
4
5
6
7
8
9
10
11
12
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]); // 입력받은 n의 첫번째 값이 가로의 길이, 두번째 값이 세로의 길이라고 정의
    let row = '*'.repeat(a); // repeat() 메서드를 이용해 a(가로의 길이)만큼 '*'를 반복한 값을 변수 row에 할당
    for (let i = 0; i < b; i++) {
        if (i === b) {
            break;
        };
        console.log(row);
    }; // 가로로 이어진 '*'를 반복문을 통해 b(세로의 길이)만큼 반복
});
cs

repeat() 을 이용해 한 번, 그리고 for문을 이용해 한 번 더 반복했다.

코드를 전부 작성하고 다른 사람들의 풀이 방법을 보니 멍청한 실수를 저질렀다는 걸 뒤늦게 발견했다!

 

반복 코드로 사용된 if문을 통해 반복 변수 i가 변수 b의 수가 되기 직 전에 반복을 멈추게끔 코드를 짰는데

다시금 생각해보니 반복문의 조건 자체가 일정한 값에서 반복을 멈추도록 구간을 지정한다는 것이었다.

 

이런 어처구니 없는 실수는 내가 for문이란 문법을 정확히 숙지하지 못한 채 알고리즘 문제에 직면한 탓에 일어난 일!

다음부턴 이런 실수가 일어나지 않도록 기본을 탄탄히 다져놓는 게 몹시 중요할 것이다.

 

 

우여곡절 끝에 완성된 코드의 완전한 모습이다.

 

▶ repeat() 메서드 이용

1
2
3
4
5
6
7
8
9
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]); // 입력받은 n의 첫번째 값이 가로의 길이, 두번째 값이 세로의 길이라고 정의
    let row = '*'.repeat(a); // repeat() 메서드를 이용해 a(가로의 길이)만큼 '*'를 반복한 값을 변수 row에 할당
    for (let i = 0; i < b; i++) {
        console.log(row);
    }; // 가로로 이어진 '*'를 반복문을 통해 b(세로의 길이)만큼 반복
});
cs

 

이렇게 보니 다시 드는 생각은 repeat() 메서드를 두 번 사용하면 굳이 for문이 없어도 되지 않을까 하는 정도인데

그렇다면 반대로 repeat() 메서드를 쓰지 않고도 for문을 이용한 풀이로도 문제를 해결할 수 있지 않을까?

 

 

▶ for문 만을 이용

1
2
3
4
5
6
7
8
9
10
11
12
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]); // 입력받은 n의 첫번째 값이 가로의 길이, 두번째 값이 세로의 길이라고 정의
    var answer = "";
    for (let i = 0; i < a; i++) {
        answer += "*"// '*'를 a(가로길이)만큼 반복해서 더해줌
        for (let j = 0; j < b; j++) {
            console.log(answer); // answer를 b(세로길이)만큼 반복해서 
        };
    };
});
cs

 

입력

5 3

출력

*
*
*
**
**
**
***
***
***
****
****
****
*****
*****
*****

코드를 짜니 입출력 값이 생각했던 것과는 다르게 나온다.

 

결과값을 자세히 들여다보니 반복문 안에 반복문을 넣다보니 반복변수 i의 모든 경우의 수들을 j만큼 반복하게 된다는 것을 깨닫게 되었다.

 

그렇다면 이걸 어떻게 해결할까.

깊게 생각하지 않아도 가장 안 쪽 반복문을 바깥으로 꺼내와 두 반복문을 나란히 정렬시키면 된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]); // 입력받은 n의 첫번째 값이 가로의 길이, 두번째 값이 세로의 길이라고 정의
    var answer = "";
    for (let i = 0; i < a; i++) {
        answer += "*"// '*'를 a(가로길이)만큼 반복해서 더해줌
    };
    for (let j = 0; j < b; j++) {
        console.log(answer); // answer를 b(세로길이)만큼 반복해서 출력
    };
});
cs

 

 

 

 

알고리즘 문제를 풀어보니 확실히 깨달은 점이 하나 있다.

기초적인 것부터 차근차근 쌓아올리지 않는다면 오늘 같은 실수를 언제든 반복할 수 있다는 것이다.

정확하게 알고 있지 않았던 repeat() 메서드라던가 for 반복문 같은 키워드의 정확한 활용법을 조금 더 알아가게 되었다.

 

아침부터 알고리즘 문제를 직면한 코딩의 햇병아리 입장으로서의 오늘 공부는 굉장히 얻은 것이 많은 하루다.

 

<< fin. >>

'개발일지 TIL(Today I Learned)' 카테고리의 다른 글

[2023.06.27] 개발일지  (0) 2023.06.28
[2023.06.26] 개발일지  (0) 2023.06.28
[2023.06.23] 개발일지  (0) 2023.06.28
[2023.06.22] 개발일지  (0) 2023.06.28
[2023.06.21] 개발일지  (0) 2023.06.28