Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발일기

[새싹 프론트엔드] 반복문 조건문 배열 실습 문제 다시풀기 본문

JavaScript

[새싹 프론트엔드] 반복문 조건문 배열 실습 문제 다시풀기

화영강 2022. 11. 6. 01:23

문제 1.
정수를 입력하면 그 수의 약수를 출력하라

<결과>

<body>
    <script>
        let num = parseInt(prompt("정수를 입력하세요"));

        document.write(`입력한 수 : ${num}<br>`);
        document.write(`50의 약수 : `);
        for (let i = 1; i <= num; i++) {
            if (num % i === 0) {
                document.write(`${i} `);
                //for문을 이용해서 1부터 num까지의 반복할 숫자 i를 만들고
                //num을 i로 나누면 0이 되는 값(=약수)를 찾는다
            }
        }

    </script>
</body>

처음에는 이렇게 for문을 이용해서 약수가 되는 값을 바로 출력하는 방식으로 풀었다.
그런데 이 약수들을 배열안에 넣어서 배열을 출력하는 방법으로 풀고싶었다.
그래서 만든 두번째풀이.

<body>
    <script>
        let input = parseInt(prompt("정수를 입력하시오"));
        //prompt로 입력받는 값은 모두 문자열로 저장되므로 parseInt로 숫자로 변경해준다
        let num = [];
        //약수를 저장할 배열 선언

        for (let i = 1; i <= input; i++) {
            if (input % i === 0) {
                num.push(i);
                //push 메소드를 사용하여 input을 i로 나눴을 때 0이 되는 값들을 배열에 추가
            }
        }

        document.write(`입력한 수 : ${input}<br>`);
        document.write(`${input}의 약수 : ${num.join(" ")}`);
        //join() : 배열에 포함된 모든 원소를 하나의 문자열로 생성
    </script>
</body>

아니 근데 두번째 풀 때는 for문 사용해서 푸는 방법이 생각이 안나서 한참을 고민했다.
첫번째로 풀 때는 바로 풀었는데 뭔일이고,,
암튼 코드가 더 길어지긴 했으나 이렇게 값들을 배열로 넣어놓는게 좀 더 안정성(?) 있어보였다.
배열을 사용한 덕분에 push와 join 메소드도 한번씩 사용할 수 있었음.




문제 2.
통신 요금 계산하기

<결과>

<body>
    <script>
        let contract = parseInt(prompt("계약금액을 입력하세요"));
        let month = parseInt(prompt("사용 개월 수를 입력하세요"));
        let card = parseInt(prompt("사용 카드 번호를 입력하세요"));

        let mDiscount;      //개월 수에 따른 할인
        let cDiscount;      //카드 번호에 따른 할인

        //개월 수에 따른 할인
        if (month > 12) {
            mDiscount = contract * 0.2;      //12개월 초과 20% 할인
        } else if (month > 6) {
            mDiscount = contract * 0.1;      //6개월 초과 12개월 이하 10% 할인
        }

        //카드 번호에 따른 할인
        switch (card) {
            case 11:
                cDiscount = contract * 0.05;
                break;
            case 12:
                cDiscount = contract * 0.08;
                break;
            case 13:
                cDiscount = contract * 0.12;
                break;
        }

        let result = contract - mDiscount - cDiscount;

        document.write(`계약 금액 : ${contract}<br>`);
        document.write(`사용 개월 수 : ${month}<br>`);
        document.write(`카드 코드 : ${card}<br>`);
        document.write(`최종 요금 : ${result}<br>`);
    </script>
</body>

이거 풀때 첨에 할인 부분에서

mDiscount = contract * 0.2  
mDiscount = contract * 20% 이렇게 사용했다.

js에서 %는 나머지를 구하는 연산이라 이렇게 퍼센트를 구할 때 사용하면 결과값이 나오지 않으므로 주의해야한다.
이번문제에 계산하는게 조금 있다고 헷갈려서
결과값이 마이너스 나왔다가 2500원 나왔다가 난리가 났다..





