<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>codingBear's Study Room</title>
        <link>https://velog.io/</link>
        <description>front-end 분야를 중점으로 공부 중!🐣</description>
        <lastBuildDate>Fri, 01 Apr 2022 06:38:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>codingBear's Study Room</title>
            <url>https://velog.velcdn.com/images/mame-coder/profile/3c3f6ddb-1217-462c-99d8-d113af436d00/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. codingBear's Study Room. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/mame-coder" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[블로그 이전했습니다]]></title>
            <link>https://velog.io/@mame-coder/%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%9D%B4%EC%A0%84%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@mame-coder/%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%9D%B4%EC%A0%84%ED%96%88%EC%8A%B5%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Fri, 01 Apr 2022 06:38:37 GMT</pubDate>
            <description><![CDATA[<p>아래 주소로 이전했습니다.</p>
<p><a href="https://gdk01.tistory.com">https://gdk01.tistory.com</a></p>
<p><a href="https://gdk01.tistory.com/">티스토리 블로그</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 더 쉽게 하기! with Sass]]></title>
            <link>https://velog.io/@mame-coder/CSS-%EB%8D%94-%EC%89%BD%EA%B2%8C-%ED%95%98%EA%B8%B0-with-Sass</link>
            <guid>https://velog.io/@mame-coder/CSS-%EB%8D%94-%EC%89%BD%EA%B2%8C-%ED%95%98%EA%B8%B0-with-Sass</guid>
            <pubDate>Fri, 11 Mar 2022 05:19:36 GMT</pubDate>
            <description><![CDATA[<p>이번 글은 아래 강의를 토대로 작성하였습니다.
<a href="https://youtu.be/zFZrkCIc2Oc">CS50&#39;s Web Programming lecture 0. HTML &amp; CSS</a></p>
<hr>
<h2 id="들어가며">들어가며</h2>
<p><code>CSS</code>에서 같은 값을 반복해서 입력해야 할 때 불편함을 겪는다. 물론 <code>:root{}</code>를 활용하여 자주 쓰이는 값을 저장해서 호출하는 식으로 처리할 수도 있으나 <code>:root</code>에 저장한 값을 일일이 불러와야 한다는 점에선 불편한 것은 매한가지이다.
<code>Sass</code>를 활용하여 <code>CSS</code>를 작성하면 이런 번거로움을 덜 수 있다.
아래 내용을 보며 <code>Sass</code>에 대한 기본적인 지식을 익혀보자.</p>
<hr>
<h2 id="실전-활용법">실전 활용법</h2>
<hr>
<h3 id="설치하기windows-10-기준">설치하기(Windows 10 기준)</h3>
<pre><code>npm install sass</code></pre><hr>
<h3 id="complile-scss-to-css">complile scss to css</h3>
<p><code>Sass</code>의 확장자는 <code>scss</code>이다. <code>scss</code> 자체로는 웹 브라우저에 읽힐 수 없기 때문에 <code>css</code> 파일로 변환해서 사용해야 한다.
compile을 하려면 console 창에 아래와 같이 입력한다.</p>
<pre><code>sass {filename}.scss:{filename}.css</code></pre><p>위의 문장을 입력하면 <code>scss</code>에서 compile된 <code>css</code>가 생성된다. 새로 생성된 <code>css</code> 파일을 <code>html</code> 파일에 input하여 사용하면 된다.
허나 <code>scss</code> 파일에서 수정사항이 생기면 매번 compile을 해줘야 하는데 다음과 같이 <code>--watch</code>를 추가하면 <code>scss</code> 파일을 저장할 때마다 자동으로 수정사항이 <code>css</code> 파일에 반영되어 compile을 해야 하는 수고를 덜 수 있다.</p>
<pre><code>sass --watch {filename}.scss:{filename}.css</code></pre><hr>
<h3 id="1-변수-활용하여-css-유지보수-쉽게-하기">1. 변수 활용하여 CSS 유지보수 쉽게 하기</h3>
<p><img src="https://images.velog.io/images/mame-coder/post/c625166a-e85b-4fb7-9a2b-3a344d71ee5c/image.png" alt=""></p>
<pre><code class="language-html">&lt;body&gt;
    &lt;ul&gt;
      &lt;li&gt;unordered item&lt;/li&gt;
      &lt;li&gt;unordered item&lt;/li&gt;
      &lt;li&gt;unordered item&lt;/li&gt;
    &lt;/ul&gt;

    &lt;ol&gt;
      &lt;li&gt;ordered item&lt;/li&gt;
      &lt;li&gt;ordered item&lt;/li&gt;
      &lt;li&gt;ordered item&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/body&gt;</code></pre>
<p>위와 같은 <code>html</code>코드를 작성했을 때 <code>ol</code>과 <code>ul</code>에 각각 <span style="color: green">초록색</span>을 부여한다고 치자. <code>CSS</code>로 색상을 입힌다면 아래와 같이 작성해야 한다.</p>
<pre><code class="language-css">ul {
  font-size: 14px;
  color: green;
}

ol {
  font-size: 18px;
  color: green;
}</code></pre>
<p>물론 위와 같이 작성해도 전혀 문제될 것은 없다. 허나 코드 길이가 길어져 100개의 요소에 <span style="color: green">초록색</span>을 부여해야 한다면? 복붙신공을 한다 쳐도 100번은 붙여 넣어야 한다. 더 큰 문제는 값을 수정하기가 까다롭다는 점이다. 위의 예제 코드에서 <code>ul</code>과 <code>ol</code>에 부여된 <code>color</code>값 <span style="color: green">green</span>을 변수로 만든다면 보다 유지보수하기 쉬운 코드가 될 것이다.
아래는 <code>Sass</code>를 활용하여 <span style="color: green">green</span>을 변수에 저장한 코드이다.</p>
<pre><code class="language-scss">$color: green;

ul {
  font-size: 14px;
  color: $color;
}

ol {
  font-size: 18px;
  color: $color;
}</code></pre>
<p><code>Sass</code>에서 변수 선언을 할 땐 변수 앞에 <code>$</code> 기호를 붙여준다. 작성한 <code>scss</code> 파일을 위에서 살펴본 대로 compile하고, 새로 생성된 <code>css</code>를 <code>html</code> 파일에 link 해주면 기존에 <code>css</code>로 스타일을 부여했을 때와 같은 결과물이 출력된다!
<img src="https://images.velog.io/images/mame-coder/post/3661c5d6-b6ff-4733-b274-7f55d5eca6e5/image.png" alt="">
여기서 색상을 <span style="color: blue">blue</span>로 바꾸고 싶다면? 번거롭게 일일이 수정할 필요 없이 변수 <code>$color</code>의 값을 <code>blue</code>로 바꿔주기만 하면 된다.</p>
<pre><code class="language-scss">$color: blue;

ul {
  font-size: 14px;
  color: $color;
}

ol {
  font-size: 18px;
  color: $color;
}</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/2f165f7c-3cfd-49b6-a0e6-79eb4acb7dc9/image.png" alt="">
변경된 색상이 잘 반영됐음을 볼 수 있다.</p>
<hr>
<h3 id="2-nesting">2. nesting</h3>
<pre><code class="language-html">&lt;body&gt;
    &lt;div&gt;
      &lt;p&gt;This is a paragraph inside the div.&lt;/p&gt;

      List inside the div:
      &lt;ul&gt;
        &lt;li&gt;item one&lt;/li&gt;
        &lt;li&gt;item two&lt;/li&gt;
        &lt;li&gt;item three&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/div&gt;

    &lt;p&gt;This is a paragraph outside the div.&lt;/p&gt;

    List outside the div:
    &lt;ul&gt;
      &lt;li&gt;item one&lt;/li&gt;
      &lt;li&gt;item two&lt;/li&gt;
      &lt;li&gt;item three&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/body&gt;</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/7be94253-6f67-4e48-87dd-2dd082d222b7/image.png" alt="">
위와 같이 작성된 <code>html</code> 코드가 있고 <code>div</code> 태그의 하위 속성 <code>p</code>와 <code>ul</code>에 각각 색상을 부여한다 하자. <code>css</code>로 색상을 부여한다면 아래와 같이 작성해야 할 것이다.</p>
<pre><code class="language-css">div {
  font-size: 18px;
}

div p {
  color: blue;
}

div ul {
  color: green;
}</code></pre>
<p>위 코드를 <code>scss</code>로 간소화한다면 아래와 같다.</p>
<pre><code class="language-scss">div {
    font-size: 18px;

    p {
        color: blue;
    }

    ul {
        color: green;
    }
}</code></pre>
<p>따라서 <code>div</code> 태그 하위 요소에 속성을 부여해야 한다면 <code>{}</code> 안에 속성을 부여할 요소를 추가하기만 하면 된다.</p>
<hr>
<h3 id="inheritance">inheritance</h3>
<pre><code class="language-html"> &lt;body&gt;
    &lt;div class=&quot;success&quot;&gt;This is a success message.&lt;/div&gt;

    &lt;div class=&quot;warning&quot;&gt;This is a warning message.&lt;/div&gt;

    &lt;div class=&quot;error&quot;&gt;This is an error message.&lt;/div&gt;
  &lt;/body&gt;</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/4b2bd558-5bd7-4a2e-87d9-cb722a149f64/image.png" alt="">
위 예시처럼 대부분의 속성이 중복되는 요소를 관리할 때도 <code>Sass</code>로써 효율적으로 작성 가능하다.</p>
<pre><code class="language-scss">%message {
    font-family: sans-serif;
    font-size: 18px;
    font-weight: bold;
    border: 1px solid black;
    padding: 20px;
    margin: 20px;
}

.success {
    @extend %message;
    background-color: green;
}

.warning {
    @extend %message;
    background-color: orange;
}

.error {
    @extend %message;
    background-color: red;
}</code></pre>
<p>위처럼 각 요소별 중복되는 속성은 <code>%message</code>에 담고, <code>@extend</code>를 활용하여 앞서 저장한 <code>%message</code> 내 속성들을 불러와서 사용하면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[우아한 테크코스 따라잡기_숫자 야구 게임 Part 1]]></title>
            <link>https://velog.io/@mame-coder/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC%EC%BD%94%EC%8A%A4-%EB%94%B0%EB%9D%BC%EC%9E%A1%EA%B8%B0%EC%88%AB%EC%9E%90-%EC%95%BC%EA%B5%AC-%EA%B2%8C%EC%9E%84-Part-1</link>
            <guid>https://velog.io/@mame-coder/%EC%9A%B0%EC%95%84%ED%95%9C-%ED%85%8C%ED%81%AC%EC%BD%94%EC%8A%A4-%EB%94%B0%EB%9D%BC%EC%9E%A1%EA%B8%B0%EC%88%AB%EC%9E%90-%EC%95%BC%EA%B5%AC-%EA%B2%8C%EC%9E%84-Part-1</guid>
            <pubDate>Sat, 05 Mar 2022 05:18:47 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>언젠가 도전해봐야지 하며 한참을 미루다 어제부터 착수한 작업! 바로 <code>우아한 테크코스 프론트엔드 과정 프리 코스</code>의 3주치 과제 따라만들기! 그 첫 번째 과제는 바로 <code>숫자 야구 게임</code>이다. 본 과제에서 구현해야 하는 <code>기능 요구사항</code>은 다음과 같다.</p>
<hr>
<h3 id="🎯-기능-요구사항">🎯 기능 요구사항</h3>
<blockquote>
<ul>
<li>같은 수가 같은 자리에 있으면 <code>스트라이크</code>, 다른 자리에 있으면 <code>볼</code>, 같은 수가 전혀 없으면 <code>낫싱</code>이란 힌트를 얻고, 그 힌트를 이용해서 먼저 상대방(컴퓨터)의 수를 맞추면 승리한다.</li>
</ul>
</blockquote>
<ul>
<li>예) 상대방(컴퓨터)의 수가 425일 때<ul>
<li>123을 제시한 경우 : 1스트라이크</li>
<li>456을 제시한 경우 : 1볼 1스트라이크</li>
<li>789를 제시한 경우 : 낫싱<ul>
<li>위 숫자 야구게임에서 상대방의 역할을 컴퓨터가 한다. 컴퓨터는 1에서 9까지 서로 다른 임의의 수 3개를 선택한다. 게임 플레이어는 컴퓨터가 생각하고 있는 3개의 숫자를 입력하고, 컴퓨터는 입력한 숫자에 대한 결과를 출력한다.</li>
<li>이 같은 과정을 반복해 컴퓨터가 선택한 3개의 숫자를 모두 맞히면 게임이 종료되고, 재시작 버튼이 노출된다.</li>
<li>게임이 종료된 후 재시작 버튼을 클릭해 게임을 다시 시작할 수 있다.</li>
<li>사용자가 잘못된 값을 입력한 경우 <code>alert</code>으로 에러 메시지를 보여주고, 다시 입력할 수 있게 한다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="💻-실행결과">💻 실행결과</h4>
<p><img src="https://images.velog.io/images/mame-coder/post/65ab9bfb-9f70-4a99-abdc-e1fb11ca15a9/baseball_demo.gif" alt=""></p>
<hr>
<p>사실 코드 구현 자체는 <code>javascript</code>를 조금이라도 만져 본 사람이라면 크게 어렵지 않으리라 생각한다. 다만 코드 작성 시에 염두에 두어야 하는 몇 가지 요구사항들이 까다로웠다. 
아래는 우아한 테크코스 과제 작업 시 지켜야 할 사항들이다.</p>
<hr>
<h3 id="✅-프로그래밍-요구사항">✅ 프로그래밍 요구사항</h3>
<blockquote>
<ul>
<li><code>play</code>(컴퓨터의 랜덤 값, 유저의 입력 값) 메서드를 만들어 게임을 진행한다.</li>
</ul>
</blockquote>
<ul>
<li><code>play</code>메서드는 <code>String</code>으로 결과값을 return 한다.<ul>
<li>스트라이크와 볼이 같이 있는 경우 볼을 먼저쓰고, 스트라이크를 쓴다.</li>
</ul>
</li>
<li><code>index.js</code>에서 아래의 function 또는 class 형태를 활용한다.</li>
</ul>
<pre><code class="language-javascript">export default function BaseballGame() {
  this.play = function (computerInputNumbers, userInputNumbers) {
    return &quot;결과 값 String&quot;;
  };
}

