<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>우물 탈출기</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 11 Nov 2021 02:07:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>우물 탈출기</title>
            <url>https://images.velog.io/images/main_string/profile/cf92e2d0-7722-4ec1-a87f-d8e9cec4be07/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 우물 탈출기. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/main_string" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Level1 - 2016년]]></title>
            <link>https://velog.io/@main_string/Level1-2016%EB%85%84</link>
            <guid>https://velog.io/@main_string/Level1-2016%EB%85%84</guid>
            <pubDate>Thu, 11 Nov 2021 02:07:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/12901">문제출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(a, b) {
  var answer = &#39;&#39;;
  const month = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  const day = [&quot;FRI&quot;, &quot;SAT&quot;, &quot;SUN&quot;, &quot;MON&quot;, &quot;TUE&quot;, &quot;WED&quot;, &quot;THU&quot;]
  let idx = 0
  for (let i = 0; i &lt; a - 1; i++) idx += month[i];
  answer = day[(idx + b - 1) % 7]
  return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 두 개 뽑아서 더하기]]></title>
            <link>https://velog.io/@main_string/Level1-%EB%91%90-%EA%B0%9C-%EB%BD%91%EC%95%84%EC%84%9C-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@main_string/Level1-%EB%91%90-%EA%B0%9C-%EB%BD%91%EC%95%84%EC%84%9C-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 09 Nov 2021 07:48:26 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/68644">문제 출처</a></p>
</blockquote>
<h1 id="solution">Solution</h1>
<pre><code class="language-js">function solution(numbers) {
  var answer = [];
  for (let i = 0; i &lt; numbers.length - 1; i++)
    for (let j = i + 1; j &lt; numbers.length; j++)
      if (!answer.includes(numbers[i] + numbers[j]))
        answer.push(numbers[i] + numbers[j])
  return answer.sort((a, b) =&gt; a - b);
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 예산]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%98%88%EC%82%B0</link>
            <guid>https://velog.io/@main_string/Level1-%EC%98%88%EC%82%B0</guid>
            <pubDate>Mon, 08 Nov 2021 12:09:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/12982">문제출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(d, budget) {
  var answer = 0;
  let tmp = 0
  d.sort((a, b) =&gt; a - b)
  for (let num of d) {
    tmp += num
    answer++;
    if (tmp === budget) break
    else if (tmp &gt; budget) {
      tmp -= num
      answer--;
    }
  }
  return answer
}</code></pre>
<br>

<h2 id="cleanup">Cleanup</h2>
<pre><code class="language-js">function solution(d, budget) {
  var answer = 0;
  let tmp = 0
  d.sort((a, b) =&gt; a - b).forEach(num =&gt; {
    tmp += num
    if (tmp &lt;= budget) answer++;
  })
  return answer
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 3진법 뒤집기]]></title>
            <link>https://velog.io/@main_string/Level1-3%EC%A7%84%EB%B2%95-%EB%92%A4%EC%A7%91%EA%B8%B0</link>
            <guid>https://velog.io/@main_string/Level1-3%EC%A7%84%EB%B2%95-%EB%92%A4%EC%A7%91%EA%B8%B0</guid>
            <pubDate>Sat, 06 Nov 2021 06:03:14 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/68935">문제출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(n) {
  var answer = 0;
  let num3 = []
  while (n &gt; 2) {
    num3.push(n % 3)
    n = parseInt(n / 3)
  }
  num3.push(n)
  num3.reverse()
  answer = num3.reduce((acc, cur, idx) =&gt; acc + cur * Math.pow(3, idx))

  return answer;
}</code></pre>
<br>