문제 4.
커피자판기

<결과>

<body>

    <script>
        let coffee = 300;
        let money;

        for (let i = 10; i > 0; i--) {
            money = parseInt(prompt(`돈을 넣어주세요.(남은커피:${i})`));

            if (money === coffee) {
                alert(`커피를 줍니다.`);
            } else if (money > coffee) {
                alert(`거스름돈 ${money - coffee}원과 커피를 줍니다.(남은커피:${i - 1})`);
            } else if (money < coffee) {
                alert(`돈이 부족합니다.`);
                i++;
            }
        }
    </script>
</body>

금요일에 늦게까지 못풀었던 문제 중 하나였다.
남은 커피를 계산하는게 어려웠는데 for문에 i값을 10부터 1까지 내려가도록 만들면 되는것이었다.

처음에 프롬프트를 for문 밖에서 선언하고, if문 안의 alert를 document.write로 출력을 해서
실행시켰더니 커피를 줍니다 폭탄..

다시 for문으로 넣고 한참 또 헤메다가 alert를 document.write로 바꾸고 해결을 했다.





문제 5.
합격/불합격 판별

<결과>

<body>

    <script>
        let students = [];
        //let input;
        let result;

        for (let i = 0; i < 5; i++) {
            // input = parseInt(prompt(`${i+1}번 학생의 점수를 입력하세요`));
            // students.push(input);
            students.push(prompt(`${i + 1}번 학생 점수를 입력하세요`));

            (students[i] > 60) ? result = "합격" : result = "불합격";

            document.write(`${i + 1}번 학생은 ${result}입니다.<br>`);
            //변수 i는 for문 안에서만 사용 가능하므로 for문 안으로 넣었다.
        }

    </script>
</body>


다시 풀면 더 괜찮은 코드만 나올것같은데 꼭 그렇지만도 않다.
for문에 프롬프트를 한 줄로 만들었었는데 다시 풀때는 두 줄로 만들고, input이라는 쓸모없는 변수도 만들었다.
그리고 push()를 push[]로 써서 또 한참 고민하고...

개선된 부분은 예전에는 점수입력 따로, 결과출력 따로 해서 for문을 2번 썼는데 하나로 합쳤다.
그리고 간단한 if문은 삼항연산으로 풀어서 코드를 한줄로 만들었다.





문제 6.
점수의 합계 및 평균 구하기

<결과>

<body>
    <script>
        let students = [];
        let sum = 0;    

        for (let i = 0; i < 5; i++) {
            //학생 배열을 만들고 거기에 prompt로 입력한 숫자들을 저장한다.
            students.push(parseInt(prompt(`${i + 1}번 학생 점수를 입력하세요`)));
        }

        let max = Math.max(...students);    //students 배열 중 최댓값
        let min = Math.min(...students);    //students 배열 중 최솟값

        //최저, 최고점수를 제외한 나머지의 합과 평균을 구하기위해 먼저 총 합을 구한다.
        for (let i = 0; i < 5; i++) {
            sum += students[i];
        }

        let sResult = sum - max - min;       //최저, 최대 제외한 합계
        let avg = sResult/3;                //최저, 최대 제외한 평균

        document.write(`입력한 점수 : ${students.join(",")}<hr>`);
        document.write(`최고 점수 : ${max}<br>`);
        document.write(`최저 점수 : ${min}<hr>`);
        document.write(`합 : ${sResult}<br>`);
        document.write(`평균 : ${avg}`);
    </script>
</body>

이것도 처음에 풀 때는 안풀려서 미뤄뒀던 문제이다.