export default class BaseballGame {
  play(computerInputNumbers, userInputNumbers) {
    return &quot;결과 값 String&quot;;
  }
}

// 예시
play(123, 456); // &#39;낫싱&#39;
play(123, 345); // &#39;1볼&#39;
play(123, 432); // &#39;2볼&#39;
play(123, 312); // &#39;3볼&#39;
play(123, 145); // &#39;1스트라이크&#39;
play(123, 134); // &#39;1볼 1스트라이크&#39;
play(123, 132); // &#39;2볼 1스트라이크&#39;
play(123, 124); // &#39;2스트라이크&#39;</code></pre>
<hr>
<h3 id="공통-요구사항">공통 요구사항</h3>
<blockquote>
<ul>
<li>외부 라이브러리(jQuery, Lodash 등)를 사용하지 않고, 순수 Vanilla JS로만 구현한다.</li>
</ul>
</blockquote>
<ul>
<li><strong><a href="https://github.com/woowacourse/woowacourse-docs/tree/feature/styleguide/styleguide/javascript">자바스크립트 코드 컨벤션</a>을 지키면서 프로그래밍</strong> 한다.</li>
<li><strong>indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용</strong>한다.<ul>
<li>예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.</li>
<li>힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 된다.</li>
</ul>
</li>
<li><strong>함수(또는 메소드)가 한 가지 일만 하도록 최대한 작게</strong> 만들어라.</li>
<li>변수 선언시 <code>var</code> 를 사용하지 않는다. <code>const</code> 와 <code>let</code> 을 사용한다.<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const">const</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let">let</a></li>
</ul>
</li>
<li><code>import</code> 문을 이용해 스크립트를 모듈화하고 불러올 수 있게 만든다.<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/import</a></li>
</ul>
</li>
<li><strong>함수(또는 메소드)의 길이가 15라인을 넘어가지 않도록 구현한다.</strong><ul>
<li>함수(또는 메소드)가 한 가지 일만 잘 하도록 구현한다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="📝-과제-진행-요구사항">📝 과제 진행 요구사항</h3>
<blockquote>
<ul>
<li>미션은 <a href="https://github.com/woowacourse/javascript-baseball-precourse/">javascript-baseball-precourse</a> 저장소를 Fork/Clone해 시작한다.</li>
</ul>
</blockquote>
<ul>
<li><strong>기능을 구현하기 전에 javascript-baseball-precourse/docs/README.md 파일에 구현할 기능 목록을 정리</strong>해 추가한다.</li>
<li><strong>Git의 커밋 단위는 앞 단계에서 README.md 파일에 정리한 기능 목록 단위</strong>로 추가한다.<ul>
<li><a href="https://gist.github.com/stephenparish/9941e89d80e2bc58a153">AngularJS Commit Message Conventions</a> 참고해 commit log를 남긴다.</li>
</ul>
</li>
</ul>
<hr>
<p>위의 요구사항들을 받아들고 난감했다. 여태껏 함수의 깊이라든지, Module화라든지, class니 function이니, commit message니 전혀 신경써본 적이 없었기에 이걸 다 지키면서 만들어낼 수 있을까 막막하기만 했다. 그렇게 각종 문서를 뒤지며 고민하기를 1시간째... 일단 기능부터 구현하고, 추후에 요구사항에 맞춰 수정하기로 가닥을 잡았다! 행동으로 옮기지 않으면 아무 일도 일어나지 않으니까!
아래는 내가 작성한 코드와 기능 구현 결과물이다.</p>
<hr>
<h2 id="my-solution">My Solution</h2>
<pre><code># 📁 디렉토리 구조
├─ src
│  ├─ components
│  │  ├─ compareNumbers.js
│  │  ├─ createCPUNumbers.js
│  │  ├─ validateUserNumbers.js
│  ├─ index.js</code></pre><pre><code class="language-javascript"># index.js

import { compareNumbers } from &#39;./components/compareNumbers.js&#39;;