<h2 id="cleanup">Cleanup</h2>
<pre><code class="language-js">const solution = (n) =&gt; {
    return parseInt([...n.toString(3)].reverse().join(&quot;&quot;), 3);
}</code></pre>
<ul>
<li><p>toString을 이용해 n을 3진법 문자열로 변경</p>
<blockquote>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/toString">toString 참고</a></p>
</blockquote>
</li>
<li><p>변경된 문자열을 전개 연산자를 이용해 각 문자를 분리해 배열로 저장</p>
</li>
<li><p>변경된 배열을 뒤집은 뒤 10진 parseInt로 10진법으로 변경</p>
<blockquote>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/parseInt">parseInt 참고</a></p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 약수의 개수와 덧셈]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88</link>
            <guid>https://velog.io/@main_string/Level1-%EC%95%BD%EC%88%98%EC%9D%98-%EA%B0%9C%EC%88%98%EC%99%80-%EB%8D%A7%EC%85%88</guid>
            <pubDate>Sat, 06 Nov 2021 05:38:56 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/77884">문제출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(left, right) {
  var answer = 0;
  for (let num = left; num &lt;= right; num++) {
    let tmp = []
    for (let i = 1; i &lt;= num; i++)
      if (num % i === 0) tmp.push(i)
    answer += tmp.length % 2 === 0 ? num : -num
  }
  return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 실패율]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%8B%A4%ED%8C%A8%EC%9C%A8</link>
            <guid>https://velog.io/@main_string/Level1-%EC%8B%A4%ED%8C%A8%EC%9C%A8</guid>
            <pubDate>Wed, 03 Nov 2021 00:02:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42889">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(N, stages) {
  let tmp = []
  let nonClearPlayer = Array.from({
    length: N
  }, () =&gt; 0)
  let stageCount = Array.from({
    length: N
  }, () =&gt; 0)

  stages.forEach(playerStage =&gt; {
    if (playerStage &lt;= N) nonClearPlayer[playerStage - 1]++
    for (let i = 1; i &lt;= playerStage; i++) {
      if (i &lt;= N) stageCount[i - 1]++
    }
  })

  for (let i = 0; i &lt; N; i++) {
    const dict = {}
    dict[&quot;num&quot;] = i + 1
    dict[&quot;rate&quot;] = nonClearPlayer[i] / stageCount[i]
    tmp.push(dict)
  }
  return tmp.sort((a, b) =&gt; b.rate - a.rate).map(el =&gt; el[&quot;num&quot;])
}</code></pre>
<ul>
<li><code>nonClearPlayer</code>에 각 스테이지 별로 클리어하지 못하고 머무르는 인원 수 저장</li>
<li><code>stageCount</code>에 각 스테이지 별로 지나쳐간 인원과 머물러 있는 인원 수의 합 저장</li>
<li><code>tmp</code>에 &quot;num&quot; : 스테이지 번호, &quot;rate&quot; : 실패율의 형태로 Object 객체 생성</li>
<li>실패율을 기준으로 정렬한 뒤 스테이지 번호만 배열로 반환</li>
</ul>
<h2 id="clean-up">Clean-up</h2>
<pre><code class="language-js">function solution(N, stages) {
    let result = [];
    for(let i=1; i&lt;=N; i++){
        let reach = stages.filter((x) =&gt; x &gt;= i).length;
        let curr = stages.filter((x) =&gt; x === i).length;
        result.push([i, curr/reach]);
    }
    result.sort((a,b) =&gt; b[1] - a[1]);
    return result.map((x) =&gt; x[0]);
}</code></pre>
<ul>
<li><code>reach</code>에 도달한 인원수 저장</li>
<li><code>curr</code>에 현재 머무르고 있는 인원수 저장</li>
<li>실패율을 계산하여 <code>result</code>에 push</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 포켓몬]]></title>
            <link>https://velog.io/@main_string/Level1-%ED%8F%AC%EC%BC%93%EB%AA%AC</link>
            <guid>https://velog.io/@main_string/Level1-%ED%8F%AC%EC%BC%93%EB%AA%AC</guid>
            <pubDate>Tue, 02 Nov 2021 05:18:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/1845">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(nums) {
  var answer = 0;
  let tmp = []
  nums.forEach(el =&gt; {
    if (!tmp.includes(el)) tmp.push(el)
  })
  return answer = nums.length / 2 &gt; tmp.length ? tmp.length : nums.length / 2;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 체육복]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%B2%B4%EC%9C%A1%EB%B3%B5</link>
            <guid>https://velog.io/@main_string/Level1-%EC%B2%B4%EC%9C%A1%EB%B3%B5</guid>
            <pubDate>Mon, 01 Nov 2021 09:56:56 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42862">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(n, lost, reserve) {
  let rent = [];
  const more = reserve.filter(el =&gt; !lost.includes(el)).sort((a, b) =&gt; a - b)
  const need = lost.filter(el =&gt; !reserve.includes(el)).sort((a, b) =&gt; a - b)
  need.forEach(el =&gt; {
    if (el - 1 &gt; 0 &amp;&amp; more.includes(el - 1) &amp;&amp; !rent.includes(el - 1)) {
      rent.push(el - 1)
    } else if (el + 1 &lt;= n &amp;&amp; more.includes(el + 1) &amp;&amp; !rent.includes(el + 1)) {
      rent.push(el + 1)
    }
  });
  return n - (need.length - rent.length);
}</code></pre>
<h2 id="clean-up">Clean-up</h2>
<blockquote>
<p>BYUNGI님의 코드</p>
</blockquote>
<pre><code class="language-js">function solution(n, lost, reserve) {      
    return n - lost.filter(a =&gt; {
        const b = reserve.find(r =&gt; Math.abs(r-a) &lt;= 1)
        if(!b) return true
        reserve = reserve.filter(r =&gt; r !== b)
    }).length
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 모의고사]]></title>
            <link>https://velog.io/@main_string/Level1-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC</link>
            <guid>https://velog.io/@main_string/Level1-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC</guid>
            <pubDate>Thu, 28 Oct 2021 13:18:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42840">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(answers) {
  var answer = []
  let result = []
  const patterns = [
    [1, 2, 3, 4, 5],
    [2, 1, 2, 3, 2, 4, 2, 5],
    [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
  ]
  patterns.forEach(pattern =&gt; {
    let idx = 0
    let count = 0
    answers.forEach(num =&gt; {
      if (num === pattern[idx]) {
        count++
      }
      idx++
      if (idx === pattern.length) {
        idx = 0
      }

    })
    answer.push(count)
  })
  max_idx = 0
  for (let i = 1; i &lt; 3; i++)
    if (answer[max_idx] &lt; answer[i]) max_idx = i;
  for (let i = 0; i &lt; 3; i++)
    if (answer[i] === answer[max_idx]) result.push(i + 1)

  return result;
}

}</code></pre>
<h2 id="clean-up">Clean-up</h2>
<pre><code class="language-js">function solution(answers) {
    var answer = [];
    const a1 = [1, 2, 3, 4, 5];
    const a2 = [2, 1, 2, 3, 2, 4, 2, 5]
    const a3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5];

    const a1c = answers.filter((a,i)=&gt; a === a1[i%a1.length]).length;
    const a2c = answers.filter((a,i)=&gt; a === a2[i%a2.length]).length;
    const a3c = answers.filter((a,i)=&gt; a === a3[i%a3.length]).length;
    const max = Math.max(a1c,a2c,a3c);

    if (a1c === max) {answer.push(1)};
    if (a2c === max) {answer.push(2)};
    if (a3c === max) {answer.push(3)};

    return answer;
}</code></pre>
<ul>
<li><code>filter</code>메서드를 이용해 조건에 맞는 요소만 모아 <code>answers</code> 배열을 생성.
  <code>filter</code>메서드의 인수로 배열의 요소와 인덱스를 추가했다. 인덱스는 옵션.</li>
