웹: 로그, 조합 계산기

3 분 소요


</br> 가끔 조합이나 로그, 행렬 이런 게 필요할 때가 있는데, 대체로 간단한 게 아니면 계산 하기 귀찮아서 구글에 ‘조합 계산기’하고 검색해서 사용하는 편이다.
그런데 매번 검색해서 들어가기도 귀찮고, 내가 자주 쓰는 기능들만 모여 있었으면 좋겠으니까 한 번 따로 만들어 보기로 했다.
</br>

HTML, JavaScript, CSS

웹응용프로그래밍 강의를 수강하고 나선 오랜만에 사용한다
짧은 코드고 딱히 꾸밀 것도 없으니까 html 안에 자바스크립트랑 css 다 넣도록 하자

<!DOCTYPE html>

<html>
   <head>
      <meta charset = "utf-8">
      <title>Title</title>
      <style type="text/css">
          /* css classes */
      </style>
      <script>
          /* javascript functions */
      </script>
   </head>

   <body>
       <!--body(table, form, ...)-->
   </body>
</html>

대충 이런 구조
헤드 부분에 css, 자바 스크립트 부분을 두고 바디 부분에 실제로 보일 화면을 만든다.
</br>

계산기 만들기

로그 계산기

우선 비교적 간단한 로그 계산기부터 만들어 보자.

1. <body>

바디 부분에는 테이블을 사용해서 보여줘야 겠다.

로그 인풋 버튼 아웃풋
ln 사용자 입력 = \?

대충 이런 식이면 좋을 것 같다

   <body>
       <h2>로그 계산기</h2>
       <table>
           <tbody>
               <tr align="left" bgcolor="white">
                   <th width="50">ln</th>
                   <td><input type="text" size="10" id="log"></td>
                   <td><button type="button" onclick="myLog()">=</button></td>
                   <td id="logAns" class="line" width="200"></td>
               </tr>
               <tr align="left" bgcolor="white">
                   <th width="50">log2</th>
                   <td><input type="text" size="10" id="log2"></td>
                   <td><button type="button" onclick="myLog2()">=</button></td>
                   <td id="log2Ans" class="line" width="200"></td>
               </tr>
               <tr align="left" bgcolor="white">
                   <th width="50">log10</th>
                   <td><input type="text" size="10" id="log10"></td>
                   <td><button type="button" onclick="myLog10()">=</button></td>
                   <td id="log10Ans" class="line" width="200"></td>
               </tr>
           </tbody>
   </body>

<h> 구문으로 제목을 달아주고 테이블을 생성한다.
<tr>은 한 행이다. <th>로 로그 종류(ln, log2, log10)을 적어 준다. 이후 <td>로 순서대로 입력 칸, 버튼, 결과 칸을 만들어 준다.
버튼을 누르면, 입력 칸의 텍스트를 읽어서, 처리를 하고, 결과 칸에 출력해 줄 것이므로 입력칸과 결과 칸의 아이디가 필요하다.
</br>

2. <head>
      <style type="text/css">
          .line{border-bottom: 1px solid gray;}
      </style>

결과 칸에 가볍게 회색 밑줄을 그어보자
css로 이렇게 해 주면, class="line"으로 사용할 수 있다.

<script>
    function myLog(){
        var a = parseFloat(document.getElementById("log").value);
        document.getElementById("logAns").textContent = Math.log(a);
    }
    function myLog2(){
        var a = parseFloat(document.getElementById("log2").value);
        document.getElementById("log2Ans").textContent = Math.log2(a);
    }
    function myLog10(){
        var a = parseFloat(document.getElementById("log10").value);
        document.getElementById("log10Ans").textContent = Math.log10(a);
    }
</script>

자바스크립트에는 Math.log() 함수가 있다.
따라서 각 함수가 불러지면, document.getElementById()로 엘리먼트에 접근해서, .value로 그 값을 얻고 로그를 취해주고 결과 칸에 적어 준다.
</br>