const checkButton = document.querySelector(&#39;#submit&#39;);
export let restartButton = document.querySelector(&#39;#game-restart-button&#39;);
checkButton.addEventListener(&#39;click&#39;, handleCheckButtonFunction);
restartButton.style.display = &#39;none&#39;;

function handleCheckButtonFunction(e) {
  e.preventDefault();
  compareNumbers();
}</code></pre>
<pre><code class="language-javascript"># compareNumbers.js

import { createCPUNumbers } from &#39;./createCPUNumbers.js&#39;;
import { validateUserNumbers } from &#39;./validateUserNumbers.js&#39;;
import { restartButton } from &#39;../index.js&#39;;

const CPUNumbers = createCPUNumbers();

export function compareNumbers() {
  let userNumbers = validateUserNumbers();

  let strike = 0;
  let ball = 0;

  if (!userNumbers) {
    return;
  } else {
    userNumbers.forEach((value, index) =&gt; {
      if (value === CPUNumbers[index]) strike++;
      else if (CPUNumbers.includes(value)) ball++;
    });
  }

  const resultMessage = document.querySelector(&#39;#result&#39;);
  if (strike === 0 &amp;&amp; ball === 0) {
    resultMessage.innerText = &#39;낫싱&#39;;
  } else if (strike &gt; 0 &amp;&amp; ball &gt; 0) {
    resultMessage.innerText = `${ball}볼 ${strike}스트라이크`;
  } else if (ball &gt; 0) {
    resultMessage.innerText = `${ball}볼`;
  } else if (strike &gt; 0) {
    resultMessage.innerText = `${strike}스트라이크`;
  }

  if (strike === 3) {
    resultMessage.innerText = `🎉정답을 맞히셨습니다🎉

    게임을 새로 시작하시겠습니까?

    `;

    restartButton.style.display = &#39;block&#39;;
  }

  restartButton.addEventListener(&#39;click&#39;, () =&gt; location.reload());
}</code></pre>
<pre><code class="language-javascript"># createCPUNumbers.js

export function createCPUNumbers() {
  let CPUNumbersArray = [];

  while (CPUNumbersArray.length &lt;= 2) {
    let randomCPUNums = MissionUtils.Random.pickNumberInRange(1, 9);
    if (CPUNumbersArray.indexOf(randomCPUNums) &lt; 0) {
      CPUNumbersArray.push(randomCPUNums);
    }
  }

  const toStringCPUNumbers = CPUNumbersArray.map((val) =&gt; String(val));
  return toStringCPUNumbers;
}</code></pre>
<pre><code class="language-javascript"># validateUserNumbers.js

export function validateUserNumbers() {
  const userInput = document.querySelector(&#39;#user-input&#39;);
  const userNumbers = userInput.value;
  const numberedUserNumbers = +userNumbers;

  if (
    userNumbers.length &gt; 3 ||
    userNumbers.length &lt; 3 ||
    userNumbers.includes(0) ||
    userNumbers.includes(&#39; &#39;) ||
    userNumbers === &#39;&#39; ||
    isNaN(numberedUserNumbers) === true
  ) {
    alert(&#39;숫자를 조건에 맞게 다시 입력해주세요!&#39;);
    return;
  }

  const userNumberMap = {};
  for (let number of userNumbers)
    userNumberMap[number] = userNumberMap[number] + 1 || 1;

  for (let count in userNumberMap) {
    if (userNumberMap[count] &gt; 1) {
      alert(&#39;숫자를 조건에 맞게 다시 입력해주세요!&#39;);
      return;
    }
  }
  const splitedUserNumbers = userNumbers.split(&#39;&#39;);
  return splitedUserNumbers;
}</code></pre>
<h3 id="실행-결과">실행 결과</h3>
<p><img src="https://images.velog.io/images/mame-coder/post/6dc8a57f-e9e4-45af-a1ef-499be9165211/baseball.gif" alt="">
일단 기능은 완벽하게 구현했다.(고 생각한다...?!)
하지만 앞으로 할 일이 많이 남았다.</p>
<blockquote>
<p><strong>향후 계획</strong>
    1. 기능 단위로 module화하기
    2. 요구사항 지키며 코드 수정
    3. 다른 사람들이 작성한 코드 참고하며 왜 그런 식으로 작성했을지 한 줄 한 줄 들여다보기
    4. class, function, OOP, MVC 등의 개념에 대해 공부하고 실제 코드에 녹여보기</p>
</blockquote>
<hr>
<hr>
<h2 id="함께-보기">함께 보기</h2>
<p><a href="https://github.com/woowacourse/javascript-baseball-precourse">우아한 테크코스 프리코스 1주차 과제_숫자 야구 게임</a>
<a href="https://velog.io/@compy/%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC%EC%BD%94%EC%8A%A4-4%EA%B8%B0-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B3%BC%EC%A0%95-%ED%94%84%EB%A6%AC%EC%BD%94%EC%8A%A4-1%EC%A3%BC%EC%B0%A8-%ED%9B%84%EA%B8%B0">compy님 velog 포스팅_우아한테크코스 4기 프론트엔드 과정, 프리코스 1주차 후기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[하노이의 탑(Towers of Hanoi)]]></title>
            <link>https://velog.io/@mame-coder/%ED%95%98%EB%85%B8%EC%9D%B4%EC%9D%98-%ED%83%91Towers-of-Hanoi</link>
            <guid>https://velog.io/@mame-coder/%ED%95%98%EB%85%B8%EC%9D%B4%EC%9D%98-%ED%83%91Towers-of-Hanoi</guid>
            <pubDate>Thu, 03 Mar 2022 09:55:43 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>이번 글은 아래 자료들을 참고하여 작성하였습니다.</p>
<ol>
<li><a href="https://en.khanacademy.org/computing/computer-science/algorithms#towers-of-hanoi">Towers of Hanoi on Khan Academy</a></li>
<li><a href="https://youtu.be/FYCGV6F1NuY">[파이썬]알고리즘 이야기(01. 하노이 탑) by 파이썬 클래쓰 on Youtube</a></li>
<li><a href="https://youtu.be/uSSC0aKXbWQ">무조건 이해시켜 드립니다. 비법 대방출! 재귀 알고리즘 Recursion - 하노이탑, 피보나치 수열 by 딩코딩 on Youtube</a></li>
</ol>
<hr>
<h2 id="들어가며">들어가며</h2>
<p><code>하노이의 탑</code>을 풀기 위해서는 우선 <code>재귀 함수</code>에 대한 이해가 필요하다. <code>재귀 함수</code>는 <code>javascript</code>의 일반적인 동작 방식인 <code>명령형(Imperative)</code>이 아니라 <code>선언형(declarative)</code>으로 동작한다. 따라서 <code>재귀 함수</code>를 온전히 이해하려면 <code>declarative programming</code>에 대한 감각이 필요하다.</p>
<p>재귀 함수를 짤 때 중요한 것은 두 가지이다.</p>
<blockquote>
</blockquote>
<ol>
<li>종료 조건</li>
<li>문제 정의</li>
</ol>
<p>그럼 위 두 가지를 고려하여 <code>하노이의 탑</code>의 <code>pseudo code</code>를 나열해보자.</p>
<blockquote>
</blockquote>
<ul>
<li>종료조건
  1.원반이 하나 남으면 끝</li>
<li>문제 정의 선언<ol>
<li>N개의 원반을 옮기기 위해서는 N-1개의 원반을 temp기둥으로 옮겨야 함.  </li>
<li>N번째 원반을 목적지 기둥으로 옮긴다.</li>
<li>temp기둥에 있는 N-1개의 원반을 목적지 기둥으로 옮긴다.</li>
</ol>
</li>
</ul>
<p>위의 <code>pseudo code</code>를 바탕으로 코드를 짜면 아래와 같다.</p>
<hr>
<h2 id="towers-of-hanoi">Towers of Hanoi</h2>
<pre><code class="language-javascript">const route = [];

function hanoi(num, from, to, temp) {
  //원판이 한 개일 때에는 바로 옮기면 됨.
  //종료조건
  if (num === 1) {
    route.push([from, to]);
    return NaN;
  }

  hanoi(num - 1, from, temp, to); // n - 1개의 원반을 temp기둥에 옮김. 따라서 to -&gt; temp, temp -&gt; to 로 변경
  route.push([from, to]); // n번째 원반을 from기둥에서 to기둥으로 옮김. n번째 원반을 막고 있던 n - 1개의 원반을 temp로 다 옮겼기 때문에 가능.
  hanoi(num - 1, temp, to, from); // temp기둥에 있던 n - 1개의 원반을 to기둥으로 옮김. temp -&gt; from, from -&gt; temp 로 변경.
}
hanoi(3, &quot;A&quot;, &quot;B&quot;, &quot;C&quot;);
console.log(route); 
/*
[
 [ &#39;A&#39;, &#39;B&#39; ],
 [ &#39;A&#39;, &#39;C&#39; ],
 [ &#39;B&#39;, &#39;C&#39; ],
 [ &#39;A&#39;, &#39;B&#39; ],
 [ &#39;C&#39;, &#39;A&#39; ],
 [ &#39;C&#39;, &#39;B&#39; ],
 [ &#39;A&#39;, &#39;B&#39; ]
]
*/
console.log(route.length); // 7</code></pre>
<p>위 코드는 아래와 같은 순서로 실행된다.</p>
<blockquote>
</blockquote>
<p><strong>실행 과정(7단계)</strong></p>
<pre><code class="language-javascirpt">hanoi(3, A, B, C); // 4. push A, B: 3번 원반 from(A)에서 to(B)로 이동
    hanoi(2, A, C, B) // 2. push A, C: 2번 원반 from(A)에서 temp(C)로 이동
        hanoi(1, A, B, C) // 1. push A, B: 1번 원반 from(A)에서 to(B)로 이동
        hanoi(1, B, C, A) // 3. push B, C: 1번 원반 to(B)에서 temp(C)로 옮겨서 2번 원반 위에 쌓기
    hanoi(2, C, B, A)  // 6. push C, B: 2번 원반 temp(C)에서  to(B)로 이동
        hanoi(1, C, A, B) // 5. push C, A: 2번 위에 있던 1번 원반 temp(C)에서 from(A)로 이동
        hanoi(1, A, B, C) // 7. push A, B: 1번 원반 from(A)에서 to(B)로 이동하면서 완성.</code></pre>
<p>위 실행 순서를 그림으로 나타내면 다음과 같다.
<img src="https://images.velog.io/images/mame-coder/post/7425efc5-2c39-4b07-a95a-7b3e61eac1d5/tree_of_towers_of_hanoi.jpg" alt=""></p>
<hr>
<hr>
<h2 id="함께-보기">함께 보기</h2>
<p><a href="https://velog.io/@mame-coder/%EC%9E%AC%EA%B7%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98Recursive-Algorithms">recursive algorithms</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[재귀 알고리즘(Recursive Algorithms)]]></title>
            <link>https://velog.io/@mame-coder/%EC%9E%AC%EA%B7%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98Recursive-Algorithms</link>
            <guid>https://velog.io/@mame-coder/%EC%9E%AC%EA%B7%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98Recursive-Algorithms</guid>
            <pubDate>Thu, 03 Mar 2022 05:53:02 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>이번 글은 아래 자료들을 참고하여 작성하였습니다.
<a href="https://en.khanacademy.org/computing/computer-science/algorithms#recursive-algorithms">Recursive Algorithms on Khan Academy</a>
<a href="https://www.amazon.com/Think-Like-Programmer-Introduction-Creative/dp/1593274246/ref=sr_1_1?keywords=think+like+a+programmer&amp;qid=1646282385&amp;s=books&amp;sprefix=think+like+a+prog%2Cstripbooks%2C294&amp;sr=1-1">Think Like a Programmer</a></p>
<hr>
<p><img src="https://images.velog.io/images/mame-coder/post/02d869cb-72fd-4318-8220-7125337d74ce/image.png" alt="">
위 인형은 러시아의 전통 인형 <code>마트료시카</code>이다. 큰 인형을 열면 그보다 작은 인형이 하나 나오고 다시 그 인형을 열면 또 작은 인형이 나오고를 반복하며 점점 크기가 작아진다. <code>재귀 함수</code>도 이와 마찬가지로 주어진 조건을 충족할 때까지 함수 자신의 크기를 줄여가다 조건을 충족하면 결과값을 반환하는 함수이다.</p>
<hr>
<h2 id="배열-내-값-모두-더하기">배열 내 값 모두 더하기</h2>
<pre><code class="language-javascript">// solution 1.
const numArr1 = [1, 2, 3, 4, 5];

function iterativeArraySum(array, size) {
  let sum = 0;

  for (let i = 0; i &lt; size; ++i) {
    sum += array[i];
  }
  return sum;
}

console.log(iterativeArraySum(numArr1, numArr1.length)); // 15</code></pre>
<p>위 코드는 주어진 배열의 길이만큼 <code>for문</code>으로 주어진 배열을 탐색하여 배열 내 모든 값의 합을 반환하는 함수이다. 이 함수를 살펴보면 배열 index 0부터 끝까지 탐색하며 값을 하나하나 더해나가는 것을 알 수 있다. 일정 조건 하에 반복 작업을 수행하는 함수라면, 반복문 대신 재귀 함수로 바꿔 쓸 수 있다.</p>
<p>위 함수를 완전한 재귀 함수로 바꿔 쓰기 전에 위 반복문은 그대로 놔둔 채 다른 기능을 수행하는 함수를 추가하여 보다 재귀 함수와 가까워지게 작성해보자. </p>
<pre><code class="language-javascript">// solution 2.
function iterativeArraySum(array, size) {
  let sum = 0;

  for (let i = 0; i &lt; size; ++i) {
    sum += array[i];
  }
  return sum;
}

function arraySumDelegate(array, size) {
  if (size === 0) return 0;
  // the last number in the array is stored in this local variable
  const lastNum = array[size - 1];
  // the sum of all the other values in the array is computed and this result is stored in this local variable
  const allButLastSum = iterativeArraySum(array, size - 1);
  return lastNum + allButLastSum;
}

console.log(arraySumDelegate(numArr1, numArr1.length)); // 15</code></pre>
<ol>
<li>주어진 배열의 길이가 <code>0</code>이라면 결과값 <code>0</code>반환.</li>
<li>주어진 배열의 길이가 <code>0</code>보다 크다면 반복문을 호출하여 <code>size</code>의 값이 <code>0</code>이 될 때까지 배열값 더하기 작업 수행</li>
</ol>
<p>위의 함수를 재귀 함수로 바꾸기 위해서는 <code>iterativeArraySum</code>으로 호출하는 반복문을 지금 실행 중인 함수로 치환하면 된다. 작성하면 아래와 같이 된다.</p>
<pre><code class="language-javascript">// solution 3.
const numArr1 = [1, 2, 3, 4, 5];

function arraySumRecursive(array, size) {
  if (size === 0) return 0;

  const lastNum = array[size - 1];
  const allButLastSum = arraySumRecursive(array, size - 1);

  return lastNum + allButLastSum;
}

console.log(arraySumDelegate(numArr1, numArr1.length)); // 15</code></pre>
<p>위의 함수를 실행하게 되면 <code>size</code>의 값이 <code>0</code>이 될때까지 해당 작업을 반복하며 배열 내 값을 모두 더한다. <code>solution 2.</code>에서는 <code>allButLastSum</code>에 해당하는 값으로 다른 반복문을 불러왔다면, 여기서는 자기 자신을 호출함으로써 재귀적 작업을 수행한다.</p>
<hr>
<h2 id="recursive-algorithms-활용-예들">Recursive Algorithms 활용 예들</h2>
<h3 id="the-factorial-function">The Factorial Function</h3>
<pre><code class="language-javascript">const factorial = function (n) {
  // base case:
  if (n === 0) {
    return 1;
  }

  return n * factorial(n - 1);
};

console.log(factorial(5)); // 120</code></pre>
<p>위의 함수는 1부터 n까지 자연수의 곱을 계산하는 함수이다. <code>n-1</code>을 설정하여 함수 <code>factorial</code>이 재귀적으로 쓰인 것을 볼 수 있다.</p>
<hr>
<h3 id="determine-palindrome">determine palindrome</h3>
<pre><code class="language-javascript">const firstCharacter = function (str) {
  return str.slice(0, 1);
};

// Returns the last character of a string str
const lastCharacter = function (str) {
  return str.slice(-1);
};

// Returns the string that results from removing the first
//  and last characters from str
const middleCharacters = function (str) {
  return str.slice(1, -1);
};

const isPalindrome = function (str) {
  // base case #1
  if (str.length &lt;= 1) return true;
  // base case #2
  if (firstCharacter(str) === lastCharacter(str))
    return isPalindrome(middleCharacters(str));
  // recursive case
  return false;
};

const checkPalindrome = function (str) {
  console.log(&quot;Is this word a palindrome? &quot; + str);
  console.log(isPalindrome(str));
};

checkPalindrome(&quot;&quot;); // true
checkPalindrome(&quot;a&quot;); // true
checkPalindrome(&quot;motor&quot;); // false
checkPalindrome(&quot;rotor&quot;); // true</code></pre>
<p>위의 코드는 주어진 문자열이 <code>palindrome</code>인지 판별하는 함수이다. 입력값이 없거나 하나인 경우 <code>palindrome</code>이기 때문에 <code>true</code>를 반환한다. 입력값의 길이가 2 이상인 경우 첫째값과 마지막 값을 잘라내어 일치 여부를 확인하고 나머지 중간값을 반환, 다시 반환된 중간값의 첫째값과 마지막값의 일치 여부를 확인하는 작업을 반복한다. 작업을 마친 후 <code>palindrome</code>이라면 <code>true</code>, 아니라면 <code>false</code>를 반환한다.</p>
<hr>
<h2 id="fibonacci-series">Fibonacci Series</h2>
<pre><code class="language-javascript">function fib(n) {
  if (n &lt; 2) {
    return n;
  }

  return fib(n - 1) + fib(n - 2);
}

console.log(fib(9)); // 34</code></pre>
<p>위 함수는 피보나치 수열을 재귀 함수로 작성한 것이다. 함수를 실행하면 앞의 수와 앞앞의 수를 더하는 작업을 반복하여 입력값 n번째 위치하는 피보나치의 수를 구한다.</p>
<hr>
<hr>
<h2 id="함께-보기">함께 보기</h2>
<p><a href="https://velog.io/@mame-coder/%ED%94%BC%EB%B3%B4%EB%82%98%EC%B9%98%EC%9D%98-%EC%88%98%EC%97%B4Fibonacci-Sequence">Fibonacci</a>
<a href="https://velog.io/@mame-coder/Palindromes">Palindromes</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[퀵 정렬(Quick Sort)]]></title>
            <link>https://velog.io/@mame-coder/%ED%80%B5-%EC%A0%95%EB%A0%ACQuick-Sort</link>
            <guid>https://velog.io/@mame-coder/%ED%80%B5-%EC%A0%95%EB%A0%ACQuick-Sort</guid>
            <pubDate>Wed, 02 Mar 2022 07:38:05 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>이번 글은 아래 자료를 참고하여 작성하였습니다.
<a href="https://en.khanacademy.org/computing/computer-science/algorithms#insertion-sort">Insertion Sort on Khan Academy</a></p>
<hr>
<pre><code class="language-javascript">const partition = function (array, startIdx, lastIdx) {
  let partitonedArr = array,
    partitonedArrStartIdx = startIdx,
    partitonedArrLastIdx = lastIdx;

  const createPartitionedArr = function (
    partitonedArr,
    partitonedArrStartIdx,
    partitonedArrLastIdx
  ) {
    let partitonedRightArrStartIdx = partitonedArr[partitonedArrStartIdx];

    partitonedArr[partitonedArrStartIdx] = partitonedArr[partitonedArrLastIdx];
    partitonedArr[partitonedArrLastIdx] = partitonedRightArrStartIdx;
  };

  let partitonedLeftArrStartIdx = partitonedArrStartIdx;
  for (let s = partitonedArrStartIdx; s &lt; partitonedArrLastIdx; s++) {
    if (partitonedArr[s] &lt;= partitonedArr[partitonedArrLastIdx]) {
      createPartitionedArr(partitonedArr, s, partitonedLeftArrStartIdx);
      partitonedLeftArrStartIdx++;
    }
  }

  createPartitionedArr(
    partitonedArr,
    partitonedArrLastIdx,
    partitonedLeftArrStartIdx
  );

  return partitonedLeftArrStartIdx;
};

const quickSort = function (array, startIdx, lastIdx) {
  if (startIdx &lt; lastIdx) {
    let midIdx = partition(array, startIdx, lastIdx);
    quickSort(array, startIdx, midIdx - 1);
    quickSort(array, midIdx + 1, lastIdx);
  }
};

const array = [9, 7, 5, 11, 12, 2, 14, 3, 10, 6];
quickSort(array, 0, array.length - 1);
console.log(array); // [ 2, 3, 5, 6, 7, 9, 10, 11, 12, 14 ]</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/97e060d0-3b1e-406a-9ea7-8188f7f683c5/image.png" alt=""></p>
<p><code>quick sort</code>는 배열 정렬의 기준값이 되는 <code>pivot</code>을 기준으로 <code>pivot</code>보다 작은 값을 왼쪽에, 큰 값을 오른쪽에 정렬하는 알고리즘이다. 이때 <code>pivot</code>은 배열의 가장 마지막 값이다.
위 그림에서 <code>pivot</code>의 값은 <code>6</code>인데, 두 번째 줄을 보면 <code>6</code>보다 작은 값은 왼쪽 배열에, 큰 값은 오른쪽 배열에 담겼다. <code>6</code>을 기준으로 나눈 두 배열에서 다시 끝 값을 <code>pivot</code>으로 삼아 똑같은 방식으로 각 배열의 값을 정렬한다. 
<code>merge sort</code>와 같이 <code>divide-and-conquer</code> 방식으로 작동한다. <code>merge sort</code>에서는 <code>combine</code> 단계에서 정렬이 이뤄지는 반면, <code>quick sort</code>에서는 <code>divide</code> 단계에서 모든 작업이 이뤄진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[삽입 정렬(Insertion Sort)]]></title>
            <link>https://velog.io/@mame-coder/%EC%82%BD%EC%9E%85-%EC%A0%95%EB%A0%ACInsertion-Sort</link>
            <guid>https://velog.io/@mame-coder/%EC%82%BD%EC%9E%85-%EC%A0%95%EB%A0%ACInsertion-Sort</guid>
            <pubDate>Wed, 02 Mar 2022 06:27:35 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>이번 글은 아래 자료를 참고하여 작성하였습니다.
<a href="https://en.khanacademy.org/computing/computer-science/algorithms#insertion-sort">Insertion Sort on Khan Academy</a></p>
<hr>
<h2 id="insertion-sort">Insertion Sort</h2>
<pre><code class="language-javascript">function insert(array, rightIndex, value) {
  // let temp;
  // for (let i = rightIndex; i &gt;= 0; --i) {
  //   if (value &lt; array[i]) {
  //     temp = array[i];
  //     array[i] = value;
  //     array[i + 1] = temp;
  //   }
  // }

  for (let i = rightIndex; i &gt;= 0 &amp;&amp; array[i] &gt; value; --i) {
    array[i + 1] = array[i];
    array[i] = value;
  }
}

function insertionSort(array) {
  for (let i = 1; i &lt; array.length; ++i) {
    insert(array, i - 1, array[i]);
  }
  return array;
}

const array = [3, 5, 7, 11, 13, 2, 9, 6];
console.log(insertionSort(array)); // [2, 3, 5, 6, 7, 9, 11, 13]</code></pre>
<p><code>insertionSort</code>를 통해 주어진 배열을 입력값으로 탐색하면서 <code>rightIndex</code> 범위 내의 값들 중 입력값보다 탐색값이 크다면 탐색값의 index를 <code>1</code>만큼 증가시키고, <code>array[i]</code>에 있던 값을 <code>value</code>로 바꾼다. 이 작업을 반복하면 주어진 배열이 오름차순으로 정렬된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[합병 정렬(Merge Sort)]]></title>
            <link>https://velog.io/@mame-coder/%ED%95%A9%EB%B3%91-%EC%A0%95%EB%A0%ACMerge-Sort</link>
            <guid>https://velog.io/@mame-coder/%ED%95%A9%EB%B3%91-%EC%A0%95%EB%A0%ACMerge-Sort</guid>
            <pubDate>Wed, 02 Mar 2022 01:33:26 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>이번 글은 아래 자료들을 참고하여 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">Section 33. Ack, MergeSort!</a>
<a href="https://en.khanacademy.org/computing/computer-science/algorithms#merge-sort">Merge Sort on Khan Academy</a></p>
<hr>
<pre><code class="language-javascript">function mergeSort(arr) {
  if (arr.length === 1) {
    return arr;
  }

  const center = Math.floor(arr.length / 2);
  const left = arr.slice(0, center);
  const right = arr.slice(center);

  return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right) {
  const results = [];

  while (left.length &amp;&amp; right.length) {
    if (left[0] &lt; right[0]) {
      results.push(left.shift());
    } else {
      results.push(right.shift());
    }
  }

  return [...results, ...left, ...right];
}</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/34123b55-837a-4977-860e-46ac5e2ab095/image.png" alt="">
<img src="https://images.velog.io/images/mame-coder/post/62add4fe-c175-41a8-be22-7ed796e683d4/image.png" alt=""></p>
<p>위 그림에서 보듯 재귀함수 <code>mergeSort Function</code>을 거쳐서 주어진 배열의 길이가 <code>1</code>이 될 때까지 <code>left</code>, <code>right</code>로 쪼갠다. 쪼개진 값들을 <code>merge Function</code>을 거치면서 배열 <code>left</code>와 배열 <code>right</code>의 첫 값을 비교하여 작은 값을 왼쪽으로 몰고, 큰 값을 오른쪽으로 보낸다. 위 과정을 모두 거치면 주어진 배열이 오름차순으로 정렬된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[선택 정렬(Selection Sort)]]></title>
            <link>https://velog.io/@mame-coder/%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%ACSelection-Sort</link>
            <guid>https://velog.io/@mame-coder/%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%ACSelection-Sort</guid>
            <pubDate>Tue, 01 Mar 2022 01:39:31 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>이번 글은 아래 자료들을 참고하여 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">Section 32. Sort By Selection on Udemy</a>
<a href="https://en.khanacademy.org/computing/computer-science/algorithms#sorting-algorithms">Selection Sort on Khan Academy</a></p>
<hr>
<h2 id="selection-sort">Selection Sort</h2>
<pre><code class="language-javascript">// solution 1.
function selectionSort(arr) {
  for (let i = 0; i &lt; arr.length; ++i) {
    let indexOfMin = i;
    // for문 j 돌면서 arr[j]가 arr[indexOfMin]보다 작으면 indexOfMin을 j로 치환한다. 즉, 현재값과 배열 내 값들을 비교하며, 현재 값보다 작은 값의 위치를 기록하는 것이다.
    for (let j = i + 1; j &lt; arr.length; ++j) {
      if (arr[j] &lt; arr[indexOfMin]) {
        indexOfMin = j;
      }
    }
    // 현재 값보다 작은 값이 배열 내 존재했다면 indexOfMin과 i는 같지 않을 것이고 따라서 큰 값인 현재 값과 작은 값의 위치를 서로 바꿔준다.
    if (indexOfMin !== i) {
      let lesser = arr[indexOfMin];
      arr[indexOfMin] = arr[i];
      arr[i] = lesser;
    }
  }

  return arr;
}</code></pre>
<pre><code class="language-javascript">// solution 2.
const swap = function (array, firstIndex, secondIndex) {
  let temp = array[firstIndex];
  array[firstIndex] = array[secondIndex];
  array[secondIndex] = temp;
};

const indexOfMinimum = function (array, startIndex) {
  let minValue = array[startIndex];
  let minIndex = startIndex;

  for (let i = minIndex + 1; i &lt; array.length; ++i) {
    if (array[i] &lt; minValue) {
      minIndex = i;
      minValue = array[i];
    }
  }

  return minIndex;
};

const selectionSort = function (array) {
  let temp;

  for (let i = 0; i &lt; array.length; ++i) {
    temp = indexOfMinimum(array, i);
    swap(array, i, temp);
  }
};</code></pre>
<p>두 <code>solution</code> 모두 주어진 배열을 <code>for문</code>으로 탐색하면서 값들을 하나하나 비교하여 작은 값을 임시 변수에 담고, 더 작은 값이 나오면 임시 변수의 값을 치환하는 식으로 작동하는 코드이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[거품 정렬(Bubble Sort)]]></title>
            <link>https://velog.io/@mame-coder/%EA%B1%B0%ED%92%88-%EC%A0%95%EB%A0%ACBubble-Sort</link>
            <guid>https://velog.io/@mame-coder/%EA%B1%B0%ED%92%88-%EC%A0%95%EB%A0%ACBubble-Sort</guid>
            <pubDate>Mon, 28 Feb 2022 22:19:54 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 31. Sorting with BubbleSort</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="bubble-sort">Bubble Sort</h2>
<pre><code class="language-javascript">function bubbleSort(arr) {
  for (let i = 0; i &lt; arr.length; ++i) {
    for (let j = 0; j &lt; arr.length - 1 - i; ++j) {
      if (arr[j] &gt; arr[j + 1]) {
        const lesser = arr[j + 1];
        arr[j + 1] = arr[j];
        arr[j] = lesser;
      }
    }
  }

  return arr;
}</code></pre>
<hr>
<p><img src="https://images.velog.io/images/mame-coder/post/9e79ad36-3247-411b-bf4b-ae7161957683/image.png" alt="">
<code>Bubble Sort</code>는 주어진 배열 전체를 탐색하며 인접한 두 값의 대소를 비교하여 큰 값을 뒤로 보내고 작은 값을 앞으로 보내 배열 내 값들을 정렬하는 방식이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이진 탐색 트리 유효성 검사(Validating a Binary Search Tree)]]></title>
            <link>https://velog.io/@mame-coder/%EC%9D%B4%EC%A7%84-%ED%83%90%EC%83%89-%ED%8A%B8%EB%A6%AC-%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%82%ACValidating-a-Binary-Search-Tree</link>
            <guid>https://velog.io/@mame-coder/%EC%9D%B4%EC%A7%84-%ED%83%90%EC%83%89-%ED%8A%B8%EB%A6%AC-%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%82%ACValidating-a-Binary-Search-Tree</guid>
            <pubDate>Mon, 28 Feb 2022 07:41:44 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 28. Validating a Binary Search Tree</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="validating-a-binary-search-tree">Validating a Binary Search Tree</h2>
<pre><code class="language-javascript">function validate(node, min = null, max = null) {
  if (max !== null &amp;&amp; node.data &gt; max) {
    return false;
  }

  if (min !== null &amp;&amp; node.data &lt; min) {
    return false;
  }

  if (node.left &amp;&amp; !validate(node.left, min, node.data)) {
    return false;
  }

  if (node.right &amp;&amp; !validate(node.right, node.data, max)) {
    return false;
  }

  return true;
}</code></pre>
<p><code>recursive function</code>과 <code>if문</code>을 거치면서 입력값이 <code>root</code>값을 기준으로 작다면 왼쪽에 위치하고, 크다면 오른쪽에 놓이게 한다. 여기서 왼쪽 트리를 탐색할 때는 탐색 중인 왼쪽 트리의 값이 <code>max</code>값에 할당되어 그보다 작은 값만 왼쪽 트리에 저장되게끔 제한을 하고, 반대로 오른쪽은 <code>min</code>값이 바뀌어 탐색 중인 오른쪽 트리의 값보다 큰 값만이 오른쪽에 저장되게끔 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이진 탐색 트리(Binary Search Trees)]]></title>
            <link>https://velog.io/@mame-coder/%EC%9D%B4%EC%A7%84-%ED%83%90%EC%83%89-%ED%8A%B8%EB%A6%ACBinary-Search-Trees</link>
            <guid>https://velog.io/@mame-coder/%EC%9D%B4%EC%A7%84-%ED%83%90%EC%83%89-%ED%8A%B8%EB%A6%ACBinary-Search-Trees</guid>
            <pubDate>Mon, 28 Feb 2022 06:32:57 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 27. My Best Friend, Binary Search Trees</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="binary-search-trees">Binary Search Trees</h2>