<li>해당 배열의 개수가 정답 수에 해당.</li>
<li><code>i%a2.length</code>인덱스를 패턴의 길이로 나누면 인덱스 범위 초과 없이 반복할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS - DOM]]></title>
            <link>https://velog.io/@main_string/JS-DOM</link>
            <guid>https://velog.io/@main_string/JS-DOM</guid>
            <pubDate>Thu, 28 Oct 2021 05:36:41 GMT</pubDate>
            <description><![CDATA[<h2 id="dom이란">DOM이란?</h2>
<p>Document Objenct Model. 브라우저와 HTML 간의 인터페이스라고 볼 수 있다. 브라우저가 HTML을 해석하고 그 내용을 토대로 페이지를 랜더링하는데 DOM이 그 역할을 한다. DOM은 HTML문서를 <strong>객체화</strong>하여 브라우저가 해석할 수 있도록 한다. 이 객체를 javascript를 이용해서 조작할 수 있는 프로퍼티와 메서드의 집합인 DOM API를 제공한다.
<img src="https://images.velog.io/images/main_string/post/74dc6882-eb09-4736-adfa-8038ac092072/image.png" alt=""></p>
<ul>
<li>DOM은 HTML과 같은 것이 아니다. HTML에는 없었던 요소를 DOM을 조작해서 추가할 수 있고, 반대의 경우도 가능하다. </li>
<li><code>display:none</code>속성을 가진 요소를 DOM을 이용해서 선택, 수정이 가능하다. 이런 요소는 Render tree에 해당하는 뷰 포트에는 포함되지 않지만, DOM에는 포함된다. </li>
<li><code>::after</code>, <code>::before</code>와 같은 가상 요소는 DOM을 조작하여 선택하거나 수정할 수 없다.</li>
</ul>
<br>

<h2 id="virtual-dom">Virtual DOM</h2>
<p>리액트, 뷰와 같은 프레임워크에서 사용하는 DOM을 추상화한 모델을 이용해 DOM을 조작하는 방법이다. DOM을 직접 조작하여 변경 사항을 만들어 낼 경우, 변경 사항이 생길 때마다 Render tree를 만들어서 랜더링을 새로 한다.</p>
<p><img src="https://blog.kakaocdn.net/dn/bsK2db/btqCoR6Sefb/bWCCnmtGeZKkabCwwxBCn0/tfile.svg" alt=""></p>
<p>기존의 DOM의 동작을 보면 HTML과 CSS를 이용해서 각각 DOM/CSSOM tree를 만든다. 이 두 tree를 합쳐서 Render tree를 구성하는데 트리의 규모가 크면 랜더링하는데 오랜 시간이 걸리는 문제점이 발생한다. 이를 해결하고자 가상 DOM이 만들어졌다.</p>
<p>변경 사항을 먼저 가상 DOM에 리랜더링 한 뒤에 기존의  DOM과 비교하여 차이점만 DOM에 랜더링한다.(diffing) DOM의 랜더링 횟수를 줄여서 속도를 줄이는 것이 가상DOM의 사용 목적이라고 볼 수 있다.</p>
<br>

<h2 id="dom-vs-virtual-dom">DOM vs Virtual DOM</h2>
<p>중간에 가상DOM을 거친다는 점을 제외하면 DOM과 가상DOM의 동작방식은 매우 유사하다. DOM에서 10번의 랜더링이 이루어지만 마찬가지로 가상 DOM에서도 10번의 랜더링이 이루어진다. 가상DOM 또한 최적화가 잘 이루어지지 않았다면 오히려 속도가 느릴 수도 있다. DOM을 직접 조작하는 것과 가상DOM을 이용하는 것 중에 어떤 것이 더 효율적인지 알고 사용할 필요가 있고, 가상 DOM을 이용한다고 해도 어떻게 사용해야 좋을지 파악하는 것이 더욱 중요하다.</p>
<p><br><br><br><br></p>
<h4 id="참조">참조</h4>
<blockquote>
<ul>
<li><a href="https://poiemaweb.com/js-dom">https://poiemaweb.com/js-dom</a></li>
</ul>
</blockquote>
<ul>
<li><a href="https://wit.nts-corp.com/2019/02/14/5522">https://wit.nts-corp.com/2019/02/14/5522</a></li>
<li><a href="https://d2.naver.com/helloworld/59361">https://d2.naver.com/helloworld/59361</a></li>
<li><a href="https://moonsbeen.tistory.com/255">https://moonsbeen.tistory.com/255</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - K번째 수]]></title>
            <link>https://velog.io/@main_string/Level1-K%EB%B2%88%EC%A7%B8-%EC%88%98</link>
            <guid>https://velog.io/@main_string/Level1-K%EB%B2%88%EC%A7%B8-%EC%88%98</guid>
            <pubDate>Wed, 27 Oct 2021 12:03:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42748">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(array, commands) {
  var answer = [];
  commands.forEach(element =&gt; {
    answer.push(
      array.slice(element[0] - 1, element[1])
      .sort((a, b) =&gt; a - b)[element[2] - 1])
  });
  return answer;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 완주하지 못한 선수]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</link>
            <guid>https://velog.io/@main_string/Level1-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</guid>
            <pubDate>Sun, 24 Oct 2021 00:41:35 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42576">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<h4 id="효율성-검사-실패">효율성 검사 실패</h4>
<pre><code class="language-js">function solution(participant, completion) {
  completion.forEach(el =&gt; {
    let idx = participant.indexOf(el)
    participant.splice(idx, 1)
  });
  return participant[0]
}</code></pre>
<p><code>completion</code>에 담긴 모든 요소에 대해서 <code>participant</code>에 있을 경우 해당 인덱스를 찾아서 배열에서 제거해주는 방식으로 풀었을 때, 효율성 검사를 통과하지 못한다.</p>
<blockquote>
<p><img src="https://images.velog.io/images/main_string/post/51facce0-6839-4241-bbc3-c765bb428ff2/image.png" alt=""></p>
</blockquote>
<p><code>indexOf</code>는 호출될 때마다 0번 인덱스부터 완전 탐색을 통해서 요소를 탐색하기 때문에 <code>completion</code>과 <code>participant</code>의 요소가 많으면 시간이 오래 걸릴 수 밖에 없다.</p>
<br>

<h4 id="효율성-검사-성공">효율성 검사 성공</h4>
<pre><code class="language-js">function solution(participant, completion) {
  var answer = &#39;&#39;
  let part = Object()
  participant.forEach(el =&gt; {
    if (part[el] === undefined) {
      part[el] = 1
    } else {
      part[el]++
    }
  });
  completion.forEach(el =&gt; {
    part[el] -= 1
  });
  const part_key = Object.keys(part)
  const part_value = Object.values(part)
  answer = part_key[part_value.indexOf(1)]
  return answer
}</code></pre>
<ol>
<li><code>participant</code>의 요소를 key로 하여 해당 key값의 개수만큼 value를 가지는 <code>part</code> Object 생성</li>
<li><code>completion</code>의 요소를 key로 하여 해당 key값의 개수만큼 <code>part</code>의 value값을 하나씩 차감</li>
<li><code>part</code>의 key와 value를 가지는 배열을 각각 생성</li>
<li><code>part_value</code>에서 값 1에 해당하는 요소의 인덱스와 같은 인덱스의 <code>part_key</code>값 반환</li>
</ol>
<p>효율성 검사는 key값으로 value값에 바로 접근할 수 있는 Object를 이용해서 해결했다. Object를 이용하면 <code>participant</code>과 <code>completion</code>에 동일한 요소가 있을 수 있다는 문제의 제약사항을 해결할 수 있다. key : value 형태로 접근하면 시간 복잡도가 O(1)이기 때문에 쉽게 찾아서 값을 변경할 수 있다.</p>
<p><code>participant</code>가 <strong>N</strong>개의 요소를, <code>completion</code>이 <strong>M</strong>개의 요소를 가진다고 했을 때, 효율성 검사를 통과하지 못한 코드는 <strong>(N*M)</strong> 번의 탐색이 필요하고, 효율성 검사를 통과한 코드는 최대 <strong>(2N+M)</strong>번을 탐색한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 소수 만들기]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%86%8C%EC%88%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@main_string/Level1-%EC%86%8C%EC%88%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Wed, 20 Oct 2021 12:30:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/12977">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(nums) {
  var answer = 0;
  let set = []

  for (let i = 0; i &lt; nums.length; i++) {
    for (let j = i + 1; j &lt; nums.length; j++) {
      for (let k = j + 1; k &lt; nums.length; k++) {
        set.push(nums[i] + nums[j] + nums[k])
      }
    }
  }

  set.forEach(el =&gt; {
    let idx = 2
    for (idx = 2; idx &lt; el; idx++) {
      if (el % idx === 0) {
        break
      }
    }
    if (idx === el) answer++;
  })
  return answer;
}</code></pre>
<p>배열에서 숫자 세 개를 포함하는  조합의 개수를 <code>set</code>에 저장한 뒤 <code>forEach</code>메서드를 활용해서 서로소 일 때만 <code>answer</code>값을 추가해 준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[순열과 조합]]></title>
            <link>https://velog.io/@main_string/%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9</link>
            <guid>https://velog.io/@main_string/%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9</guid>
            <pubDate>Wed, 20 Oct 2021 11:53:48 GMT</pubDate>
            <description><![CDATA[<h2 id="1-순열">1. 순열</h2>
<h3 id="11-반복문-이용">1.1 반복문 이용</h3>
<pre><code class="language-python">isUse = [False] * 4
set = []

for i in range(4):
    if isUse[i]:
        continue
    isUse[i] = True
    for j in range(4):
        if isUse[j]:
            continue
        isUse[j] = True
        for k in range(4):
            if isUse[k]:
                continue
            isUse[k] = True

            tmp = arr[i], arr[j], arr[k]
            set.append(tmp)

            isUse[k] = False
        isUse[j] = False
    isUse[i] = False</code></pre>
<blockquote>
<p>입력 : [1, 2, 3, 4]</p>
</blockquote>
<blockquote>
<p>출력
(1, 2, 3) (1, 2, 4) (1, 3, 2)
(1, 3, 4) (1, 4, 2) (1, 4, 3)
(2, 1, 3) (2, 1, 4) (2, 3, 1)
(2, 3, 4) (2, 4, 1) (2, 4, 3)
(3, 1, 2) (3, 1, 4) (3, 2, 1)
(3, 2, 4) (3, 4, 1) (3, 4, 2)
(4, 1, 2) (4, 1, 3) (4, 2, 1)
(4, 2, 3) (4, 3, 1) (4, 3, 2)</p>
</blockquote>
<p>반복문을 이용해서 순열을 쉽게 구할 수 있지만, 위으 예처럼 4개 중에 3개가 아닌 훨씬 더 큰 경우의 수를 구하려면 코드가 굉장이 길어진다. 재귀 함수를 이용하면 순열의 개수에 상관없이 일정한 코드를 사용할 수 있다.</p>
<h3 id="12-재귀-이용">1.2 재귀 이용</h3>
<pre><code class="language-python">import copy
set = []
tmp = []  # 수를 저장할 배열

def Permutation(cnt):
    if len(tmp) == cnt:
        made = copy.deepcopy(tmp)
        set.append(made)
        return

    for i in range(4):
        if arr[i] in tmp:
            continue
        tmp.append(arr[i])
        Permutation(cnt)
        tmp.pop()
Permutation(3)</code></pre>
<blockquote>
<p>입력 : [1, 2, 3, 4]</p>
</blockquote>
<blockquote>
<p>출력
(1, 2, 3) (1, 2, 4) (1, 3, 2)
(1, 3, 4) (1, 4, 2) (1, 4, 3)
(2, 1, 3) (2, 1, 4) (2, 3, 1)
(2, 3, 4) (2, 4, 1) (2, 4, 3)
(3, 1, 2) (3, 1, 4) (3, 2, 1)
(3, 2, 4) (3, 4, 1) (3, 4, 2)
(4, 1, 2) (4, 1, 3) (4, 2, 1)
(4, 2, 3) (4, 3, 1) (4, 3, 2)</p>
</blockquote>
<h2 id="2-조합">2. 조합</h2>
<h3 id="21-반복문-이용">2.1 반복문 이용</h3>
<pre><code class="language-python">set = []

for i in range(4):
    for j in range(i+1, 4):
        for k in range(j+1, 4):
            tmp = arr[i], arr[j], arr[k]
            set.append(tmp)
</code></pre>
<blockquote>
<p>입력 : [1, 2, 3, 4]</p>
</blockquote>
<blockquote>
<p>출력 : (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)</p>
</blockquote>
<p>순열과 다르게 조합은 순서에 상관이 없다. 직전 반복문에서 사용한 숫자를 다시 사용하지 않기 위해서 바로 다음 요소부터 반복문을 수행하도록 순서를 강제해야 한다.</p>
<h3 id="22-재귀-이용">2.2 재귀 이용</h3>
<pre><code class="language-python">import copy
tmp = []
set = []

def Combination(idx, cnt):
    if len(tmp) == cnt:
        made = copy.deepcopy(tmp)
        set.append(made)
        return

    for i in range(idx, 4):
        tmp.append(arr[i])
        Combination(i+1, cnt)
        tmp.pop()

Combination(0, 3)</code></pre>
<blockquote>
<p>입력 : [1, 2, 3, 4]</p>
</blockquote>
<blockquote>
<p>출력 : (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 크레인 인형뽑기]]></title>
            <link>https://velog.io/@main_string/%E3%85%81%E3%84%B4%E3%85%87%E3%84%B9</link>
            <guid>https://velog.io/@main_string/%E3%85%81%E3%84%B4%E3%85%87%E3%84%B9</guid>
            <pubDate>Mon, 18 Oct 2021 12:46:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/64061?language=javascript">문제 출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(board, moves) {
  var answer = 0;
  let basket = []
  const N = board.length
  moves.forEach(loc =&gt; {
    for (let i = 0; i &lt; N; i++) {
      if (board[i][loc - 1] !== 0) {
        const tmp = board[i][loc - 1]
        board[i][loc - 1] = 0
        if (basket[basket.length - 1] === tmp) {
          basket.pop()
          answer += 2
        } else {
          basket.push(tmp)
        }
        break
      }
    }
  });
  return answer;
}
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS - Promise]]></title>
            <link>https://velog.io/@main_string/JS-Promise</link>
            <guid>https://velog.io/@main_string/JS-Promise</guid>
            <pubDate>Thu, 30 Sep 2021 12:24:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>동기식 : 응답을 받아야만 다음 동작을 이어가는 방식