* Math.max Math.min은 수업시간에 배우진 않았지만 구글링해서 사용했다.
Math.max와 Math.min은 파라미터로 입력받은 숫자들 중 최소값과 최대값을 구해서 리턴하는 함수이다.
그리고 안에 배열의 변수를 넣어서 배열의 요소중 최대 최소값을 구할 수 있다.
배열을 넣을 때는 Math.max(...arr) 이런식으로 ...다음에 배열명을 입력하면 된다.

* 처음 문제풀때 계속 에러가 났던 부분은 합과 평균 부분이었다.

사진처럼 합이 내가 입력한 순서대로 출력이 됐다.
앞에 0이 붙을걸로 보아 변수 sum을 0으로 초기화 시킨것에서 온 것 같았다.
즉, 지금 sum이 숫자가 아니라 문자열로 저장이 되는데 이 부분을 도저히 알 수 가 없어서 강사님께 물어봤다.
알고보니 내가 프롬프트를 parseInt로 받지 않아서 문자열로 받아진것이다.
최대값, 최소값은 Math라는 함수를 이용해서 자동으로 숫자로 형변환 되었지만
합과 평균은 문자열 그대로 저장되었다.
prompt에 parseInt를 붙여주니 제대로 실행됐다.




문제 7.
로또 번호 뽑기

<결과>

<body>
    <h1>로또 1등 당첨 번호</h1>
    <hr>

    <script>
        let lotto = [];     //로또 번호들이 저장될 배열
        let num;

        for(let i=0; i<6; i++) {
            //i는 0부터 5까지 반복되며 로또 번호는 총 6개이기 때문

            num = Math.floor(Math.random()*45+1);
            //변수 input는 1~45까지 랜덤으로 출력되는 변수이다.

            //중복값이 나오지 않게 하려고 배열에 동일한 값이 있는지 확인하는 includes() 함수를 사용
            //동일한 값이 있으면 true, 없으면 false 출력
            if(lotto.includes(num) === false) {
                lotto[i] = num;
                //동일한 값이 없으면 랜덤으로 받은 숫자가 lotto[0]번에 추가됨
            } else {
                //동일한 값이 있으면 i값을 1빼주고 continue
                i--;
                //continue;
                //그런데 continue는 왜 사용하는 걸까? -> 없어도 잘 돌아감
                //else일때 i에서 1빼주면 밖으로 나와서 또 for문 돌리는거 아닌가?
            }
        }

        document.write(lotto);
        //배열 값 전체가 출력된다
    </script>
</body>

이 문제에서 어려웠던 부분은 중복되는 값을 제외하고 출력을 만드는 것이었다.
배열의 메소드 includes()를 이용하여 동일한 값이 있는지 확인할 수 있다.

한가지 궁금한 점은 else의 continue인데
continue를 사용하지 않아도 계속 될 것같은데 안된다. 왜 그런걸까?

다시 해보니 없어도 잘 돌아간다..

document.write(lotto);를 하면 배열 전체 값이 출력된다.
알고 있었던건지 몰랐던건지, 안쓰니까 잊어버리게 된다.

 
 
 
 
 
#정리

실습문제 코드를 점검만 해보는 것이 아니라, 아예 다시 풀어봤다.
좀 더 깔끔한 코드가 되었으면 해서 이것저것 해 봤는데 한번 더 푼다고 해서
더 완벽하게 코드를 짜는건 아니었다.
첫번째 실습을 풀때보다 코드를 못짠 경우도 있지만 뭐 괜찮다.

다시 풀면서 새로운 방법으로 풀려고 노력하기도 하고,
평소보다 주석을 많이 달아서 좀 더 정리가 되는 느낌이었다.
새롭게 알게된 부분이나 헷갈렸던 부분들을 짚고 넘어갈 수 있어서 좋았다.

그런데 이렇게 문제 전체를 다시 풀기에는 시간이 많이 소요된다.
평일에는 실습문제 중 모르는 문제, 헷갈리는 문제 위주로만 다시 풀고,
전체 문제는 주말에 시간이 나게 되면 정리 해야겠다.


새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 3주차 블로그 포스팅