<pre><code class="language-javascript">class Node {
  constructor(data) {
    this.data = data;
    this.left = null;
    this.right = null;
  }

  insert(data) {
    // 입력값 data가 this.data보다 작고 this.left에 값이 이미 할당되어 있다면 this.left에 입력값 data을 넣고, this.left가 없는데 입력값 data가 this.data보다 작다면 this.left에 새로운 node를 할당한다. 입력값의 대소비교만을 빼고 this.right의 경우도 마찬가지이다.
    if (data &lt; this.data &amp;&amp; this.left) {
      this.left.insert(data);
    } else if (data &lt; this.data) {
      this.left = new Node(data);
    } else if (data &gt; this.data &amp;&amp; this.right) {
      this.right.insert(data);
    } else if (data &gt; this.data) {
      this.right = new Node(data);
    }
  }

  contains(data) {
    if (this.data === data) {
      return this;
    }
    // 입력값 data가 현재값 this.data보다 크고 this.right에 node가 존재한다면?
    if (this.data &lt; data &amp;&amp; this.right) {
      return this.right.contains(data);
    } else if (this.data &gt; data &amp;&amp; this.left) {
      return this.left.contains(data);
    }

    return null;
  }
}</code></pre>
<hr>
<p><img src="https://images.velog.io/images/mame-coder/post/99ff717b-b901-4e6c-9a0e-6ee338821e2c/image.png" alt=""></p>
<p><code>binary search trees</code>란 <code>root</code>값을 기준으로 새로 입력하는 값이 작으면 왼쪽, 크다면 오른쪽으로 정렬해놓은 트리이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[트리의 너비(Tree Width)]]></title>
            <link>https://velog.io/@mame-coder/%ED%8A%B8%EB%A6%AC%EC%9D%98-%EB%84%88%EB%B9%84Tree-Width</link>
            <guid>https://velog.io/@mame-coder/%ED%8A%B8%EB%A6%AC%EC%9D%98-%EB%84%88%EB%B9%84Tree-Width</guid>
            <pubDate>Mon, 28 Feb 2022 03:14:52 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 26. Tree Width with Level Width</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="tree-width">Tree Width</h2>