비동기식 : 응답 여부와 관계 없이 다음 동작을 이어가는 방식</p>
</blockquote>
<p>자바스크립트는 기본적으로 동기식으로 작동한다. 하나의 Call Stack만 사용하기 때문에, JS만으로는 비동기식 동작을 구현할 수 없다. 따라서 브라우저에서 지원하는 Web API를 이용해서 비동기식 동작을 구현하게 된다. <code>setTimeout</code>이나 axois를 이용해 요청을 보내고 응답을 기다려야 할 경우, 이 함수는 Web API로 넘어가게 되고 다른 함수가 Call Stack으로 들어와 실행되는데, 이를 오히려 방지해야 하는 경우가 있다.</p>
<blockquote>
<p><a href="https://new93helloworld.tistory.com/361">자바스크립트의 동작 원리 참고</a></p>
</blockquote>
<pre><code class="language-js">function a() {
  setTimeout(() =&gt; {
    console.log(&#39;A&#39;)
  }, 1000);
}

function b() {
  console.log(&#39;B&#39;)
}

function test() {
  a()
  b()
}
test()
// B
// A</code></pre>
<h2 id="1-callback">1. callback</h2>
<p>함수의 실행의 순서를 보장하고 싶을 때 사용할 수 있는 방법 중에 하나로 callback이 있다.</p>
<pre><code class="language-js">function a(callback) {
  setTimeout(() =&gt; {
    console.log(&#39;A&#39;)
    callback()
  }, 1000);
}

function b(callback) {
  console.log(&#39;B&#39;)
  callback()
}

function c(callback) {
  setTimeout(() =&gt; {
    console.log(&#39;C&#39;)
    callback()
  }, 1000);
}

function d(callback) {
  console.log(&#39;D&#39;)
  callback()
}

function test() {
  a(() =&gt; {
    b(() =&gt; {
      c(() =&gt; {
        d(() =&gt; {
        })
      })
    })
  })
}
test()
// A
// B
// C
// D</code></pre>
<p>callback을 사용하지 않고 실행하면 실행하는데 딜레이가 있는 <code>a</code>함수보다 <code>b</code>함수가 먼저 실행되겠지만, 비동기 실행을 했기 때문에 순서대로 실행이 되었다. 하지만 callback을 여러 개 중첩해서 사용할 경우 코드가 복잡해지고 관리가 어려워진다. 위 코드처럼 순차적으로 되어 있지 않고 조금만 복잡해도 알아보기 힘들 것이다.</p>
<br>

<h2 id="2-promise">2. Promise</h2>
<blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise 참고</a></p>
</blockquote>
<p>callback 함수를 사용해 순서를 보장해 주는 것처럼 함수 실행의 순서를 보장할 수 있는 방법으로 Promise 객체를 사용하는 방법이 있다.</p>
<h3 id="21-비동기-실행">2.1 비동기 실행</h3>
<pre><code class="language-js">function a() {
  return new Promise((resolve) =&gt; {
    setTimeout(() =&gt; {
      console.log(&#39;A&#39;)
      resolve()
    }, 1000)
  })
}

function b() {
  return new Promise((resolve) =&gt; {
    console.log(&#39;B&#39;)
    resolve()
  })
}

function c() {
  return new Promise((resolve) =&gt; {
    setTimeout(() =&gt; {
      console.log(&#39;C&#39;)
      resolve()
    }, 1000)
  })
}

function d() {
  return new Promise((resolve) =&gt; {
    console.log(&#39;D&#39;)
    resolve()
  })
}

function test() {
  a().then(() =&gt; {
    b().then(() =&gt; {
      c().then(() =&gt; {
        d().then(() =&gt; {
          console.log(&#39;Done&#39;)
        })
      })
    })
  })
}
test()</code></pre>
<p><code>a</code>, <code>b</code>, <code>c</code>, <code>d</code> 함수는 각각 Promise 객체를 반환한다. Promise 객체의 매개변수로 하나의 함수가 들어가고, 해당 함수의 매개변수로 <code>resolve</code>가 할당된다. 이 <code>resolve</code>는 callback과 대응한다고 볼 수 있다.</p>
<p><code>a</code> 함수 내부에서 <code>resolve</code> 매개변수가 실행될 때까지 앞의 코드가 실행되고, <code>resolve</code>가 실행되면 Promise 객체를 반환한 뒤 <code>then</code>메서드를 실행한다.</p>
<p>하지만, 위 코드를 보면 callback을 사용했을 때와 유사하게 복잡하다. 이를 return을 이용해서 수정하면 아래처럼 만들 수 있다.</p>
<pre><code class="language-js">function test() {
  a().then(() =&gt; {
    return b()
  }).then(() =&gt; {
    return c()
  }).then(() =&gt; {
    return d()
  }).then(() =&gt; {
    console.log(&#39;Done&#39;)
  })
}</code></pre>
<p><code>a</code>함수를 실행하면 Promise 객체 하나를 반환한다. <code>then</code> 메서드를 실행하여 <code>a</code>함수의 실행이 끝난 뒤 <code>b</code>함수를 실행하여 반환한다. 즉, <code>b</code>함수의 Promise 객체가 반환된다. 마지막에 반환값 없이 함수를 실행하고 끝난다.</p>
<h3 id="22-예외처리">2.2 예외처리</h3>
<p>Promise 객체는 <code>catch</code>와 <code>finally</code>메서드를 활용해서 예외처리가 가능하다.</p>
<pre><code class="language-js">function a(number) {
  return new Promise((resolve, reject) =&gt; {
    if (number &gt; 4) {
      reject()
      return
    }
    setTimeout(() =&gt; {
      console.log(&#39;A&#39;)
      resolve()
    }, 1000)
  })
}

function test() {
  a([인수])
    .then(() =&gt; {
      console.log(&#39;resolve&#39;)
    })
    .catch(() =&gt; {
      console.log(&#39;reject&#39;)
    })
    .finally(() =&gt; {
      console.log(&#39;done&#39;)
    })
}</code></pre>
<p><code>a</code>함수부터 살펴 보면 매개변수로 <code>reject</code>가 추가되었다. <code>reject</code>는 <code>resolve</code>가 실행될 수 없는 상황에서 실행되는 매개변수로 <code>catch</code>메서드를 실행시킨다. 위 코드를 예로 살펴보면, <code>a</code>함수의 <code>number</code>매개변수로 4이하의 값이 할당되면 <code>resolve</code>매개변수가 실행되어 결과는 다음 과 같다.</p>
<blockquote>
<p>A<br>resolve<br>done</p>
</blockquote>
<p>반대로 <code>a</code>함수의 <code>number</code>매개변수로 4보다 큰 값이 할당되면 <code>reject</code>매개변수가 실행되어 결과는 다음 과 같다.</p>
<blockquote>
<p>reject<br>done</p>
</blockquote>
<p>결과를 보면 <code>finally</code>라는 메서드는 <code>resolve</code>와 <code>reject</code>가 실행됐을 때 모두 동작하는 것을 알 수 있다. <code>finally</code>는 항상 실행되는 메서드이다.</p>
<br>

<h2 id="3-async-await">3. async, await</h2>
<p>최신의 자바스크립트는 <code>async</code>함수와 <code>await</code>를 제공한다. 이 또한 함수 실행 순서를 보장해주는 역할을 하는데 callback이나 Promise 객체의 메서드를 사용할 때 보다 훨씬 직관적인 코드를 작성할 수 있다.</p>
<h3 id="31-비동기-실행">3.1 비동기 실행</h3>
<pre><code class="language-js">function a() {
  return new Promise((resolve) =&gt; {
    setTimeout(() =&gt; {
      console.log(&#39;A&#39;)
      resolve()
    }, 1000)
  })
}

function b() {
  return new Promise((resolve) =&gt; {
    console.log(&#39;B&#39;)
    resolve()
  })
}

function c() {
  return new Promise((resolve) =&gt; {
    setTimeout(() =&gt; {
      console.log(&#39;C&#39;)
      resolve()
    }, 1000)
  })
}

function d() {
  return new Promise((resolve) =&gt; {
    console.log(&#39;D&#39;)
    resolve()
  })
}

async function test() {
  await a()
  b()
  await c()
  d()

}</code></pre>
<p>결과는 Promise의 <code>then</code>메서드를 사용했을 때와 똑같다. 하지만 <code>test</code>함수의 내부가 훨씬 직관적이고 깔끔하다. async는 비동기 실행을 할 함수를 나타내고 await는 해당 함수가 실행이 완료될 때까지 대기한 뒤에, 다음 코드를 실행한다는 의미이다.</p>
<br>

<h3 id="32-예외처리">3.2 예외처리</h3>
<pre><code class="language-js">function a(number) {
  // resolve가 실행될 수 없을 때 reject
  return new Promise((resolve, reject) =&gt; {
    if (number &gt; 4) {
      reject()
      return
    }
    setTimeout(() =&gt; {
      console.log(&#39;A&#39;)
      resolve()
    }, 1000)
  })
}

async function test() {
  try {
    await a(11)
    console.log(&#39;resolve&#39;)
  } catch (err) {
    console.log(&#39;reject&#39;)
  } finally {
    console.log(&#39;done&#39;)
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 음양 더하기]]></title>
            <link>https://velog.io/@main_string/Level1-%EC%9D%8C%EC%96%91-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@main_string/Level1-%EC%9D%8C%EC%96%91-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 22 Sep 2021 01:31:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/76501?language=javascript">문제 출처</a></p>
</blockquote>
<h1 id="solution">Solution</h1>
<pre><code class="language-js">function solution(absolutes, signs) {
  var answer = 123456789;
  answer = absolutes.reduce((acc, cur_v, cur_i) =&gt; {
    if (signs[cur_i]) {
      return acc + cur_v
    } else {
      return acc - cur_v
    }
  }, 0)
  return answer;
}</code></pre>
<p><img src="https://images.velog.io/images/main_string/post/c1590553-4665-4e3e-ad9a-041672952163/image.png" alt="">
<code>reduce</code>메서드는 4개의 인자를 받는다.</p>
<blockquote>
<ul>
<li>accumulator : 콜백 함수의 결과를 누적</li>
</ul>
</blockquote>
<ul>
<li>currentValue : 처리할 현재 요소</li>
<li>currentIndex : 처리할 현재 요소의 인덱스</li>
<li>array : 메서드를 호출한 배열</li>
</ul>
<p>메서드 종료시 accumulator 값을 반환한다.</p>
<p>initialValue를 지정하지 않으면 0번 인덱스 값이 accumulator에 할당되고 1번 인덱스부터 콜백함수가 실행된다. initialValue를 지정하면 해당 값이 accumulator에 할당되고 0번 인덱스부터 콜백함수가 실행된다.</p>
<p><code>absolute = [4, 7, 12]</code><br><code>signs = [true, false, true]</code><br>위의 조건으로 코드가 실행되면 <code>reduce</code>메서드의 동작은 다음과 같다.</p>
<table>
<thead>
<tr>
<th>callback</th>
<th>accumulator</th>
<th>currentValue</th>
<th>currentIndex</th>
<th>반환 값</th>
</tr>
</thead>
<tbody><tr>
<td>1번째 호출</td>
<td><center>0</center></td>
<td><center>4</center></td>
<td><center>0</center></td>
<td><center>4</center></td>
</tr>
<tr>
<td>2번째 호출</td>
<td><center>4</center></td>
<td><center>7</center></td>
<td><center>1</center></td>
<td><center>-3</center></td>
</tr>
<tr>
<td>3번째 호출</td>
<td><center>-3</center></td>
<td><center>12</center></td>
<td><center>2</center></td>
<td><center>9</center></td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 없는 숫자 더하기]]></title>
            <link>https://velog.io/@main_string/Level-1-%EC%97%86%EB%8A%94-%EC%88%AB%EC%9E%90-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@main_string/Level-1-%EC%97%86%EB%8A%94-%EC%88%AB%EC%9E%90-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 21 Sep 2021 00:55:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/86051?language=javascript">문제출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(numbers) {
  var answer = 45;
  const tmp = new RegExp(/[0-9]/)
  numbers.forEach(number =&gt; {
    if (tmp.test(String(number))) {
      console.log(number)
      answer -= number
    }
  })
  return answer;
}</code></pre>
<p>0~9까지 존재하는 숫자를 빼면 없는 숫자를 모두 더한 것과 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Level1 - 키패드 누르기]]></title>
            <link>https://velog.io/@main_string/Level-1-%ED%82%A4%ED%8C%A8%EB%93%9C-%EB%88%84%EB%A5%B4%EA%B8%B0</link>
            <guid>https://velog.io/@main_string/Level-1-%ED%82%A4%ED%8C%A8%EB%93%9C-%EB%88%84%EB%A5%B4%EA%B8%B0</guid>
            <pubDate>Sat, 18 Sep 2021 06:53:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/67256?language=javascript">문제출처</a></p>
</blockquote>
<h2 id="solution">Solution</h2>
<pre><code class="language-js">function solution(numbers, hand) {
  var answer = &#39;&#39;;
  let left = [3, 0];
  let right = [3, 2];
  const btns = {
    1: &#39;L&#39;,
    4: &#39;L&#39;,
    7: &#39;L&#39;,
    3: &#39;R&#39;,
    6: &#39;R&#39;,
    9: &#39;R&#39;,
  }
  const btns_keys = Object.keys(btns)
  for (let number of numbers) {
    // 행동이 정해진 버튼 입력
    if (btns_keys.includes(String(number))) {
      let tmp = btns[number]
      answer += tmp
      if (tmp === &#39;L&#39;) {
        left = [parseInt((number - 1) / 3), 0]
      } else {
        right = [parseInt((number - 1) / 3), 2]
      }
    }
    // 행동이 정해지지 않은 버튼 입력
    else {
      let btn = null
      // 가운데 열 버튼 위치
      if (number === 0) {
        btn = [3, 1]
      } else {
        btn = [parseInt((number - 1) / 3), 1]
      }
      // 이동량 계산
      const left_cnt = [Math.abs(btn[0] - left[0]), Math.abs(btn[1] - left[1])].reduce((acc, cur) =&gt; acc + cur, 0)
      const right_cnt = [Math.abs(btn[0] - right[0]), Math.abs(btn[1] - right[1])].reduce((acc, cur) =&gt; acc + cur, 0)
      console.log(btn)
      console.log(left_cnt, left, right_cnt, right)
      // 위치 이동
      if (left_cnt &lt; right_cnt) {
        answer += &#39;L&#39;
        left = btn
      } else if (left_cnt &gt; right_cnt) {
        answer += &#39;R&#39;
        right = btn
      } else {
        if (hand === &#39;left&#39;) {
          answer += &#39;L&#39;
          left = btn
        } else {
          answer += &#39;R&#39;
          right = btn
        }
      }
    }
  }

  return answer;
}</code></pre>
<blockquote>
<p>[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[&#39;*&#39;, 0, &#39;#&#39;],
]</p>
</blockquote>
<p>위와 같은 이차원 배열이 있다는 가정하에 해결했다.
1, 4, 7, 3, 6, 9는 정해진 규칙이 있으므로 객체에 key:value 형태로 저장해서 해당 규칙을 지킬수 있게 했다.</p>
<p>버튼의 위치에 해당하는 행과 열, <code>left</code> 혹은 <code>right</code>에 해당하는 행과 열의 각각 차이를 더하면 이동량이 된다. 이동량을 기준으로 <code>left</code>에 변화를 줄지 <code>right</code>에 변화를 줄지 결정한다.</p>
<p>행을 결정하는 방식은 <code>parseInt((number - 1) / 3)</code>이고 열을 결정하는 방식은 숫자별로 고정되어 있다.</p>
<ol>
<li>먼저 객체 메서드인 <code>keys()</code> 를 이용해서 key 값을 저장한 배열(<code>btns_keys</code>)을 만들었다. 이 메서드는 <strong>배열 안에 요소를 문자열 형태로 저장한다.</strong></li>
<li><code>number</code>가 <code>btns_keys</code>에 포함될 경우 <code>btns[number]</code>값을 <code>answer</code>에 추가해준다.</li>
<li><code>number</code>가 <code>btns_keys</code>에 포함되지 않을 경우, <code>btn</code>의 위치를 0 혹은 2,5,8의 경우로 나눠 결정한다.</li>
<li><code>left</code>, <code>right</code>와 <code>btn</code>의 행의 차이, 열의 차리를 더하여 각각의 이동량을 계산한다.</li>
<li>이동량을 기준으로 규칙에 맞는 문자를 answer에 추가한다.</li>
</ol>
<p>이동량 계산을 할 때 <code>reduce</code>메서드를 사용했다. <code>reduce</code>는 배열의 각 요소끼리 콜백 함수를 호출하여 하나의 값을 반환하는 메서드이다.</p>
<blockquote>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce">reduce 참고</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS - 클로저]]></title>
            <link>https://velog.io/@main_string/JS-%ED%81%B4%EB%A1%9C%EC%A0%80</link>
            <guid>https://velog.io/@main_string/JS-%ED%81%B4%EB%A1%9C%EC%A0%80</guid>
            <pubDate>Sat, 18 Sep 2021 05:02:22 GMT</pubDate>
            <description><![CDATA[<h2 id="1-클로저의-개요">1. 클로저의 개요</h2>
<p>JS는 상위 스코프를 함수의 선언되는 위치에 따라 결정한다. 이를 렉시컬 스코핑이라고 하며, 해당 스포크를 렉시컬 환경이라고 한다. 즉, 특정 함수가 선언되었을 때, 해당 함수와 함수가 참조할 수 있는 상위 스포크를 렉시컬 환경이라고 한다. 이러한 특징을 이용한 것이 클로저이다.</p>
<pre><code class="language-js">function outerFunc() {
  var x = 10;
  var innerFunc = function () { 
    console.log(x); 
  };
  innerFunc();
}

outerFunc(); // 10</code></pre>
<p><code>innerFunc</code>를 선언했을 때, 해당 함수의 상위 스코프는 <code>outerFunc</code>와 전역이다. 따라서 <code>innerFunc</code>가 실행됐을 때 상위 스코프의 변수인 <code>x</code>를 참조할 수 있다.
<br></p>
<pre><code class="language-js">function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  return innerFunc;
}
var inner = outerFunc();
inner(); // 10</code></pre>
<p>위 코드를 보면 <code>outerFunc</code>함수를 <code>inner</code>에 할당했다. <code>outerFunc</code>가 <code>innerFunc</code>를 반환하고 유효 범위가 끝났기 때문에(실행되고 실행 컨텍스트 스택에서 제거 됐기 때문에)  <code>inner</code>를 실행하면 오류가 날 것 같지만 그렇지 않고 잘 실행이 된다.</p>
<p>이렇게 특정 내부함수가 자신의 상위 스코프 밖에서(상위 스코프가 종료된 이후) 실행되어도, 해당 내부함수가 선언된 시점의 렉시컬 환경에 해당하는 변수와 함수를 사용할 수 있는 것을 클로저라고 한다.</p>
<blockquote>
<p>정리하자면 클로저란, 자신이 선언된 시점의 렉시컬 환경에 해당하는 것을 기억하여 밖에서 호출되더라도 해당 렉시컬 환경의 변수, 함수를 사용할 수 있게 만든 함수이다.</p>
</blockquote>
<blockquote>
<p><a href="https://poiemaweb.com/js-closure">클로저 활용</a></p>
</blockquote>
<p><br><br><br><br></p>
<h5 id="참조">참조</h5>
<blockquote>
<ul>
<li><a href="https://poiemaweb.com/js-closure">https://poiemaweb.com/js-closure</a></li>
</ul>
</blockquote>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures">https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>