조합 계산기

1. <body>
    <h2>조합 계산기</h2>
    <table>
        <tbody>
            <tr align="left" bgcolor="white">
                <th width="50">nCr</th>
                <td><input type="text" size="8" id="n"></td>
                <td>C</td>
                <td><input type="text" size="8" id="r"></td>
                <td><button type="button" onclick="myComb()">=</button></td>
                <td id="combAns" class="line" width="200"></td>
            </tr>
        </tbody>
    </table>
조합 인풋 조합 인풋 버튼 아웃풋
nCr 사용자 입력 C 사용자 입력 = \?

디자인은 귀찮으니 직관적이게 만들자
</br>

2. <head>

조합은 그냥 팩토리얼로 하면 큰 수는 오버플로우 난다 자바스크립트라고 크게 다를 건 없을 거다
저번에 백준에서도 푼 2407: 조합(https://cyj893.github.io/algorithm/Algorithm16_4)에서, 큰 수 조합을 계산하는 걸 해 봤다
따라서 수를 문자열로 처리해서 곱했는데, 이걸 응용하도록 하자

<script>
    var cp = [];
    var ans = [];

    function mult(p){
        var one = 0;
        var sz = ans.length-1;
        for(var i = 0; i < sz+1; i++){
            var t = ans[sz-i] * p + one;
            one = Math.floor(t/10);
            ans[sz-i] = t%10;
        }
        while( one != 0 ){
            ans.unshift(one%10);
            one = Math.floor(one/10);
        }
    }

    function primes(k, isMinus){
        var j = 2;
        while( k > 1 ){
            if( (k % j) == 0 ){
                cp[j] += isMinus;
                k /= j;
            }
            else j++;
        }
    }

    function myComb(){
        var n = parseInt(document.getElementById("n").value);
        var r = parseInt(document.getElementById("r").value);
        for(var i = 0; i <= n; i++){
            cp[i] = 0;
        }
        for(var i = 0; i < r; i++){
            primes(n-i, 1);
        }
        for(var i = 2; i <= r; i++){
            primes(i, -1);
        }
        ans = [1];
        for(var i = 0; i <= n; i++){
            if( cp[i] != 0 ){
                mult(Math.pow(i, cp[i]));
            }
        }
        var txt = "";
        for(var i = 0; i < ans.length; i++){
            txt += String(ans[i]);
        }
        document.getElementById("combAns").textContent = txt;
    }
</script>

일단 n과 r을 받아오고 cp[] 배열을 0으로 초기화한다.
조합이 n! / (r! * (n-r)!)이므로,
그리고 n, n-1, …, n-r까지 소인수 분해해서 cp에 +로 저장한다(n!/(n-r)! 부분).
그리고 1, 2, …, r까지 소인수 분해 해서 cp에 -로 저장한다(r! 부분).

이제 cp에 있는 것들을 다 곱해주면 된다.
mult()로 배열로 나타낸 수의 곱셈을 처리할 수 있다(사람이 곱하는 방식).
</br>

블로그에 링크 걸기(minimal mistakes)

1
블로그 상단 내비게이션에 계산기를 누르면 바로 갈 수 있게 추가해 보자

// _data/navigation.yml

# main links
main:
 - title: "About"
   url: /about/
 - title: "Category"
   url: /categories/
 - title: "Tag"
   url: /tags/
 - title: "Archive"
   url: /year-archive/
 - title: "Calc"
   url: https://cyj893.github.io/calc.html

_data/navigation.yml 파일을 열어서, 타이틀을 “Calc”로 하고, url을 연결한다.
물론 cyj893.github.io 폴더 안에 calc.html을 넣어 놓은 상태이다.

결과

2
잘 된다 굿
</br>


다음에 시간 나면 행렬 계산기도 추가해 보자~~

</br>

댓글남기기