<pre><code class="language-javascript">function levelWidth(root) {
  const arr = [root, &quot;s&quot;];
  const widths = [0];

  while (arr.length &gt; 1) {
    const node = arr.shift();

    if (node === &quot;s&quot;) {
      widths.push(0);
      arr.push(&quot;s&quot;);
    } else {
      arr.push(...node.children);
      widths[widths.length - 1]++;
    }
  }

  return widths;
}</code></pre>
<blockquote>
<p><img src="https://images.velog.io/images/mame-coder/post/0c50adec-09ab-4bbd-9129-5e242e63721a/tree_width.gif" alt=""></p>
</blockquote>
<p>각 단계에 포함된 값들을 <code>arr</code>에 넣어서 배열 <code>arr</code>의 길이를 <code>width</code>로서 저장하고, 중간에 <code>stopper</code> 역할을 하는 문자 <code>s</code>를 넣어 탐색 작업 중 문자 <code>s</code>와 만나면 다음 단계로 넘어가게끔 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[트리(Tree)]]></title>
            <link>https://velog.io/@mame-coder/%ED%8A%B8%EB%A6%ACTree</link>
            <guid>https://velog.io/@mame-coder/%ED%8A%B8%EB%A6%ACTree</guid>
            <pubDate>Mon, 28 Feb 2022 02:40:58 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 25. Building a Tree</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="node">Node</h2>
<pre><code class="language-javascript">class Node {
  constructor(data) {
    this.data = data;
    this.children = [];
  }
  // node의 입력값 data를 배열로 children에 push
  add(data) {
    const node = new Node(data);
    this.children.push(node);
  }
 // filter() method로써 특정값을 제외한 배열을 반환
  remove(data) {   
    this.children = this.children.filter((node) =&gt; {
      return node.data !== data;
    });
  }
}</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/c0c5161d-33b9-4de8-af7a-91989be5ff0a/image.png" alt=""></p>
<hr>
<h2 id="tree">Tree</h2>
<pre><code class="language-javascript">class Tree {
  constructor() {
    this.root = null;
  }

  traverseBF(fn) {
    const arr = [this.root];
    while (arr.length) {
      const node = arr.shift();
      // 그냥 node.children을 push하면 array로 들어가서 nested array 되기 때문에 하나씩 꺼내어 push
      arr.push(...node.children);
      //   for (let child of node.children) {
      //     arr.push(child);
      //   }
      fn(node);
    }
  }

  traverseDF(fn) {
    const arr = [this.root];
    while (arr.length) {
      const node = arr.shift();

      arr.unshift(...node.children);
      fn(node);
    }
  }
}</code></pre>
<hr>
<h3 id="너비-탐색breadth-first-search">너비 탐색(breadth first search)</h3>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/mame-coder/post/09bf67a9-0733-4907-b053-8261a33db969/image.png" alt="">
<img src="https://images.velog.io/images/mame-coder/post/6f1bf4e0-bede-4429-94ff-0e3611624615/image.png" alt="">
<img src="https://images.velog.io/images/mame-coder/post/ee11c069-d1e3-4eb7-a29e-1becd1badeef/traverseBF.gif" alt=""></p>
<p>위 그림에서 볼 수 있듯 <code>너비 탐색(breadth first search)</code>에서는 <code>linked list</code>의 맨 상위 단계에서 맨 하위 단계로 내려가면서, 각 단계별 첫 값에서 끝 값까지를 탐색한다.</p>
<hr>
<h3 id="깊이-탐색depth-first-search">깊이 탐색(depth first search)</h3>
<blockquote>
</blockquote>
<p><img src="https://images.velog.io/images/mame-coder/post/36afb222-2bc4-4e50-99cf-95b10f281eef/image.png" alt="">
<img src="https://images.velog.io/images/mame-coder/post/1377e658-18a8-447e-ad40-e9a954602314/traverseDF.gif" alt=""></p>
<p>위 그림에서 볼 수 있듯 <code>깊이 탐색(depth first search)</code>의 경우 <code>linked list</code>의 맨 상위 단계에서 맨 하위 단계로 내려가면서 각 단계의 맨 첫 값에 하위값이 있다면 그 하위값들부터 우선 탐색을 하고, 다시 상위 단계로 돌아와 하위값들을 탐색하는 과정을 반복한다.</p>
<hr>
<h2 id="entire-code">Entire Code</h2>
<pre><code class="language-javascript">class Node {
  constructor(data) {
    this.data = data;
    this.children = [];
  }

  add(data) {
    const node = new Node(data);
    this.children.push(node);
  }

  remove(data) {
    this.children = this.children.filter((node) =&gt; {
      return node.data !== data;
    });
  }
}

class Tree {
  constructor() {
    this.root = null;
  }

  traverseBF(fn) {
    const arr = [this.root];
    while (arr.length) {
      const node = arr.shift();

      arr.push(...node.children);
      //   for (let child of node.children) {
      //     arr.push(child);
      //   }
      fn(node);
    }
  }

  traverseDF(fn) {
    const arr = [this.root];
    while (arr.length) {
      const node = arr.shift();

      arr.unshift(...node.children);
      fn(node);
    }
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[끝에서부터 노드 세기(From the Tail)]]></title>
            <link>https://velog.io/@mame-coder/%EB%81%9D%EC%97%90%EC%84%9C%EB%B6%80%ED%84%B0-%EB%85%B8%EB%93%9C-%EC%84%B8%EA%B8%B0From-the-Tail</link>
            <guid>https://velog.io/@mame-coder/%EB%81%9D%EC%97%90%EC%84%9C%EB%B6%80%ED%84%B0-%EB%85%B8%EB%93%9C-%EC%84%B8%EA%B8%B0From-the-Tail</guid>
            <pubDate>Sat, 26 Feb 2022 00:41:02 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 24. Step Back From the Tail</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="solution">Solution</h2>
<pre><code class="language-javascript">function fromLast(list, n) {
  let slow = list.getFirst();
  let fast = list.getFirst();

  while (n &gt; 0) {
    fast = fast.next;
    n--;
  }

  while (fast.next) {
    slow = slow.next;
    fast = fast.next;
  }

  return slow;
}</code></pre>
<p>눈여겨봐야 할 부분은 두 개의 <code>while</code>문의 기능이다.</p>
<blockquote>
<p><strong>첫 번째 <code>while문</code></strong>
<img src="https://images.velog.io/images/mame-coder/post/45b101cc-7b08-4d6e-b291-661856d82a0a/from_the_tail_1.gif" alt=""></p>
</blockquote>
<p><code>n</code>이 <code>0</code>보다 클 동안 <code>while문</code>을 돌면서 변수 <code>fast</code>를 한 칸씩 앞으로 전진시킨다. 결과적으로 변수 <code>fast</code>에 할당된 <code>node</code>의 위치는 변수 <code>slow</code>에 할당된 <code>node</code>보다 <code>n</code>만큼 앞서게 된다. </p>
<blockquote>
<p><strong>두 번째 <code>while문</code></strong>
<img src="https://images.velog.io/images/mame-coder/post/86cf56ec-29d3-4176-b969-ef513cb5e3ff/from_the_tail_2.gif" alt=""></p>
</blockquote>
<p><code>fast.next</code>가 <code>true</code>인 동안 변수 <code>slow</code>와 <code>fast</code> 한 칸씩 전진시킨다. <code>fast.next</code>의 값이 <code>null</code>이 되는 지점이 곧 <code>tail</code>을 뜻하므로 이 때의 <code>slow</code>는 곧<code>tail</code>에서 <code>n</code>만큼 떨어진 <code>node</code>와 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[순환 리스트(Circular List)]]></title>
            <link>https://velog.io/@mame-coder/%EC%88%9C%ED%99%98-%EB%A6%AC%EC%8A%A4%ED%8A%B8Circular-List</link>
            <guid>https://velog.io/@mame-coder/%EC%88%9C%ED%99%98-%EB%A6%AC%EC%8A%A4%ED%8A%B8Circular-List</guid>
            <pubDate>Fri, 25 Feb 2022 23:30:12 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 23. Circular Lists?</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="solution">Solution</h2>
<pre><code class="language-javascript">function circular(list) {
  let slow = list.getFirst(); // = list.head;
  let fast = list.getFirst();

  while (fast.next &amp;&amp; fast.next.next) {
    slow = slow.next;
    fast = fast.next.next;

    if (slow === fast) {
      return true;
    }
  }

  return false;
}

// --- Examples
//   const l = new List();
//   const a = new Node(&#39;a&#39;);
//   const b = new Node(&#39;b&#39;);
//   const c = new Node(&#39;c&#39;);
//   l.head = a;
//   a.next = b;
//   b.next = c;
//   c.next = b;
//   circular(l) // true</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/9fee561d-7392-4b2d-8727-5cccbff1a059/image.png" alt="">
이전에 작성한 <a href="https://velog.io/@mame-coder/%EC%A4%91%EA%B0%84-%EB%85%B8%EB%93%9C-%EC%B0%BE%EA%B8%B0Find-the-Middle-Node">중간 노드 찾기</a>와 코드 구성이 유사하다. <code>slow</code>와 <code>fast</code> 변수가 각각 <code>linked list</code>를 탐색하다가 두 값이 모두 똑같은 <code>node</code>를 가리키게 되면 <code>true</code>를 반환하고, 조건을 만족하지 못하면 <code>false</code>를 반환하게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[중간 노드 찾기(Find the Middle Node)]]></title>
            <link>https://velog.io/@mame-coder/%EC%A4%91%EA%B0%84-%EB%85%B8%EB%93%9C-%EC%B0%BE%EA%B8%B0Find-the-Middle-Node</link>
            <guid>https://velog.io/@mame-coder/%EC%A4%91%EA%B0%84-%EB%85%B8%EB%93%9C-%EC%B0%BE%EA%B8%B0Find-the-Middle-Node</guid>
            <pubDate>Fri, 25 Feb 2022 14:00:02 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 22. Find the Midpoint</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="solution">Solution</h2>
<pre><code class="language-javascript">function midpoint(list) {
  let slow = list.getFirst();
  let fast = list.getFirst();

  while (fast.next &amp;&amp; fast.next.next) {
    slow = slow.next;
    fast = fast.next.next;
  }

  return slow;
}</code></pre>
<p><code>linked list</code>를 한 칸씩 탐색하는 변수 <code>slow</code>와 두 칸씩 탐색하는 변수 <code>fast</code>를 각각 선언한다. <code>fast</code>로 탐색을 하다 더 이상 탐색값이 없다면(null) <code>while문</code>을 멈추고 <code>linked list</code>의 중간값인 <code>slow</code>를 반환한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[연결 리스트(Linked Lists)]]></title>
            <link>https://velog.io/@mame-coder/%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8Linked-Lists</link>
            <guid>https://velog.io/@mame-coder/%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8Linked-Lists</guid>
            <pubDate>Fri, 25 Feb 2022 12:08:53 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 21. Linked Lists</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="solution">Solution</h2>
<pre><code class="language-javascript">class Node {
  // node에다 새로운 instance 생설할 때마다 constructor가 자동으로 실행됨.
  // argument next의 기본값은 null로 설정. tail node에는 next가 없기 때문.
  constructor(data, next = null) {
    this.data = data;
    this.next = next;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
  }

  insertFirst(data) {
    // 새로이 node를 insert하게 되면 head에 할당되어 있던 기존 값은 next에 할당되고 새 값이 head로 치환됨.
    // this.head = new Node(data, this.head);
    this.insertAt(data, 0);
  }

  insertLast(data) {
    // const last = this.getLast();

    // if (last) {
    //   // There are some existing nodes in our chain
    //   last.next = new Node(data);
    // } else {
    //   // The chain is empty
    //   this.head = new Node(data);
    // }
    this.insertAt(data, this.size());
  }

  size() {
    let counter = 0;
    let node = this.head;

    while (node) {
      counter++;
      node = node.next;
    }

    return counter;
  }

  getFirst() {
    // return this.head;
    return this.getAt(0);
  }

  getLast() {
    // if (!this.head) {
    //   return null;
    // }

    // let node = this.head;
    // // this.head를 while문으로써 한 칸씩 옮겨가며 node.next가 없을 때까지 탐색
    // while (node) {
    //   // next가 없다면 현재 탐색값인 node 반환.
    //   if (!node.next) {
    //     return node;
    //   }
    //   // next가 있다면 node를 node.next로 치환.
    //   node = node.next;
    // }
    return this.getAt(this.size() - 1);
  }

  clear() {
    this.head = null;
  }

  removeFirst() {
    // if (!this.head) {
    //   return;
    // }

    // this.head = this.head.next;
    this.removeAt(0);
  }

  removeLast() {
    // // 아무 node도 없다면?
    // if (!this.head) {
    //   return;
    // }
    // // node가 하나밖에 없다면?(next가 false라면?)
    // if (!this.head.next) {
    //   this.head = null;
    //   return;
    // }

    // let previous = this.head;
    // let node = this.head.next;
    // // next가 존재하는 동안 while 돌리기
    // while (node.next) {
    //   previous = node;
    //   node = node.next;
    // }
    // // while 다 돌고 나면 마지막 값 null로 만들어 삭제
    // previous.next = null;
    this.removeAt(this.size() - 1);
  }

  getAt(index) {
    let counter = 0;
    let node = this.head;

    while (node) {
      if (counter === index) {
        return node;
      }

      counter++;
      node = node.next;
    }

    return null;
  }

  removeAt(index) {
    if (!this.head) {
      return;
    }

    if (index === 0) {
      this.head = this.head.next;
      return;
    }

    const previous = this.getAt(index - 1);

    if (!previous || !previous.next) {
      return;
    }

    previous.next = previous.next.next;
  }

  insertAt(data, index) {
    if (!this.head) {
      this.head = new Node(data);
      return;
    }
    // index 0에 insert할 경우 현재 head(this.head)를 next에 할당하고 this.head의 값으로 insert 값을 치환.
    if (index === 0) {
      this.head = new Node(data, this.head);
      return;
    }

    const previous = this.getAt(index - 1) || this.getLast();
    const node = new Node(data, previous.next);
    previous.next = node;
  }

  forEach(fn) {
    let node = this.head;
    let counter = 0;

    while (node) {
      fn(node, counter);
      node = node.next;
      counter++;
    }
  }

  *[Symbol.iterator]() {
    let node = this.head;

    while (node) {
      yield node;
      node = node.next;
    }
  }
}

module.exports = { Node, LinkedList };</code></pre>
<h3 id="node">Node</h3>
<h4 id="head--tail">Head &amp; Tail</h4>
<p><img src="https://images.velog.io/images/mame-coder/post/8851593d-697c-4b4e-b96d-dd5ff5d5f6d0/image.png" alt="">
<code>linked list</code>에 속한 <code>node</code>는 기본적으로 <code>reference</code>를 갖는다. 이 <code>node</code>들 중 마지막 값에 해당하여 <code>reference</code>를 갖지 않는 것이 바로 <code>tail</code>이다. 
<code>node</code> 안의 <code>data</code>에는 유효한 값이라면 <code>type</code>을 구분하지 않고 저장할 수 있다.
<img src="https://images.velog.io/images/mame-coder/post/a0506196-853b-4003-9b10-ffb0ba772b42/image.png" alt="">
<code>linked list class</code> 내에 <code>insert</code>, <code>remove</code>, <code>get</code> 등 다양한 method를 작성하여 <code>linked list</code> 내의 <code>node</code>를 자유롭게 편집할 수 있다.
<code>linked list</code>는 단 한 개의 <code>head property</code>만 받는다. 즉, 첫 번째 <code>node</code>만을 인식하고, <code>linked list</code> 안에 현재 <code>node</code>가 몇 개인지, 어떤 <code>data</code>를 담고 있는지 전혀 신경 쓰지 않는다. 따라서 특정한 <code>data</code>를 얻기 위해서는 <code>linked list</code> 전체를 탐색해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택으로 큐 만들기(Create Queue with Stacks)]]></title>
            <link>https://velog.io/@mame-coder/%EC%8A%A4%ED%83%9D%EC%9C%BC%EB%A1%9C-%ED%81%90-%EB%A7%8C%EB%93%A4%EA%B8%B0Create-Queue-with-Stacks</link>
            <guid>https://velog.io/@mame-coder/%EC%8A%A4%ED%83%9D%EC%9C%BC%EB%A1%9C-%ED%81%90-%EB%A7%8C%EB%93%A4%EA%B8%B0Create-Queue-with-Stacks</guid>
            <pubDate>Thu, 24 Feb 2022 06:44:56 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 20. Two Become One</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="solution">Solution</h2>
<pre><code class="language-javascript">const Stack = require(&quot;./stack&quot;);

class Queue {
  // whenever you create an instance of a queue, you will automatically generate two stacks and assign it to this queue class.
  constructor() {
    this.first = new Stack();
    this.second = new Stack();
  }

  add(record) {
    this.first.push(record);
  }

  remove() {
    while (this.first.peek()) {
      this.second.push(this.first.pop());
    }

    const record = this.second.pop();

    while (this.second.peek()) {
      this.first.push(this.second.pop());
    }

    return record;
  }

  peek() {
    while (this.first.peek()) {
      this.second.push(this.first.pop());
    }

    const record = this.second.peek();

    while (this.second.peek()) {
      this.first.push(this.second.pop());
    }

    return record;
  }
}

module.exports = Queue;</code></pre>
<p><img src="https://images.velog.io/images/mame-coder/post/444a10bf-290d-4b51-8949-dfbfe2b57a9e/stack&queue.gif" alt="">
기본적인 작동원리는 위 그림과 같다. <code>선입선출(FIFO)</code>의 원리를 <code>stack</code>에도 적용한다 보면 된다. </p>
<hr>
<hr>
<h2 id="함께-보기">함께 보기</h2>
<p><a href="https://velog.io/@mame-coder/%ED%81%90The-Queue">큐</a>
<a href="https://velog.io/@mame-coder/%ED%81%90-%ED%95%A9%EC%B9%98%EA%B8%B0Queue-Weaving">큐 합치기</a>
<a href="https://velog.io/@mame-coder/%EC%8A%A4%ED%83%9DStacks">스택</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택(Stacks)]]></title>
            <link>https://velog.io/@mame-coder/%EC%8A%A4%ED%83%9DStacks</link>
            <guid>https://velog.io/@mame-coder/%EC%8A%A4%ED%83%9DStacks</guid>
            <pubDate>Thu, 24 Feb 2022 06:05:42 GMT</pubDate>
            <description><![CDATA[<h2 id="references">References</h2>
<p>아래 링크의 강의 중 <code>Section 19. Stack &#39;Em Up With Stacks</code>의 내용을 추려 이번 글을 작성하였습니다.
<a href="https://www.udemy.com/course/coding-interview-bootcamp-algorithms-and-data-structure/">The Coding Interview Bootcamp: Algorithms + Data Structures on Udemy</a></p>
<hr>
<h2 id="solution">Solution</h2>
<pre><code class="language-javascript">class Stack {
  constructor() {
    this.data = [];
  }

  push(record) {
    this.data.push(record);
  }

  pop() {
    return this.data.pop();
  }

  peek() {
    return this.data[this.data.length - 1];
  }
}
// const s = new Stack();
// s.push(1);
// s.push(2);
// s.pop(); // returns 2
// s.pop(); // returns 1</code></pre>
<p><code>stack</code> 역시 <code>data</code>를 저장하는 방식 중의 하나이다. 이전에 살펴본 <a href="https://velog.io/@mame-coder/%ED%81%90The-Queue">Queue</a>와 차이점이 있다면 <code>선입후출(FILO)</code> 구조라는 것이다.
<img src="https://images.velog.io/images/mame-coder/post/30d62708-9828-412a-96a0-0db2ae82c31e/image.png" alt="">
위 그림에서 보듯 들어오기는 <code>A</code>가 먼저 들어오고 나가는 것은 <code>B</code>가 먼저 나간다. <code>push()</code> method로 이전 값 뒤에 새로운 값을 input하고, <code>pop()</code> method로 가장 최근에 들어온 값을 output하는 구조이다.</p>
<hr>
<hr>
<h2 id="함께-보기">함께 보기</h2>
<p><a href="https://velog.io/@mame-coder/%ED%81%90The-Queue">Queue</a></p>
]]></description>
        </item>
    </channel>
</rss>