<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>MOON.DEVELOG</title>
        <link>https://velog.io/</link>
        <description>MOON.DEVLOG</description>
        <lastBuildDate>Mon, 08 Dec 2025 14:42:03 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>MOON.DEVELOG</title>
            <url>https://velog.velcdn.com/images/moon_dev/profile/6bd493c9-da64-4230-a72e-c7b679b44dab/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. MOON.DEVELOG. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/moon_dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 배열의 원소 삭제하기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EC%9B%90%EC%86%8C-%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0-sslauxbs</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EC%9B%90%EC%86%8C-%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0-sslauxbs</guid>
            <pubDate>Mon, 08 Dec 2025 14:42:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181844">배열의 원소 삭제하기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수 배열 <code>arr</code>과 <code>delete_list</code>가 있습니다. <code>arr</code>의 원소 중 <code>delete_list</code>의 원소를 모두 삭제하고 남은 원소들은 기존의 <code>arr</code>에 있던 순서를 유지한 배열을 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 100</li>
<li>1 ≤ <code>arr</code>의 원소 ≤ 1,000</li>
<li><code>arr</code>의 원소는 모두 서로 다릅니다.</li>
<li>1 ≤ <code>delete_list</code>의 길이 ≤ 100</li>
<li>1 ≤ <code>delete_list</code>의 원소 ≤ 1,000</li>
<li><code>delete_list</code>의 원소는 모두 서로 다릅니다.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>delete_list</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[293, 1000, 395, 678, 94]</td>
<td>[94, 777, 104, 1000, 1, 12]</td>
<td>[293, 395, 678]</td>
</tr>
<tr>
<td>[110, 66, 439, 785, 1]</td>
<td>[377, 823, 119, 43]</td>
<td>[110, 66, 439, 785, 1]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번의 <code>arr</code>의 원소 중 1000과 94가 <code>delete_list</code>에 있으므로 이 두 원소를 삭제한 [293, 395, 678]을 return 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>예제 2번의 <code>arr</code>의 원소 중 <code>delete_list</code>에 있는 원소는 없습니다. 따라서 <code>arr</code> 그대로인 [110, 66, 439, 785, 1]을 return 합니다.</li>
</ul>
<hr>
<h2 id="접근-방법">접근 방법</h2>
<p>이 문제는 <code>arr</code> 내부의 원소 중 <code>delete_list</code>에 포함된 값을 제거하고, 나머지는 기존 순서를 유지한 채 반환하는 단순한 필터링 문제다. 핵심은 두 가지로 요약된다.</p>
<ol>
<li>현재 값이 삭제 대상인지 빠르게 판별해야 한다.</li>
<li>삭제 대상이 아니라면 결과 배열에 포함해야 한다.</li>
</ol>
<p>이를 JavaScript에서 구현할 때 가장 적합한 도구는 <code>Set</code>과 <code>Array.prototype.filter</code>이다. 두 개념을 명확히 이해하면 코드가 왜 이러한 구조를 취하는지 자연스럽게 파악된다.</p>
<hr>
<h2 id="set의-필요성과-동작-원리">Set의 필요성과 동작 원리</h2>
<p><code>Set</code>은 중복을 허용하지 않는 데이터 집합을 저장하는 자료구조로, 특정 값이 포함되어 있는지 판별하는 연산이 평균적으로 O(1)의 시간에 수행된다. 배열에서 동일한 작업을 할 경우 <code>includes</code>를 사용해야 하고, 이는 매번 O(n) 탐색이 필요하므로 전체 성능이 저하된다.</p>
<p>이 문제에서는 삭제해야 할 값들을 <code>Set</code>에 담아두고 <code>has</code> 메서드로 빠르게 포함 여부를 확인하는 전략이 가장 적합하다.</p>
<pre><code class="language-jsx">const toDelete = new Set(delete_list);
</code></pre>
<p>위 코드는 삭제 대상 목록을 <code>Set</code>으로 변환한다. 이후 <code>toDelete.has(value)</code>는 <code>value</code>가 삭제 대상에 포함되면 <code>true</code>, 포함되지 않으면 <code>false</code>를 반환한다.</p>
<hr>
<h2 id="filter의-동작-방식">filter의 동작 방식</h2>
<p><code>filter</code>는 배열을 처음부터 끝까지 순회하며, 콜백 함수가 <code>true</code>를 반환할 때만 해당 값을 결과 배열에 포함한다. 원본 배열을 직접 수정하지 않고, 조건을 만족하는 값들만 모아 새로운 배열을 생성한다는 점에서 선언적이고 명료한 방식이다.</p>
<p>형식은 다음과 같다.</p>
<pre><code class="language-jsx">arr.filter(value =&gt; 조건식);
</code></pre>
<p>조건식이 <code>true</code>일 때 <code>value</code>는 유지되고, <code>false</code>일 때는 제거된다.</p>
<p>이 문제에서의 조건은 단순하다.</p>
<blockquote>
<p>&quot;삭제 대상에 포함되어 있지 않은 값만 남긴다.&quot;</p>
</blockquote>
<p>따라서 조건식은 <code>!toDelete.has(value)</code>가 된다.</p>
<hr>
<h2 id="최종-코드">최종 코드</h2>
<pre><code class="language-jsx">function solution(arr, delete_list) {
  const toDelete = new Set(delete_list);
  return arr.filter(value =&gt; !toDelete.has(value));
}
</code></pre>
<hr>
<h2 id="코드-동작-과정">코드 동작 과정</h2>
<p>예제 1을 기준으로 실제 동작을 표로 정리하면 다음과 같다.</p>
<p><code>arr = [293, 1000, 395, 678, 94]</code></p>
<p><code>toDelete = new Set([94, 777, 104, 1000, 1, 12])</code></p>
<table>
<thead>
<tr>
<th>값</th>
<th>toDelete.has(value)</th>
<th>유지 여부</th>
</tr>
</thead>
<tbody><tr>
<td>293</td>
<td>false</td>
<td>유지</td>
</tr>
<tr>
<td>1000</td>
<td>true</td>
<td>제거</td>
</tr>
<tr>
<td>395</td>
<td>false</td>
<td>유지</td>
</tr>
<tr>
<td>678</td>
<td>false</td>
<td>유지</td>
</tr>
<tr>
<td>94</td>
<td>true</td>
<td>제거</td>
</tr>
</tbody></table>
<p>결과는 <code>[293, 395, 678]</code>이 된다.</p>
<hr>
<h2 id="다른-구현-방식과의-비교">다른 구현 방식과의 비교</h2>
<h3 id="1-배열-includes-사용">1. 배열 <code>includes</code> 사용</h3>
<pre><code class="language-jsx">arr.filter(value =&gt; !delete_list.includes(value));
</code></pre>
<p>문제의 입력 규모에서는 정상적으로 동작하지만, 삭제 대상 목록이 커지면 반복적으로 전체 배열을 탐색해야 하므로 효율성이 떨어진다.</p>
<h3 id="2-set-기반-구현">2. Set 기반 구현</h3>
<pre><code class="language-jsx">const toDelete = new Set(delete_list);
arr.filter(value =&gt; !toDelete.has(value));
</code></pre>
<p>삭제 대상 여부를 확인하는 연산이 상수 시간에 이루어지므로 더 안정적이며, 특히 입력 크기가 커지는 환경에서는 필수에 가깝다.</p>
<hr>
<h2 id="정리">정리</h2>
<ul>
<li><code>Set</code>은 삭제 대상 목록을 빠르게 조회하기 위한 최적의 자료구조다.</li>
<li><code>filter</code>는 조건 기반 요소 추출에 적합한 선언적 API다.</li>
<li>이 두 가지를 조합하면 가독성, 성능, 확장성 모두 균형 잡힌 구조를 만들 수 있다.</li>
<li>실무에서도 유지 조건 또는 필터링 조건이 있는 배열 처리에서는 동일한 패턴이 자주 사용된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 문자열로 변환]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C-%EB%B3%80%ED%99%98</guid>
            <pubDate>Sun, 07 Dec 2025 15:40:21 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181845">문자열로 변환</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수 <code>n</code>이 주어질 때, <code>n</code>을 문자열로 변환하여 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>n</code> ≤ 10000</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>n</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>123</td>
<td>&quot;123&quot;</td>
</tr>
<tr>
<td>2573</td>
<td>&quot;2573&quot;</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>123을 문자열로 변환한 &quot;123&quot;을 return합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>2573을 문자열로 변환한 &quot;2573&quot;을 return합니다.</li>
</ul>
<hr>
<h1 id="1-가장-명확한-방법--stringn">1. 가장 명확한 방법 — <code>String(n)</code></h1>
<pre><code class="language-jsx">function solution(n) {
  return String(n);
}</code></pre>
<h3 id="왜-이-방식이-좋은가">왜 이 방식이 좋은가?</h3>
<ul>
<li><strong>의도가 가장 분명하다.</strong> “숫자를 문자열로 변환한다”는 목적이 코드만 보아도 명확하게 드러난다.</li>
<li><strong>암묵적 변환을 피한다.</strong> 협업 환경에서는 암묵적 타입 변환이 버그를 유발할 여지가 있으므로, 명시적 변환이 권장된다.</li>
<li><strong>변환 대상이 무엇이든 안정적이다.</strong> <code>null</code>, <code>undefined</code> 등 특수 값도 명시적으로 문자열로 바뀐다.</li>
</ul>
<hr>
<h1 id="2-템플릿-리터럴-사용--백틱-기반-문자열-결합">2. 템플릿 리터럴 사용 — 백틱 기반 문자열 결합</h1>
<pre><code class="language-jsx">function solution(n) {
  return `${n}`;
}</code></pre>
<h3 id="장점">장점</h3>
<ul>
<li>ES6 이후 가장 많이 사용되는 문자열 생성 방식.</li>
<li>내부적으로 <strong>문자열 연산이 보장</strong>되므로 자연스럽게 문자열 타입 변환이 이루어진다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li><code>&quot;문자열을 만들기 위해 템플릿 문법을 사용한다&quot;</code>는 점에서 약간의 과잉 표현.</li>
<li>목적은 &quot;변환&quot;인데 &quot;포매팅&quot; 문법을 쓴 것처럼 보일 수 있다.</li>
</ul>
<hr>
<h1 id="3-문자열-덧셈--전통적인-방식">3. 문자열 덧셈 — 전통적인 방식</h1>
<pre><code class="language-jsx">function solution(n) {
  return n + &quot;&quot;;
}</code></pre>
<h3 id="평가">평가</h3>
<ul>
<li>자바스크립트 초창기부터 존재하던 방식.</li>
<li><strong>암묵적 타입 변환</strong>에 의존하기 때문에 오늘날에는 선호되지 않는다.</li>
<li>코드 리뷰 시 “의도가 불명확하다”는 지적을 받을 여지가 있다.</li>
</ul>
<hr>
<h1 id="4-tostring-메서드-사용">4. <code>toString()</code> 메서드 사용</h1>
<pre><code class="language-jsx">function solution(n) {
  return n.toString();
}</code></pre>
<h3 id="장점-1">장점</h3>
<ul>
<li>숫자의 고유 메서드이므로 비교적 직관적이다.</li>
</ul>
<h3 id="주의-사항">주의 사항</h3>
<ul>
<li><code>null</code>이나 <code>undefined</code>에 사용하면 에러를 발생시킨다.</li>
<li>이 문제는 입력이 항상 유효하므로 문제는 없지만, <strong>방어적 프로그래밍 관점</strong>에서는 <code>String(n)</code>이 더 안전하다.</li>
</ul>
<hr>
<h1 id="📌-최종-권장-풀이">📌 최종 권장 풀이</h1>
<pre><code class="language-jsx">function solution(n) {
  return String(n);
}</code></pre>
<h3 id="선택-이유">선택 이유</h3>
<ul>
<li>명시적이고 안전하며 협업 환경에서 예측 가능한 패턴.</li>
<li>타입 변환이라는 본래 의도를 가장 직관적으로 드러낸다.<h3 id=""></h3>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 두 수의 합]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%91%90-%EC%88%98%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%91%90-%EC%88%98%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Mon, 01 Dec 2025 15:57:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181846">두 수의 합</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>0 이상의 두 정수가 <strong>문자열</strong> <code>a</code>, <code>b</code>로 주어질 때, <code>a</code> + <code>b</code>의 값을 문자열로 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>a</code>의 길이 ≤ 100,000</li>
<li>1 ≤ <code>b</code>의 길이 ≤ 100,000</li>
<li><code>a</code>와 <code>b</code>는 숫자로만 이루어져 있습니다.</li>
<li><code>a</code>와 <code>b</code>는 정수 0이 아니라면 0으로 시작하지 않습니다.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;582&quot;</td>
<td>&quot;734&quot;</td>
<td>&quot;1316&quot;</td>
</tr>
<tr>
<td>&quot;18446744073709551615&quot;</td>
<td>&quot;287346502836570928366&quot;</td>
<td>&quot;305793246910280479981&quot;</td>
</tr>
<tr>
<td>&quot;0&quot;</td>
<td>&quot;0&quot;</td>
<td>&quot;0&quot;</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번의 <code>a</code>, <code>b</code>는 각각 582, 734이고 582 + 734 = 1316입니다. 따라서 &quot;1316&quot;을 return 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>예제 2번의 <code>a</code>, <code>b</code>는 각각 18446744073709551615, 287346502836570928366이고 18446744073709551615 + 287346502836570928366 = 305793246910280479981입니다. 따라서 &quot;305793246910280479981&quot;을 return 합니다.</li>
</ul>
<p>입출력 예 #3</p>
<ul>
<li>예제 3번의 <code>a</code>, <code>b</code>는 각각 0, 0이고 0 + 0 = 0입니다. 따라서 &quot;0&quot;을 return 합니다.</li>
</ul>
<hr>
<p>문제의 핵심은 <strong>일반 정수 타입으로 표현할 수 없을 만큼 큰 숫자를 문자열 형태로 받아 직접 덧셈 로직을 구현</strong>하는 것이다.</p>
<p>JavaScript의 <code>Number</code> 혹은 <code>BigInt</code>를 쓸 수도 있지만, 이 문제는 <strong>문자열 기반 덧셈 알고리즘을 직접 구현하는 경험</strong>을 요구한다.</p>
<hr>
<h2 id="1-문제의-본질-문자열-기반-수학-연산">1. 문제의 본질: 문자열 기반 수학 연산</h2>
<p>일반 덧셈은 다음의 규칙을 따른다.</p>
<ol>
<li><strong>가장 낮은 자리부터(오른쪽부터) 계산</strong>한다.</li>
<li>각 자리수의 합이 10 이상이면 <strong>올림(carry)</strong> 를 발생시킨다.</li>
<li>모든 자리를 순회한 뒤 마지막에 carry가 남는다면 가장 앞에 추가한다.</li>
</ol>
<p>문자열 덧셈도 동일한 원리에 기반하지만, 차이가 있다.</p>
<ul>
<li>숫자를 배열로 변환하거나 거꾸로 순회해야 한다.</li>
<li>한 문자열의 길이가 더 길 수 있으므로 <strong>두 포인터 방식</strong>이 유용하다.</li>
<li>반복 횟수는 <code>max(a.length, b.length)</code>으로 결정되며, <strong>최대 100,000번</strong>이므로 O(N) 단일 패스로 충분히 빠르다.</li>
</ul>
<hr>
<h2 id="2-기본-알고리즘-two-pointer--carry">2. 기본 알고리즘: Two-Pointer + Carry</h2>
<h3 id="핵심-의사코드">핵심 의사코드</h3>
<ul>
<li><code>i = a.length - 1</code>, <code>j = b.length - 1</code></li>
<li><code>carry = 0</code></li>
<li>while <code>i ≥ 0</code> or <code>j ≥ 0</code> or <code>carry &gt; 0</code><ul>
<li>각 자리 숫자를 더함</li>
<li>carry 업데이트</li>
<li>문자열에 결과 누적</li>
</ul>
</li>
<li>문자열 뒤집기</li>
</ul>
<p>이 구조는 <strong>단일 패스 + 상수 공간의 carry 관리</strong>라는 측면에서 가장 이상적이다.</p>
<hr>
<h2 id="3-javascript-구현--최적화-버전">3. JavaScript 구현 — 최적화 버전</h2>
<pre><code class="language-jsx">function solution(a, b) {
  let i = a.length - 1;
  let j = b.length - 1;
  let carry = 0;
  const result = [];

  while (i &gt;= 0 || j &gt;= 0 || carry &gt; 0) {
    const x = i &gt;= 0 ? a.charCodeAt(i) - 48 : 0;
    const y = j &gt;= 0 ? b.charCodeAt(j) - 48 : 0;

    const sum = x + y + carry;
    result.push(sum % 10);
    carry = Math.floor(sum / 10);

    i--;
    j--;
  }

  return result.reverse().join(&#39;&#39;);
}
</code></pre>
<h3 id="구현-포인트">구현 포인트</h3>
<ul>
<li><strong><code>charCodeAt</code> 기반 숫자 변환</strong>은 문자열 → 숫자 변환 중 가장 빠른 방법 중 하나이다.</li>
<li>결과를 배열에 push한 뒤 마지막에 <code>reverse()</code>하는 방식이 가장 단순하며 성능도 충분히 좋다.</li>
<li>매 반복에서 정수 연산만 수행되므로 O(N) 시간에 안정적으로 동작한다.</li>
</ul>
<hr>
<h2 id="4-대안적-접근법-비교">4. 대안적 접근법 비교</h2>
<h3 id="41-bigint-사용-간단하지만-비권장">4.1 <code>BigInt</code> 사용 (간단하지만 비권장)</h3>
<pre><code class="language-jsx">function solution(a, b) {
  return (BigInt(a) + BigInt(b)).toString();
}
</code></pre>
<h3 id="장점">장점</h3>
<ul>
<li>가장 간단하다.</li>
<li>자바스크립트 내장 기능을 활용해 읽기 쉽다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>문제 취지와 다르다.</li>
<li><strong>메모리 사용량 증가</strong>, 초대형 입력(10⁵ 자리의 문자열)을 <code>BigInt</code>로 변환하는 비용이 매우 크다.</li>
<li>일부 플랫폼에서는 <code>BigInt</code> 연산 overflow나 성능 문제가 발생할 수 있다.</li>
</ul>
<blockquote>
<p>실무에서는 BigInt로 처리하는 것이 이득인 경우도 많지만, 알고리즘 문제에서는 직접 구현이 정답이다.</p>
</blockquote>
<hr>
<h3 id="42-앞에서부터-누적하는-방식-비효율">4.2 앞에서부터 누적하는 방식 (비효율)</h3>
<pre><code class="language-jsx">// 비효율적: 문자열 앞에 추가 → 매 삽입마다 O(n)
result = digit + result;
</code></pre>
<p>이 방식은 <strong>문자열 concat 비용이 누적되어 O(N²)</strong> 로 악화될 수 있으므로 금지해야 한다.</p>
<hr>
<h2 id="5-학습-포인트-정리">5. 학습 포인트 정리</h2>
<h3 id="문자열-기반-수학을-구현할-때-반드시-고려해야-하는-요소">문자열 기반 수학을 구현할 때 반드시 고려해야 하는 요소</h3>
<ul>
<li>자리수 순회는 <strong>오른쪽부터</strong></li>
<li>하위 단계에서 발생하는 <strong>carry는 상위 단계로 전파</strong></li>
<li>문자열 덧셈은 결국 <strong>배열 + reverse()</strong> 로 귀결된다</li>
<li>JavaScript에서 숫자 변환은 <code>charCodeAt</code>이 빠르다</li>
<li>두 포인터 방식은 큰 입력에서도 성능을 보장한다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 0 떼기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-0%EB%96%BC%EA%B8%B0-70h60s65</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-0%EB%96%BC%EA%B8%B0-70h60s65</guid>
            <pubDate>Sun, 30 Nov 2025 10:08:24 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181847">0떼기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수로 이루어진 문자열 <code>n_str</code>이 주어질 때, <code>n_str</code>의 가장 왼쪽에 처음으로 등장하는 0들을 뗀 문자열을 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>2 ≤ <code>n_str</code> ≤ 10</li>
<li><code>n_str</code>이 &quot;0&quot;으로만 이루어진 경우는 없습니다.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>n_str</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;0010&quot;</td>
<td>&quot;10&quot;</td>
</tr>
<tr>
<td>&quot;854020&quot;</td>
<td>&quot;854020&quot;</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>&quot;0010&quot;의 가장 왼쪽에 연속으로 등장하는 &quot;0&quot;을 모두 제거하면 &quot;10&quot;이 됩니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>&quot;854020&quot;는 가장 왼쪽에 0이 없으므로 &quot;854020&quot;을 return합니다.</li>
</ul>
<hr>
<h2 id="1-문제-정리">1. 문제 정리</h2>
<ul>
<li>입력: <code>&quot;0010&quot;</code>, <code>&quot;854020&quot;</code> 같은 <strong>정수로 이루어진 문자열</strong> <code>n_str</code></li>
<li>해야 할 일:<ul>
<li>문자열 <strong>왼쪽에서부터 연속해서 등장하는 <code>&#39;0&#39;</code>들을 전부 제거</strong></li>
<li>단, 중간이나 끝에 있는 <code>0</code>은 유지</li>
</ul>
</li>
<li>보장 조건:<ul>
<li>길이는 2 이상 10 이하</li>
<li><code>&quot;0&quot;</code>으로만 이루어진 문자열은 없다 → 결과 문자열은 반드시 비어있지 않다</li>
</ul>
</li>
</ul>
<p>즉, <strong>“첫 번째 0이 아닌 문자가 나올 때까지의 0들을 제거하고, 그 뒤는 그대로 둔다”</strong>는 문제다.</p>
<hr>
<h2 id="2-권장-풀이--정규식-replace-사용">2. 권장 풀이 — 정규식 <code>replace</code> 사용</h2>
<p>가장 간결하면서도 의도가 잘 드러나는 방식은 <strong>정규식을 이용한 치환</strong>이다.</p>
<pre><code class="language-jsx">function solution(n_str) {
  return n_str.replace(/^0+/, &#39;&#39;);
}
</code></pre>
<h3 id="코드-해설">코드 해설</h3>
<ul>
<li><code>^0+</code> 정규식의 의미<ul>
<li><code>^</code> : 문자열의 <strong>시작</strong>을 의미한다.</li>
<li><code>0+</code> : 문자 <code>&#39;0&#39;</code>이 <strong>1개 이상 연속</strong>해서 나오는 구간을 의미한다.</li>
</ul>
</li>
<li><code>n_str.replace(/^0+/, &#39;&#39;)</code><ul>
<li>문자열 <strong>시작 부분에서 연속된 0들을 찾아서</strong></li>
<li><strong>빈 문자열로 치환</strong> → 즉, 제거한다.</li>
</ul>
</li>
</ul>
<h3 id="예시-동작">예시 동작</h3>
<ul>
<li><code>&quot;0010&quot;.replace(/^0+/, &#39;&#39;)</code> → <code>&quot;10&quot;</code></li>
<li><code>&quot;854020&quot;.replace(/^0+/, &#39;&#39;)</code> → <code>&quot;854020&quot;</code> (앞에 0이 없으므로 변경 없음)</li>
<li><code>&quot;00012300&quot;.replace(/^0+/, &#39;&#39;)</code> → <code>&quot;12300&quot;</code> (맨 앞 0만 제거, 뒤의 <code>00</code>은 유지)</li>
</ul>
<h3 id="왜-이-풀이를-1순위로-추천하는가">왜 이 풀이를 1순위로 추천하는가?</h3>
<ol>
<li><p><strong>의도가 선언적으로 드러난다</strong></p>
<p> “문자열 시작(<code>^</code>)에서 0들을 제거하겠다”라는 의도가 코드 레벨에서 바로 보인다.</p>
</li>
<li><p>구현이 매우 간단하고, 에지 케이스까지 자연스럽게 처리한다.</p>
</li>
<li><p>문제의 요구사항(앞쪽 0만 제거)에 정확히 대응하는 패턴이다.</p>
</li>
</ol>
<p>실무에서도 정규식 기반의 <code>replace</code>는 <strong>입력 정제, 포맷팅, 마스킹</strong> 등에 매우 자주 쓰이는 패턴이므로 익숙해질 가치가 크다.</p>
<hr>
<h2 id="3-대안-풀이-1--인덱스를-직접-찾는-방식">3. 대안 풀이 1 — 인덱스를 직접 찾는 방식</h2>
<p>정규식을 쓰지 않고, <strong>문자열을 직접 순회</strong>하며 첫 번째 0이 아닌 문자의 위치를 찾아 <code>slice</code> 하는 방식도 있다.</p>
<pre><code class="language-jsx">function solution(n_str) {
  let index = 0;

  while (index &lt; n_str.length &amp;&amp; n_str[index] === &#39;0&#39;) {
    index++;
  }

  return n_str.slice(index);
}
</code></pre>
<h3 id="코드-해설-1">코드 해설</h3>
<ol>
<li><code>index</code>를 0부터 시작한다.</li>
<li>문자열을 왼쪽에서 오른쪽으로 보면서:<ul>
<li>현재 문자가 <code>&#39;0&#39;</code>이면 <code>index++</code></li>
<li><code>&#39;0&#39;</code>이 아닌 문자를 만나면 반복 종료</li>
</ul>
</li>
<li><code>n_str.slice(index)</code>로 해당 위치부터 끝까지 잘라서 반환</li>
</ol>
<h3 id="장점">장점</h3>
<ul>
<li>동작 방식이 매우 직관적이다.</li>
<li>정규식을 모르는 사람에게도 쉽게 설명 가능하다.</li>
<li>시간 복잡도는 <code>O(n)</code> → 이 문제 크기(최대 10)에서는 의미 없지만, 길이가 매우 길어져도 효율적이다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li>같은 기능을 수행하는데 코드 라인이 늘어난다.</li>
<li>정규식 풀이에 비해 “패턴 기반 문자열 처리”라는 관점에서는 덜 선언적이다.</li>
</ul>
<p>정규식을 팀에서 선호하지 않거나, <strong>정규식 사용이 부담되는 초기 학습 단계</strong>라면 이 방법도 좋은 선택이다.</p>
<hr>
<h2 id="4-대안-풀이-2--숫자로-변환-후-다시-문자열로">4. 대안 풀이 2 — 숫자로 변환 후 다시 문자열로</h2>
<p>이 문제는 입력이 “정수로 이루어진 문자열”이며, <code>&quot;0&quot;</code>으로만 이루어진 문자열은 주어지지 않는다고 명시되어 있다.</p>
<p>따라서 <strong>숫자로 한 번 변환했다가 다시 문자열로 바꾸는 방식</strong>도 동작한다.</p>
<pre><code class="language-jsx">function solution(n_str) {
  return String(Number(n_str));
}
</code></pre>
<p>혹은:</p>
<pre><code class="language-jsx">function solution(n_str) {
  return String(parseInt(n_str, 10));
}
</code></pre>
<h3 id="동작-원리">동작 원리</h3>
<ul>
<li><code>Number(&quot;0010&quot;)</code> → <code>10</code> (숫자 타입)</li>
<li><code>String(10)</code> → <code>&quot;10&quot;</code></li>
</ul>
<p>즉, 숫자 변환 과정에서 자동으로 <strong>선행 0들이 제거</strong>된다.</p>
<h3 id="이-방식의-문제점-왜-보조적-방법인가">이 방식의 문제점 (왜 “보조적” 방법인가?)</h3>
<ol>
<li><strong>문제의 요구는 “문자열 처리”인데, 중간에 불필요하게 숫자 타입으로 바꾼다.</strong><ul>
<li>문자열 포맷을 유지해야 하는 문제(예: 전화번호, 카드번호 등)에서는 위험할 수 있다.</li>
</ul>
</li>
<li>향후 문제 확장 시, 숫자 범위가 커지면 <code>Number</code>의 <strong>정확도 문제</strong>(IEEE 754, <code>2^53 - 1</code> 초과)가 생길 수 있다.</li>
<li><code>&quot;0000000007&quot;</code> 같은 값을 BigInt나 문자열 그대로 다뤄야 하는 케이스에선 부적절하다.</li>
</ol>
<blockquote>
<p>이 문제의 제한(길이 ≤ 10, 모두 정수 문자열)에서는 정상적으로 동작하지만,</p>
<p><strong>타입 변환을 로직으로 쓰는 패턴은 “습관”으로 가져가기엔 위험</strong>하다는 점을 인지하는 것이 중요하다.</p>
</blockquote>
<hr>
<h2 id="5-세-가지-접근-방식-비교">5. 세 가지 접근 방식 비교</h2>
<table>
<thead>
<tr>
<th>접근</th>
<th>예시 코드</th>
<th>장점</th>
<th>단점</th>
<th>실무에서의 위치</th>
</tr>
</thead>
<tbody><tr>
<td>정규식 <code>replace</code></td>
<td><code>n_str.replace(/^0+/, &#39;&#39;)</code></td>
<td>선언적, 간결, 의도 명확</td>
<td>정규식 문법 이해 필요</td>
<td>문자열 전처리의 주력 패턴</td>
</tr>
<tr>
<td>인덱스 스캔</td>
<td><code>while (n_str[i] === &#39;0&#39;) i++</code></td>
<td>구현 과정이 직관적</td>
<td>코드가 다소 장황</td>
<td>정규식 기피 시 대안</td>
</tr>
<tr>
<td>숫자 변환 후 문자열</td>
<td><code>String(Number(n_str))</code></td>
<td>코드 짧고 깔끔</td>
<td>의미적으론 “숫자 변환”이지 “문자열 처리”가 아님</td>
<td>제한된 상황에서만 사용 권장</td>
</tr>
</tbody></table>
<hr>
<h2 id="6-문제-확장변형-시-고려할-포인트">6. 문제 확장/변형 시 고려할 포인트</h2>
<p>실무적인 관점에서 이 문제를 확장하면 다음과 같은 질문들이 생긴다.</p>
<ol>
<li><p><strong><code>&quot;0&quot;</code>으로만 이루어진 문자열이 들어올 수도 있다면?</strong></p>
<ul>
<li>예: <code>&quot;0000&quot;</code> → 어떤 결과를 원할 것인가? <code>&quot;0&quot;</code>인지, <code>&quot;&quot;</code>인지?</li>
<li>일반적으로는 <code>&quot;0&quot;</code>으로 normalize(정규화)하는 편이 자연스럽다.</li>
</ul>
</li>
<li><p><strong>길이가 매우 긴 숫자 문자열 (예: 1000자리) 이라면?</strong></p>
<ul>
<li><code>Number</code>로 변환하는 방식은 정확도를 잃는다.</li>
<li>이럴 때는 <strong>무조건 문자열 기반 처리(정규식 또는 인덱스)</strong>를 사용해야 한다.</li>
</ul>
</li>
<li><p><strong>중간의 0도 제거할 것인가, 앞부분만 제거할 것인가?</strong></p>
<ul>
<li><p>이 문제는 “앞부분만” 제거이므로, 정규식에서도 <code>^</code>를 쓰는 것이 중요하다.</p>
<p>  (<code>/0+/g</code>처럼 전체에서 0을 제거하면 완전히 다른 동작을 한다.)</p>
</li>
</ul>
</li>
</ol>
<p>이런 고민을 통해 “현재 제약 조건에서 왜 이 풀이가 맞는지”뿐 아니라,</p>
<p>“제약이 바뀌면 어느 지점에서 깨지는지”까지 생각하는 습관이 실무에서 큰 힘이 된다.</p>
<hr>
<h2 id="7-최종-정리">7. 최종 정리</h2>
<p>이 문제에 대한 <strong>가장 추천하는 풀이</strong>는 다음과 같다.</p>
<pre><code class="language-jsx">function solution(n_str) {
  return n_str.replace(/^0+/, &#39;&#39;);
}
</code></pre>
<ul>
<li>정규식으로 <strong>“문자열 시작 지점의 연속된 0”만 제거</strong>한다.</li>
<li>문제의 요구사항과 정확히 일치하며, 확장성·가독성 측면에서도 우수하다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 문자열을 정수로 변환하기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-%EC%A0%95%EC%88%98%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-%EC%A0%95%EC%88%98%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 30 Nov 2025 10:05:43 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181848">문자열을 정수로 변환하기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>숫자로만 이루어진 문자열 <code>n_str</code>이 주어질 때, <code>n_str</code>을 정수로 변환하여 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>n_str</code> ≤ 5</li>
<li><code>n_str</code>은 0부터 9까지의 정수 문자로만 이루어져 있습니다.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>n_str</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;10&quot;</td>
<td>10</td>
</tr>
<tr>
<td>&quot;8542&quot;</td>
<td>8542</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>&quot;10&quot;을 정수로 바꾸면 10입니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>&quot;8542&quot;를 정수로 바꾸면 8542입니다.</li>
</ul>
<hr>
<h2 id="1-문제-핵심-정리">1. 문제 핵심 정리</h2>
<ul>
<li>입력: <code>&quot;8542&quot;</code>처럼 <strong>숫자로만 이루어진 문자열</strong></li>
<li>출력: <strong>정수 타입</strong></li>
<li>제약이 작기 때문에 성능은 모든 방식이 충분하다.</li>
<li>하지만 JavaScript의 특성상 “문자열을 숫자로 바꾸는 다양한 방식”의 차이를 이해하는 것이 학습의 핵심이다.</li>
</ul>
<hr>
<h2 id="2-권장-풀이--number-사용">2. 권장 풀이 — <code>Number()</code> 사용</h2>
<pre><code class="language-jsx">function solution(n_str) {
  return Number(n_str);
}
</code></pre>
<h3 id="왜-number인가">왜 <code>Number()</code>인가?</h3>
<ul>
<li>명시적 타입 변환(explicit coercion) 함수이며, <strong>가장 의도가 명확한 방식</strong>이다.</li>
<li>JavaScript 엔진이 문자열을 정수/실수 모두 포함한 숫자로 정확하게 변환해준다.</li>
<li><code>&quot;0012&quot;</code>와 같이 앞자리 0이 포함되어도 정상 동작한다.</li>
<li><code>&quot;10e2&quot;</code>(지수 표기), <code>&quot; 42 &quot;</code>(공백 포함)도 올바르게 처리가능하지만, 이번 문제에서는 입력 범위가 좁아 영향을 주지 않는다.</li>
</ul>
<blockquote>
<p>실무 기준</p>
<p>API 파라미터, 환경 변수(<code>process.env.*</code>), 쿼리 스트링 파싱 등에서 가장 일반적으로 사용되는 방법이다.</p>
<p>명확한 의도 표출 + 예측 가능한 동작 = 협업 환경에서 가장 안전하다.</p>
</blockquote>
<hr>
<h2 id="3-대안적-풀이-상황에-따라-유용">3. 대안적 풀이 (상황에 따라 유용)</h2>
<h3 id="31-parseint">3.1 <code>parseInt</code></h3>
<pre><code class="language-jsx">function solution(n_str) {
  return parseInt(n_str, 10);
}
</code></pre>
<h3 id="특징">특징</h3>
<ul>
<li>문자열을 정수로 변환.</li>
<li>두 번째 인자로 <code>10</code>을 명시하면 예상치 못한 진법 문제를 예방할 수 있다.</li>
<li>숫자가 아닌 문자를 만나면 변환을 중단한다. (<code>&quot;10px&quot;</code> → <code>10</code>)</li>
</ul>
<h3 id="이-문제에서는-왜-굳이-사용할-필요가-없는가">이 문제에서는 왜 굳이 사용할 필요가 없는가?</h3>
<ul>
<li>입력값이 오로지 숫자로만 이루어져 있어 <strong><code>Number()</code>와 차이가 없다</strong>.</li>
<li>하지만 <code>parseInt</code>는 &quot;정수 변환&quot;이라는 의미가 강해 실수를 허용하지 않는다.</li>
</ul>
<hr>
<h3 id="32-단항-연산자-">3.2 단항 연산자 <code>+</code></h3>
<pre><code class="language-jsx">function solution(n_str) {
  return +n_str;
}
</code></pre>
<h3 id="장점">장점</h3>
<ul>
<li>매우 짧고 빠르다.</li>
<li>암묵적 타입 변환을 수행한다.</li>
</ul>
<h3 id="단점">단점</h3>
<ul>
<li><p><strong>의도가 즉시 드러나지 않는다.</strong></p>
<p>  특히 JS 초중급 개발자에게는 가독성이 좋지 않다.</p>
</li>
<li><p><code>&quot; &quot;</code>(공백), <code>&quot; 42 &quot;</code> 등의 값 처리 시 동작이 명확히 보이지 않는다.</p>
</li>
</ul>
<blockquote>
<p>실무에서는 팀 규칙에 따라 사용 여부가 달라진다.</p>
<p>퍼포먼스가 중요한 로우 레벨 로직에서는 사용되지만, 일반적인 웹백엔드/프론트 코드에서는 잘 쓰지 않는다.</p>
</blockquote>
<hr>
<h2 id="4-비추천-풀이">4. 비추천 풀이</h2>
<h3 id="41-parsefloat-사용">4.1 <code>parseFloat</code> 사용</h3>
<p>입력이 정수 문자열이라는 점에서 불필요하다.</p>
<h3 id="42-n_str-비트-연산자-활용">4.2 <code>~~n_str</code> (비트 연산자 활용)</h3>
<ul>
<li>빠르긴 하지만 32비트 정수 범위 제한, 부호 처리 등 부작용이 많다.</li>
<li><strong>문제에서 요구하는 범위에서는 동작하지만</strong> 확장성·가독성 측면에서 배제해야 한다.</li>
</ul>
<hr>
<h2 id="5-전체-비교">5. 전체 비교</h2>
<table>
<thead>
<tr>
<th>방식</th>
<th>의도 명확성</th>
<th>확장성</th>
<th>가독성</th>
<th>비고</th>
</tr>
</thead>
<tbody><tr>
<td><code>Number()</code></td>
<td>⭐⭐⭐⭐⭐</td>
<td>⭐⭐⭐⭐⭐</td>
<td>⭐⭐⭐⭐⭐</td>
<td>가장 권장되는 방식</td>
</tr>
<tr>
<td><code>parseInt(n, 10)</code></td>
<td>⭐⭐⭐⭐</td>
<td>⭐⭐⭐⭐</td>
<td>⭐⭐⭐⭐</td>
<td>정수-only 상황에서 유용</td>
</tr>
<tr>
<td><code>+n</code></td>
<td>⭐⭐⭐</td>
<td>⭐⭐⭐</td>
<td>⭐⭐</td>
<td>아주 짧지만 의도가 모호함</td>
</tr>
<tr>
<td><code>~~n</code></td>
<td>⭐</td>
<td>⭐</td>
<td>⭐</td>
<td>비트 연산 기반 트릭, 실무 비추천</td>
</tr>
</tbody></table>
<hr>
<h2 id="6-예외-케이스-관점-문제를-확장한다면">6. 예외 케이스 관점 (문제를 확장한다면)</h2>
<p>이번 문제는 숫자만 주어지지만, 실제 서비스에서는 다음 케이스도 고려해야 한다.</p>
<ol>
<li><code>&quot;0012&quot;</code> → 앞자리 0</li>
<li><code>&quot; 42 &quot;</code> → 공백 포함 입력</li>
<li><code>&quot;10px&quot;</code> → 숫자 뒤 문자열 포함</li>
<li><code>&quot;&quot;</code> → 빈 문자열</li>
<li><code>&quot;1e3&quot;</code> → 지수 표기</li>
<li><code>&quot;Infinity&quot;</code> → 무한대</li>
<li><code>&quot;0000000000000000000001&quot;</code> → 매우 긴 숫자 (BigInt 고려)</li>
</ol>
<p>입력 정제와 숫자 변환 정책이 리스크를 줄이는 핵심이다.</p>
<hr>
<h2 id="7-결론-및-학습-포인트">7. 결론 및 학습 포인트</h2>
<ul>
<li>이 문제는 단순하지만, <strong>JavaScript의 타입 변환 전략을 이해하는 좋은 출발점</strong>이다.</li>
<li>실무에서는 <strong>명시적 타입 변환</strong>을 사용하여 코드 의도를 분명히 하는 것이 중요하다.</li>
<li>특히 API 개발 시, 숫자·문자열 변환 정책을 일관되게 관리해야 협업 생산성이 올라간다.</li>
</ul>
<p><strong>최종 권장 코드:</strong></p>
<pre><code class="language-jsx">function solution(n_str) {
  return Number(n_str);
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 문자열 정수의 합]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%A0%95%EC%88%98%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%A0%95%EC%88%98%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Thu, 27 Nov 2025 15:22:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181849">문자열 정수의 합</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>한 자리 정수로 이루어진 문자열 <code>num_str</code>이 주어질 때, 각 자리수의 합을 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>3 ≤ <code>num_str</code> ≤ 100</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>num_str</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;123456789&quot;</td>
<td>45</td>
</tr>
<tr>
<td>&quot;1000000&quot;</td>
<td>1</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>문자열 안의 모든 숫자를 더하면 45가 됩니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>문자열 안의 모든 숫자를 더하면 1이 됩니다.</li>
</ul>
<hr>
<h2 id="코드">코드</h2>
<pre><code class="language-jsx">function solution(num_str) {
  return num_str.split(&quot;&quot;).reduce((acc, curr) =&gt; acc + Number(curr), 0);
}

console.log(solution(&quot;123456789&quot;)); // 45
console.log(solution(&quot;1000000&quot;));   // 1
</code></pre>
<hr>
<h2 id="코드-설명">코드 설명</h2>
<p><code>num_str</code>을 <code>split(&quot;&quot;)</code>을 사용해 한 글자씩 분리한 배열로 변환한 뒤,</p>
<p><code>reduce()</code>를 활용하여 각 요소를 <code>Number()</code>로 형변환하면서 누적해 합을 계산하는 방식입니다.</p>
<p>핵심 흐름</p>
<p><code>&quot;1234&quot;</code> → <code>[&quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;]</code> → <code>1 + 2 + 3 + 4 = 10</code></p>
<p>사용된 주요 메서드</p>
<table>
<thead>
<tr>
<th>코드</th>
<th>역할</th>
</tr>
</thead>
<tbody><tr>
<td><code>split(&quot;&quot;)</code></td>
<td>문자열을 한 글자씩 배열로 변환</td>
</tr>
<tr>
<td><code>reduce()</code></td>
<td>배열 요소를 순회하며 누적 계산 수행</td>
</tr>
<tr>
<td><code>Number()</code></td>
<td>문자형 숫자를 숫자로 변환</td>
</tr>
</tbody></table>
<hr>
<h2 id="다른-풀이-방법">다른 풀이 방법</h2>
<h3 id="1-for-of-반복문-사용">1) <code>for-of</code> 반복문 사용</h3>
<pre><code class="language-jsx">function solution(num_str) {
  let sum = 0;
  for (let n of num_str) sum += Number(n);
  return sum;
}
</code></pre>
<h3 id="2-전개-연산자--reduce">2) 전개 연산자 + <code>reduce()</code></h3>
<pre><code class="language-jsx">const solution = num_str =&gt;
  [...num_str].reduce((a, c) =&gt; a + +c, 0);
</code></pre>
<h3 id="3-arrayfrom-활용">3) <code>Array.from()</code> 활용</h3>
<pre><code class="language-jsx">function solution(num_str) {
  return Array.from(num_str, Number).reduce((a, c) =&gt; a + c, 0);
}
</code></pre>
<hr>
<h2 id="추가-내용">추가 내용</h2>
<h3 id="1-split-의-장점">1. <code>split(&quot;&quot;)</code> 의 장점</h3>
<p>문자열을 전개하는 방식은 여러 가지가 있습니다.</p>
<table>
<thead>
<tr>
<th>방식</th>
<th>결과</th>
<th>시간/메모리 복잡도</th>
<th>비고</th>
</tr>
</thead>
<tbody><tr>
<td><code>split(&quot;&quot;)</code></td>
<td>새 배열 생성</td>
<td>O(n)</td>
<td>문자열 → 배열 명시적 변환</td>
</tr>
<tr>
<td><code>[...num_str]</code></td>
<td>새 배열 생성</td>
<td>O(n)</td>
<td>내부적으로 spread 연산은 iterator 기반</td>
</tr>
<tr>
<td><code>Array.from(num_str)</code></td>
<td>새 배열 생성</td>
<td>O(n)</td>
<td>mapping 콜백 활용 가능</td>
</tr>
<tr>
<td><code>for-of</code> 반복</td>
<td>배열 생성 없이 순회</td>
<td>O(n)</td>
<td>가장 메모리 효율적</td>
</tr>
</tbody></table>
<p>즉, <strong>split은 구현은 간단하지만 메모리 할당이 추가</strong>됩니다.</p>
<blockquote>
<p>문자열이 매우 길거나 메모리 최적화가 중요하다면</p>
<p><code>for-of</code> 방식이 더 효율적입니다.</p>
</blockquote>
<hr>
<h3 id="2-reduce를-사용하는-이유">2. <code>reduce()</code>를 사용하는 이유</h3>
<table>
<thead>
<tr>
<th>비교</th>
<th><code>for</code> 반복문</th>
<th><code>reduce()</code></th>
</tr>
</thead>
<tbody><tr>
<td>구현</td>
<td>장황해짐</td>
<td>한 줄에 표현 가능</td>
</tr>
<tr>
<td>선언형/가독성</td>
<td>로직이 명령형</td>
<td><strong>합을 구한다는 목적이 명확</strong></td>
</tr>
<tr>
<td>부작용 위험</td>
<td>변수 노출</td>
<td>내부 스코프에서 안전하게 처리</td>
</tr>
</tbody></table>
<p>즉, reduce는 <strong>의도를 드러내는 함수형 코드</strong>입니다.</p>
<blockquote>
<p>합을 구하는 상황에서 reduce는 정답에 가깝다.</p>
</blockquote>
<hr>
<h3 id="3-numbercurr-vs-parseintcurr-vs-curr">3. <code>Number(curr)</code> vs <code>parseInt(curr)</code> vs <code>+curr</code></h3>
<table>
<thead>
<tr>
<th>방식</th>
<th>장점</th>
<th>단점</th>
</tr>
</thead>
<tbody><tr>
<td><code>Number(curr)</code></td>
<td>타입 명확</td>
<td>다소 길다</td>
</tr>
<tr>
<td><code>parseInt(curr)</code></td>
<td>유연함</td>
<td>문자 포함 시 오해 가능</td>
</tr>
<tr>
<td><code>+curr</code></td>
<td>가장 짧음</td>
<td>초보자에게 가독성 떨어짐</td>
</tr>
</tbody></table>
<p>예시:</p>
<pre><code class="language-jsx">parseInt(&quot;08px&quot;) // 8 ← 좋은 결과인가?
Number(&quot;08px&quot;)   // NaN ← 에러를 명확히 드러냄
</code></pre>
<blockquote>
<p>에러를 감추지 않는 것이 더 안전</p>
</blockquote>
<p>그래서 <code>Number()</code> 선택도 충분한 이유가 존재합니다.</p>
<hr>
<h2 id="다른-풀이와-문제점-비교">다른 풀이와 문제점 비교</h2>
<h3 id="for-of-방식-메모리-효율-최고">for-of 방식 (메모리 효율 최고)</h3>
<pre><code class="language-jsx">function solution(num_str) {
  let sum = 0;
  for (const c of num_str) sum += Number(c);
  return sum;
}
</code></pre>
<ul>
<li>장점: 불필요한 중간 배열 생성 없음</li>
<li>단점: 함수형 의도가 약해짐</li>
</ul>
<hr>
<h3 id="reduce--spread-방식">reduce + spread 방식</h3>
<pre><code class="language-jsx">[...num_str].reduce(...)
</code></pre>
<ul>
<li>가독성 좋음</li>
<li>하지만 <strong>문자열 Iterator → 배열 복사 추가 비용</strong></li>
</ul>
<hr>
<h3 id="arrayfrom-방식">Array.from 방식</h3>
<pre><code class="language-jsx">Array.from(num_str, Number)
</code></pre>
<ul>
<li>문자 → 숫자 mapping이 한 번에 처리됨</li>
<li>하지만 Array.from 자체가 오버헤드가 있음</li>
</ul>
<hr>
<h2 id="어떤-방식이-좋은가">어떤 방식이 “좋은가”?</h2>
<table>
<thead>
<tr>
<th>목적 기준</th>
<th>추천 풀이</th>
</tr>
</thead>
<tbody><tr>
<td>가장 직관적이고 가독성 높은 코드</td>
<td><code>split(&quot;&quot;) + reduce()</code></td>
</tr>
<tr>
<td>메모리 효율 우선</td>
<td><code>for-of</code></td>
</tr>
<tr>
<td>함수형으로 끝까지 가고 싶을 때</td>
<td><code>Array.from()</code></td>
</tr>
</tbody></table>
<p>즉, 현재 문제의 스케일에서는 <strong>가독성과 의도 투명성이 우선 → reduce 기반 풀이가 최선</strong></p>
<hr>
<h2 id="확장-상황을-생각해보자">확장 상황을 생각해보자</h2>
<table>
<thead>
<tr>
<th>확장 사례</th>
<th>추가로 고려해야 할 문제</th>
</tr>
</thead>
<tbody><tr>
<td>문자열 길이 수천~수백만</td>
<td>GC 부담, 메모리 효율 고려</td>
</tr>
<tr>
<td>음수 포함</td>
<td>입력 검증 로직 필요</td>
</tr>
<tr>
<td>숫자가 아닌 문자 포함</td>
<td>예외 처리 필수</td>
</tr>
<tr>
<td>BigInt 범위</td>
<td>기본 정수 연산 불가 →</td>
</tr>
</tbody></table>
<p>예: 1000자리 초과 숫자 → <code>bigint</code> 또는 직접 자리수 연산</p>
<hr>
<h2 id="결론">결론</h2>
<p><strong>좋은 코드는 단순하게 보이지만 내부적으로 많은 트레이드오프를 고려한 결과입니다.</strong></p>
<ul>
<li><p>왜 reduce인가?</p>
<p>  → &quot;합을 구한다&quot;는 목적과 가장 직결되므로</p>
</li>
<li><p>왜 Number인가?</p>
<p>  → 실패 시 오류를 숨기지 않기 때문</p>
</li>
<li><p>왜 split인가?</p>
<p>  → 명확하고 직관적인 문자열 처리</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 정수 부분]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EC%A0%95%EC%88%98-%EB%B6%80%EB%B6%84</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EC%A0%95%EC%88%98-%EB%B6%80%EB%B6%84</guid>
            <pubDate>Wed, 26 Nov 2025 15:37:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181850">정수 부분</a></p>
</blockquote>
<h2 id="문제-설명"><strong>문제 설명</strong></h2>
<p>실수 <code>flo</code>가 매개 변수로 주어질 때, <code>flo</code>의 정수 부분을 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>0 ≤ <code>flo</code> ≤ 100</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>flo</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>1.42</td>
<td>1</td>
</tr>
<tr>
<td>69.32</td>
<td>69</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>1.42의 정수 부분은 1입니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>69.32의 정수 부분은 69입니다.</li>
</ul>
<hr>
<h2 id="코드">코드</h2>
<pre><code class="language-jsx">function solution(flo) {
    return parseInt(flo);
}</code></pre>
<hr>
<h3 id="설명"><strong>설명</strong></h3>
<ul>
<li><code>Math.floor()</code> 함수는 <strong>주어진 실수의 소수점 이하를 버리고 가장 가까운 정수(작거나 같은 정수)</strong> 를 반환합니다.<ul>
<li>예: <code>Math.floor(1.42)</code> → 1</li>
<li>예: <code>Math.floor(69.32)</code> → 69</li>
</ul>
</li>
</ul>
<h3 id="다른-방법들-참고용"><strong>다른 방법들 (참고용)</strong></h3>
<pre><code class="language-jsx">// 1. 비트 연산자 (소수점 이하 제거)
function solution(flo) {
    return flo | 0;
}

// 2. parseInt 사용
function solution(flo) {
    return parseInt(flo);
}</code></pre>
<p>하지만 위 두 방법은 <strong>양수에서는 문제 없지만</strong>, <strong>음수가 들어올 수 있는 일반적인 경우</strong>에는 <code>Math.floor()</code>가 더 정확하고 안전합니다.</p>
<p>현재 문제의 제한사항에선 <code>flo &gt;= 0</code>이기 때문에 모두 사용 가능하지만, 가장 명확한 방법은 <code>Math.floor()</code>입니다.</p>
<hr>
<h3 id="mathfloor-vs-parseint-vs-비트-연산--0"><strong><code>Math.floor()</code> vs <code>parseInt()</code> vs <code>비트 연산 (| 0)</code></strong></h3>
<pre><code class="language-jsx">const num = -1.9;</code></pre>
<h3 id="1-mathfloornum"><strong>1. <code>Math.floor(num)</code></strong></h3>
<pre><code class="language-jsx">Math.floor(-1.9); // ➜ -2</code></pre>
<ul>
<li><strong>설명</strong>: 소수점을 버리고, <strong>더 작은 쪽 정수로 내림</strong> (즉, -1.9 → -2)</li>
</ul>
<h3 id="2-parseintnum"><strong>2. <code>parseInt(num)</code></strong></h3>
<pre><code>parseInt(-1.9); // ➜ -1</code></pre><ul>
<li><strong>설명</strong>: 문자열로 변환된 수에서 소수점 앞까지만 해석 → 실제로는 <strong>문자열 파싱 동작</strong></li>
<li>⚠️ <strong>정확한 내림이 아님</strong> — 예상과 다르게 작동할 수 있음</li>
</ul>
<h3 id="3-num--0--비트-연산"><strong>3. <code>num | 0</code>  (비트 연산)</strong></h3>
<pre><code>-1.9 | 0; // ➜ -1</code></pre><ul>
<li><strong>설명</strong>: 비트 연산자 사용 시 소수점 이하 버림 <strong>(정수로 강제 변환)</strong></li>
<li>그러나 결과는 <strong>0 쪽으로 내림</strong> ⇒ -1.9 → -1</li>
</ul>
<h3 id="결론-mathfloor-가-더-정확하고-안전한-이유"><strong>결론: <code>Math.floor()</code> 가 더 정확하고 안전한 이유</strong></h3>
<ul>
<li>Math.floor()는 <strong>항상 “작거나 같은 정수”로 내림</strong>하여 수학적으로 가장 정확한 <strong>내림 함수</strong>입니다.</li>
<li>반면, parseInt()나 | 0은 양수에는 같게 동작하지만, <strong>음수에서는 “0 방향”으로 내림</strong>하여 예기치 않은 결과를 줄 수 있습니다.</li>
</ul>
<hr>
<h2 id="👇-정리"><strong>👇 정리</strong></h2>
<table>
<thead>
<tr>
<th><strong>함수</strong></th>
<th>-1.9 <strong>결과</strong></th>
<th><strong>설명</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Math.floor</td>
<td>-2</td>
<td>작거나 같은 정수로 내림</td>
</tr>
<tr>
<td>parseInt</td>
<td>-1</td>
<td>문자열 파싱으로 소수점 제거</td>
</tr>
<tr>
<td>`</td>
<td>0`</td>
<td>-1</td>
</tr>
</tbody></table>
<hr>
<p><strong>따라서, 일반적인 환경에서 정수 부분을 안전하게 구하고 싶다면 Math.floor()를 사용하는 것이 가장 신뢰할 수 있는 방법입니다.</strong></p>
<hr>
<h3 id="정수로-변환하고-싶다면--방법별-차이-정리"><strong>정수로 변환하고 싶다면? — 방법별 차이 정리</strong></h3>
<table>
<thead>
<tr>
<th><strong>목적 / 특징</strong></th>
<th><strong>사용법</strong></th>
<th><strong>예시 (1.42)</strong></th>
<th><strong>예시 (-1.42)</strong></th>
<th><strong>비고</strong></th>
</tr>
</thead>
<tbody><tr>
<td>소수점 이하 <strong>버림 (내림)</strong></td>
<td>Math.floor()</td>
<td>1</td>
<td><strong>-2</strong></td>
<td>가장 정확한 내림(항상 더 작은 정수로)</td>
</tr>
<tr>
<td>소수점 이하 <strong>올림</strong></td>
<td>Math.ceil()</td>
<td>2</td>
<td><strong>-1</strong></td>
<td>항상 더 큰 정수로</td>
</tr>
<tr>
<td>가장 <strong>가까운 정수</strong></td>
<td>Math.round()</td>
<td>1</td>
<td><strong>-1</strong></td>
<td>.5 이상 올림</td>
</tr>
<tr>
<td>정수 부분만 가져오기 (0쪽으로 절삭)</td>
<td>Math.trunc()</td>
<td>1</td>
<td><strong>-1</strong></td>
<td>ES6+, 직관적이고 안전</td>
</tr>
<tr>
<td>정수 부분만 가져오기 (0쪽으로 절삭)</td>
<td>parseInt(숫자)</td>
<td>1</td>
<td><strong>-1</strong></td>
<td>문자열 파싱이므로 숫자 변환 용도는 추천 X</td>
</tr>
<tr>
<td>문자열에서 숫자만 파싱</td>
<td>parseInt(&quot;문자열&quot;)</td>
<td>&quot;1.42&quot; → 1</td>
<td>&quot;-1.42&quot; → -1</td>
<td>소수점 이후는 무시</td>
</tr>
<tr>
<td>소수점 이하 제거 (0쪽으로 절삭)</td>
<td>~~숫자</td>
<td>1</td>
<td><strong>-1</strong></td>
<td>빠르지만 32비트 정수 제한 / 가독성 ↓</td>
</tr>
</tbody></table>
<hr>
<h3 id="🔍-어떤-상황에서-어떤-방법을-쓰면-좋을까"><strong>🔍 어떤 상황에서 어떤 방법을 쓰면 좋을까?</strong></h3>
<table>
<thead>
<tr>
<th><strong>상황</strong></th>
<th><strong>추천 방법</strong></th>
<th><strong>이유</strong></th>
</tr>
</thead>
<tbody><tr>
<td>음수 포함 &amp; 정확한 내림이 필요</td>
<td>Math.floor()</td>
<td>가장 신뢰할 수 있는 내림 함수</td>
</tr>
<tr>
<td>소수점 절삭이 목적이며 음/양수 둘 다 취급</td>
<td>Math.trunc()</td>
<td>의도 표현이 명확하고 안전</td>
</tr>
<tr>
<td>단순 반올림</td>
<td>Math.round()</td>
<td>일반적인 반올림</td>
</tr>
<tr>
<td>빠른 정수 절삭이 필요 &amp; 값이 32비트 정수 범위</td>
<td>~~num</td>
<td>고성능 트릭이지만 협업에는 비추천</td>
</tr>
<tr>
<td>문자열에서 정수만 뽑아야 할 때</td>
<td>parseInt(&quot;문자열&quot;)</td>
<td>숫자+문자 혼합 문자열 파싱에 적합</td>
</tr>
</tbody></table>
<hr>
<h3 id="한-줄-요약"><strong>한 줄 요약</strong></h3>
<blockquote>
<p>숫자의 정수 부분을 가장 안전하게 얻고 싶다면 Math.trunc()(절삭) 또는 Math.floor()(내림)가 가장 권장된다. (parseInt()와 ~~는 특정 상황을 제외하면 비추천)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 전국 대회 선발 고사]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EC%A0%84%EA%B5%AD-%EB%8C%80%ED%9A%8C-%EC%84%A0%EB%B0%9C-%EA%B3%A0%EC%82%AC</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EC%A0%84%EA%B5%AD-%EB%8C%80%ED%9A%8C-%EC%84%A0%EB%B0%9C-%EA%B3%A0%EC%82%AC</guid>
            <pubDate>Thu, 26 Jun 2025 15:10:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181851">전국 대회 선발 고사</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>0번부터 n - 1번까지 n명의 학생 중 3명을 선발하는 전국 대회 선발 고사를 보았습니다. 등수가 높은 3명을 선발해야 하지만, 개인 사정으로 전국 대회에 참여하지 못하는 학생들이 있어 참여가 가능한 학생 중 등수가 높은 3명을 선발하기로 했습니다.</p>
<p>각 학생들의 선발 고사 등수를 담은 정수 배열 <code>rank</code>와 전국 대회 참여 가능 여부가 담긴 boolean 배열 <code>attendance</code>가 매개변수로 주어집니다. 전국 대회에 선발된 학생 번호들을 등수가 높은 순서대로 각각 a, b, c번이라고 할 때 10000 × a + 100 × b + c를 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>3 ≤ <code>rank</code>의 길이 = <code>attendance</code>의 길이 ≤ 100</li>
<li><code>rank[i]</code>는 <code>i</code>번 학생의 선발 고사 등수를 의미합니다.</li>
<li><code>rank</code>의 원소는 1부터 n까지의 정수로 모두 서로 다릅니다.</li>
<li><code>attendance[i]</code>는 <code>i</code>번 학생의 전국 대회 참석 가능 여부를 나타냅니다.<ul>
<li><code>attendance[i]</code>가 true라면 참석 가능, false면 참석 불가능을 의미합니다.</li>
</ul>
</li>
<li><code>attendance</code>의 원소 중 적어도 3개는 true입니다.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>rank</th>
<th>attendance</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[3, 7, 2, 5, 4, 6, 1]</td>
<td>[false, true, true, true, true, false, false]</td>
<td>20403</td>
</tr>
<tr>
<td>[1, 2, 3]</td>
<td>[true, true, true]</td>
<td>102</td>
</tr>
<tr>
<td>[6, 1, 5, 2, 3, 4]</td>
<td>[true, false, true, false, false, true]</td>
<td>50200</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번에서 1등은 6번 학생이지만 전국 대회에 참석 불가능하므로 넘어갑니다. 2등은 2번 학생이고 전국 대회에 참석 가능하므로 1순위로 선발됩니다. 3등은 0번 학생이고 전국 대회에 참석 불가능 하므로 넘어갑니다. 4등과 5등은 각각 4번, 3번 학생이고 두 학생 모두 전국 대회에 참석 가능하므로 각각 2순위, 3순위로 선발됩니다. 3명을 선발하였으므로 6등과 7등은 확인하지 않아도 됩니다. 따라서 10000 × 2 + 100 × 4 + 3 = 20403을 return 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>예제 2번에서 1, 2, 3등은 각각 0번, 1번, 2번 학생이고 세 학생 모두 전국 대회에 참석 가능하므로 각각 1순위, 2순위, 3순위로 선발됩니다. 따라서 10000 × 0 + 100 × 1 + 2 = 102를 return 합니다.</li>
</ul>
<p>입출력 예 #3</p>
<ul>
<li>예제 3번에서 1, 2, 3등은 각각 1번, 3번, 4번 학생이지만 세 학생 모두 전국 대회에 참석 불가능합니다. 다음으로 4, 5, 6등은 각각 5번, 2번, 0번 학생이고 세 학생 모두 전국 대회에 참석 가능하므로 각각 1순위, 2순위, 3순위로 선발됩니다. 따라서 10000 × 5 + 100 × 2 + 0 = 50200을 return 합니다.</li>
</ul>
<hr>
<h3 id="코드"><strong>코드</strong></h3>
<pre><code class="language-jsx">/**
 * 전국 대회 선발 고사 - 다양한 풀이법 비교
 */

// ============================================
// 방법 1: 함수형 프로그래밍 (추천 ⭐⭐⭐)
// ============================================
function solution1(rank, attendance) {
  /**
   * 함수형 접근법의 장점:
   * - 체이닝으로 한 번에 읽기 쉬움
   * - 각 단계가 명확하게 분리됨
   * - 불변성을 유지하며 데이터 변환
   */
  return rank
    .map((rankValue, studentIndex) =&gt; ({ rankValue, studentIndex })) // 1. 학생 정보 객체화
    .filter((student) =&gt; attendance[student.studentIndex]) // 2. 참석 가능한 학생만 필터링
    .sort((a, b) =&gt; a.rankValue - b.rankValue) // 3. 등수 기준 오름차순 정렬
    .slice(0, 3) // 4. 상위 3명만 선택
    .reduce((result, student, index) =&gt; {
      // 5. 최종 계산
      const multiplier = [10000, 100, 1][index]; // 각 순위별 가중치
      return result + student.studentIndex * multiplier;
    }, 0);
}

// ============================================
// 방법 2: 직관적인 배열 활용 (이해하기 쉬움 ⭐⭐)
// ============================================
function solution2(rank, attendance) {
  /**
   * 직관적 접근법의 장점:
   * - 코드 흐름이 명확함
   * - 초보자도 이해하기 쉬움
   * - 디버깅이 용이함
   */
  const attendableStudents = [];

  // 참석 가능한 학생들의 정보를 수집
  for (let i = 0; i &lt; rank.length; i++) {
    if (attendance[i]) {
      attendableStudents.push({
        studentNumber: i,
        rank: rank[i],
      });
    }
  }

  // 등수 기준으로 정렬 (낮은 등수 = 높은 순위)
  attendableStudents.sort((a, b) =&gt; a.rank - b.rank);

  // 상위 3명의 학생 번호로 결과 계산
  const [first, second, third] = attendableStudents;
  return (
    first.studentNumber * 10000 +
    second.studentNumber * 100 +
    third.studentNumber
  );
}

// ============================================
// 방법 3: 원라이너 (간결함 ⭐)
// ============================================
function solution3(rank, attendance) {
  /**
   * 원라이너 접근법:
   * - 매우 간결함
   * - 함수형 프로그래밍의 극치
   * - 가독성은 떨어질 수 있음
   */
  return rank
    .map((r, i) =&gt; [r, i])
    .filter(([, i]) =&gt; attendance[i])
    .sort(([a], [b]) =&gt; a - b)
    .slice(0, 3)
    .reduce(
      (sum, [, studentNum], idx) =&gt; sum + studentNum * [10000, 100, 1][idx],
      0
    );
}

// ============================================
// 방법 4: Map 사용 (기존 방법)
// ============================================
function solution_original(rank, attendance) {
  const rankMap = new Map();
  for (let i = 0; i &lt; rank.length; i++) {
    if (attendance[i]) {
      rankMap.set(rank[i], i);
    }
  }
  const sortedRank = Array.from(rankMap.entries()).sort((a, b) =&gt; a[0] - b[0]);
  return sortedRank[0][1] * 10000 + sortedRank[1][1] * 100 + sortedRank[2][1];
}

// ============================================
// 성능 비교 및 테스트
// ============================================

/**
 * 추천하는 해결법: solution1 (함수형 프로그래밍)
 *
 * 이유:
 * 1. 가독성이 좋음 - 각 단계가 명확히 보임
 * 2. 유지보수 용이 - 각 체이닝 단계를 독립적으로 수정 가능
 * 3. 모던 JavaScript 스타일 - ES6+ 문법 활용
 * 4. 함수형 프로그래밍 패러다임 - 부작용 없는 순수 함수
 */

// 모든 해결법으로 테스트
const testCases = [
  [
    [3, 7, 2, 5, 4, 6, 1],
    [false, true, true, true, true, false, false],
  ], // 예상: 20403
  [
    [1, 2, 3],
    [true, true, true],
  ], // 예상: 102
  [
    [6, 1, 5, 2, 3, 4],
    [true, false, true, false, false, true],
  ], // 예상: 50200
];

console.log(&quot;=== 성능 및 결과 비교 ===&quot;);
testCases.forEach((testCase, index) =&gt; {
  const [rank, attendance] = testCase;

  console.log(`\n테스트 케이스 ${index + 1}:`);
  console.log(`방법1 (함수형): ${solution1(rank, attendance)}`);
  console.log(`방법2 (직관적): ${solution2(rank, attendance)}`);
  console.log(`방법3 (원라이너): ${solution3(rank, attendance)}`);
  console.log(`기존방법 (Map): ${solution_original(rank, attendance)}`);
});
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 뒤에서 5등 위로]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1-%EC%9C%84%EB%A1%9C-egenfu00</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1-%EC%9C%84%EB%A1%9C-egenfu00</guid>
            <pubDate>Sun, 16 Mar 2025 06:03:42 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181852">뒤에서 5등 위로</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수로 이루어진 리스트 <code>num_list</code>가 주어집니다. <code>num_list</code>에서 가장 작은 5개의 수를 제외한 수들을 오름차순으로 담은 리스트를 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>6 ≤ <code>num_list</code>의 길이 ≤ 30</li>
<li>1 ≤ <code>num_list</code>의 원소 ≤ 100</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>num_list</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[12, 4, 15, 46, 38, 1, 14, 56, 32, 10]</td>
<td>[15, 32, 38, 46, 56]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>[12, 4, 15, 46, 38, 1, 14, 56, 32, 10]를 정렬하면 [1, 4, 10, 12, 14, 15, 32, 38, 46, 56]이 되고, 앞에서 부터 6번째 이후의 수들을 고르면 [15, 32, 38, 46, 56]가 됩니다.</li>
</ul>
<hr>
<h3 id="코드"><strong>코드</strong></h3>
<pre><code class="language-jsx">function solution(num_list) {
    return num_list.sort((a, b) =&gt; a - b).slice(5);
}
</code></pre>
<hr>
<h3 id="코드-설명"><strong>코드 설명</strong></h3>
<ol>
<li><p><strong>리스트를 오름차순 정렬</strong></p>
<pre><code class="language-jsx"> num_list.sort((a, b) =&gt; a - b)
</code></pre>
<ul>
<li><code>sort()</code>를 사용하여 <strong>오름차순 정렬</strong>.</li>
<li><code>(a, b) =&gt; a - b</code>는 <strong>숫자 정렬</strong>을 위한 비교 함수.</li>
</ul>
</li>
<li><p><strong>가장 작은 5개의 숫자를 제외하고 반환</strong></p>
<pre><code class="language-jsx"> .slice(5)
</code></pre>
<ul>
<li><code>slice(5)</code>를 사용하여 <strong>앞에서 5개를 제외한 나머지 부분 반환</strong>.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 뒤에서 5등까지]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1%EA%B9%8C%EC%A7%80</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1%EA%B9%8C%EC%A7%80</guid>
            <pubDate>Sun, 16 Mar 2025 05:40:05 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181853">뒤에서 5등까지</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수로 이루어진 리스트 <code>num_list</code>가 주어집니다. <code>num_list</code>에서 가장 작은 5개의 수를 오름차순으로 담은 리스트를 return하도록 solution 함수를 완성해주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>6 ≤ <code>num_list</code>의 길이 ≤ 30</li>
<li>1 ≤ <code>num_list</code>의 원소 ≤ 100</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>num_list</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[12, 4, 15, 46, 38, 1, 14]</td>
<td>[1, 4, 12, 14, 15]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>[12, 4, 15, 46, 38, 1, 14]를 정렬하면 [1, 4, 12, 14, 15, 38, 46]이 되고, 앞에서 부터 5개를 고르면 [1, 4, 12, 14, 15]가 됩니다.</li>
</ul>
<hr>
<h3 id="코드"><strong>코드</strong></h3>
<pre><code class="language-jsx">function solution(num_list) {
    return num_list.sort((a, b) =&gt; a - b).slice(0, 5);
}</code></pre>
<hr>
<h3 id="코드-설명"><strong>코드 설명</strong></h3>
<ol>
<li><p><strong>정렬 (오름차순)</strong></p>
<pre><code class="language-jsx"> num_list.sort((a, b) =&gt; a - b)</code></pre>
<ul>
<li><code>sort()</code>를 사용하여 리스트를 <strong>오름차순 정렬</strong>.</li>
<li><code>(a, b) =&gt; a - b</code>는 <strong>숫자 정렬</strong>을 위한 비교 함수.</li>
</ul>
</li>
<li><p><strong>가장 작은 5개의 숫자 선택</strong></p>
<pre><code class="language-jsx"> .slice(0, 5)</code></pre>
<ul>
<li><code>slice(0, 5)</code>를 사용하여 <strong>정렬된 리스트의 처음 5개 요소</strong>를 추출.</li>
</ul>
</li>
</ol>
<p>결론: <code>sort()</code>로 정렬 후 <code>slice()</code>로 상위 5개 추출.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 배열의 길이에 따라 다른 연산하기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EA%B8%B8%EC%9D%B4%EC%97%90-%EB%94%B0%EB%9D%BC-%EB%8B%A4%EB%A5%B8-%EC%97%B0%EC%82%B0%ED%95%98%EA%B8%B0-b9y274ro</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EA%B8%B8%EC%9D%B4%EC%97%90-%EB%94%B0%EB%9D%BC-%EB%8B%A4%EB%A5%B8-%EC%97%B0%EC%82%B0%ED%95%98%EA%B8%B0-b9y274ro</guid>
            <pubDate>Sun, 16 Mar 2025 05:07:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181854">배열의 길이에 따라 다른 연산하기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수 배열 <code>arr</code>과 정수 <code>n</code>이 매개변수로 주어집니다. <code>arr</code>의 길이가 홀수라면 <code>arr</code>의 모든 짝수 인덱스 위치에 <code>n</code>을 더한 배열을, <code>arr</code>의 길이가 짝수라면 <code>arr</code>의 모든 홀수 인덱스 위치에 <code>n</code>을 더한 배열을 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 1,000</li>
<li>1 ≤ <code>arr</code>의 원소 ≤ 1,000</li>
<li>1 ≤ <code>n</code> ≤ 1,000</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>n</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[49, 12, 100, 276, 33]</td>
<td>27</td>
<td>[76, 12, 127, 276, 60]</td>
</tr>
<tr>
<td>[444, 555, 666, 777]</td>
<td>100</td>
<td>[444, 655, 666, 877]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번의 <code>arr</code>의 길이는 5로 홀수입니다. 따라서 <code>arr</code>의 짝수 인덱스 0, 2, 4에 주어진 <code>n</code> 값인 27을 더하면 [76, 12, 127, 276, 60]이 됩니다. 따라서 [76, 12, 127, 276, 60]를 return 합니다.</li>
</ul>
<p>입출력 예 #1</p>
<ul>
<li>예제 2번의 <code>arr</code>의 길이는 4로 짝수입니다. 따라서 <code>arr</code>의 홀수 인덱스 1, 3에 주어진 <code>n</code> 값인 100을 더하면 [444, 655, 666, 877]이 됩니다. 따라서 [444, 655, 666, 877]를 return 합니다.</li>
</ul>
<hr>
<pre><code>function solution(arr, n) {
    return arr.map((num, i) =&gt; (arr.length % 2 === 1 ? i % 2 === 0 : i % 2 === 1) ? num + n : num);
}</code></pre><hr>
<h2 id="코드-설명"><strong>코드 설명</strong></h2>
<h3 id="1----map을-사용하여-배열을-변환">1.    <strong>map()을 사용하여 배열을 변환</strong></h3>
<p>•    arr.map((num, i) =&gt; {...}) : arr의 각 요소를 순회하며 새로운 배열을 생성.</p>
<p>•    num은 현재 요소, i는 현재 인덱스.</p>
<h3 id="2----배열-길이에-따른-인덱스-조건-설정">2.    <strong>배열 길이에 따른 인덱스 조건 설정</strong></h3>
<pre><code class="language-jsx">arr.length % 2 === 1 ? i % 2 === 0 : i % 2 === 1</code></pre>
<p>•    arr.length % 2 === 1 (홀수인 경우) → 짝수 인덱스 (i % 2 === 0)에 n을 더함.</p>
<p>•    arr.length % 2 === 0 (짝수인 경우) → 홀수 인덱스 (i % 2 === 1)에 n을 더함.</p>
<h3 id="3----변환된-값을-반환">3.    <strong>변환된 값을 반환</strong></h3>
<pre><code class="language-jsx">num + n : num</code></pre>
<p>•    조건을 만족하면 num + n 반환, 그렇지 않으면 원래 값 반환.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 스크롤 이벤트 (scroll Event)]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8-scroll-Event</link>
            <guid>https://velog.io/@moon_dev/JavaScript-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8-scroll-Event</guid>
            <pubDate>Sun, 16 Mar 2025 04:39:00 GMT</pubDate>
            <description><![CDATA[<h2 id="스크롤-이벤트-scroll-event"><strong>스크롤 이벤트 (scroll Event)</strong></h2>
<p>웹 문서에서 스크롤이 발생하면 scroll 이벤트가 발생한다. 기본적으로 웹 문서의 크기가 브라우저 창보다 클 경우 스크롤이 자동으로 생성되며, CSS를 이용해 특정 요소에 스크롤을 추가할 수도 있다.</p>
<hr>
<h3 id="1-스크롤-이벤트-감지하기"><strong>1. 스크롤 이벤트 감지하기</strong></h3>
<p>일반적으로 스크롤 이벤트는 <strong>브라우저를 대변하는 window 객체</strong>에 등록하는 경우가 많다.</p>
<pre><code class="language-jsx">window.addEventListener(&quot;scroll&quot;, () =&gt; {
  console.log(&quot;스크롤 이벤트 발생&quot;);
});</code></pre>
<p>✅ <strong>결과</strong>: 웹 문서에서 스크롤이 발생할 때마다 콘솔에 &quot;스크롤 이벤트 발생&quot;이 출력된다.</p>
<hr>
<h3 id="2-현재-스크롤-위치-확인하기"><strong>2. 현재 스크롤 위치 확인하기</strong></h3>
<p>스크롤 이벤트를 활용할 때 window 객체의 프로퍼티를 자주 사용한다.</p>
<pre><code class="language-jsx">window.addEventListener(&quot;scroll&quot;, () =&gt; {
  console.log(`현재 스크롤 위치: ${window.scrollY}px`);
});</code></pre>
<p>✅ <strong>결과</strong>: 현재 <strong>문서의 맨 위에서부터 몇 픽셀</strong> 만큼 스크롤했는지를 콘솔에 출력.</p>
<hr>
<h3 id="3-특정-위치에서-요소-스타일-변경하기"><strong>3. 특정 위치에서 요소 스타일 변경하기</strong></h3>
<p>스크롤 이벤트를 활용하여 특정 위치를 기준으로 요소의 스타일을 변경할 수 있다.</p>
<pre><code class="language-jsx">const navbar = document.querySelector(&quot;.navbar&quot;);

window.addEventListener(&quot;scroll&quot;, () =&gt; {
  if (window.scrollY &gt; 30) {
    navbar.classList.add(&quot;scrolled&quot;);
  } else {
    navbar.classList.remove(&quot;scrolled&quot;);
  }
});</code></pre>
<p>✅ <strong>결과</strong>:</p>
<p>•    <strong>30px 이상 스크롤</strong>하면 .navbar 요소에 scrolled 클래스 추가 → 그림자 효과 적용</p>
<p>•    <strong>30px 이하로 스크롤</strong>하면 클래스 제거 → 원래 상태로 복귀</p>
<pre><code class="language-jsx">.scrolled {
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}</code></pre>
<hr>
<h3 id="4-스크롤-방향-감지하기"><strong>4. 스크롤 방향 감지하기</strong></h3>
<p>스크롤을 내릴 때와 올릴 때 다른 동작을 수행할 수도 있다.</p>
<pre><code class="language-jsx">let lastScrollY = 0;

window.addEventListener(&quot;scroll&quot;, () =&gt; {
  if (window.scrollY &gt; lastScrollY) {
    console.log(&quot;스크롤 내림&quot;);
  } else {
    console.log(&quot;스크롤 올림&quot;);
  }
  lastScrollY = window.scrollY;
});</code></pre>
<p>✅ <strong>결과</strong>:</p>
<p>•    아래로 스크롤하면 &quot;스크롤 내림&quot;</p>
<p>•    위로 스크롤하면 &quot;스크롤 올림&quot;</p>
<hr>
<h3 id="요약"><strong>요약</strong></h3>
<p>•    scroll 이벤트는 <strong>웹 문서가 스크롤될 때마다 발생</strong>한다.</p>
<p>•    window.scrollY를 활용하여 <strong>현재 스크롤 위치를 확인</strong>할 수 있다.</p>
<p>•    특정 위치 이상 스크롤되면 <strong>요소에 클래스를 추가하거나 제거</strong>할 수 있다.</p>
<p>•    <strong>스크롤 방향을 감지</strong>하여 위/아래 이동에 따라 다른 동작을 수행할 수 있다.</p>
<p>이렇게 스크롤 이벤트를 활용하면 다양한 UI 효과를 구현할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 문자열 묶기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%AC%B6%EA%B8%B0-d782de00</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%AC%B6%EA%B8%B0-d782de00</guid>
            <pubDate>Tue, 25 Feb 2025 12:32:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181855">문자열 묶기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>문자열 배열 <code>strArr</code>이 주어집니다. <code>strArr</code>의 원소들을 길이가 같은 문자열들끼리 그룹으로 묶었을 때 가장 개수가 많은 그룹의 크기를 return 하는 solution 함수를 완성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>strArr</code>의 길이 ≤ 100,000<ul>
<li>1 ≤ <code>strArr</code>의 원소의 길이 ≤ 30</li>
<li><code>strArr</code>의 원소들은 알파벳 소문자로 이루어진 문자열입니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>strArr</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[&quot;a&quot;,&quot;bc&quot;,&quot;d&quot;,&quot;efg&quot;,&quot;hi&quot;]</td>
<td>2</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p><strong>입출력 예 #1</strong></p>
<ul>
<li>각 문자열들을 길이에 맞게 그룹으로 묶으면 다음과 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>문자열 길이</th>
<th>문자열 목록</th>
<th>개수</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>[&quot;a&quot;,&quot;d&quot;]</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>[&quot;bc&quot;,&quot;hi&quot;]</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>[&quot;efg&quot;]</td>
<td>1</td>
</tr>
<tr>
<td>- 개수의 최댓값은 2이므로 2를 return 합니다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<hr>
<pre><code class="language-jsx">function solution(strArr) {
    const lengthCount = new Map(); // 문자열 길이별 개수를 저장할 Map

    // 각 문자열의 길이를 카운트
    for (const str of strArr) {
        const len = str.length;
        lengthCount.set(len, (lengthCount.get(len) || 0) + 1);
    }

    // 가장 큰 그룹 크기 찾기
    return Math.max(...lengthCount.values());
}
</code></pre>
<hr>
<h3 id="코드설명"><strong>코드설명</strong></h3>
<ol>
<li><p><strong>문자열 길이별 개수를 저장할 <code>Map</code> 생성</strong></p>
<pre><code class="language-jsx"> const lengthCount = new Map();
</code></pre>
<ul>
<li><code>Map</code>을 사용하여 문자열 길이를 key로 하고, 해당 길이를 가진 문자열 개수를 value로 저장합니다.</li>
</ul>
</li>
<li><p><strong>각 문자열의 길이를 <code>Map</code>에 카운트</strong></p>
<pre><code class="language-jsx"> for (const str of strArr) {
     const len = str.length;
     lengthCount.set(len, (lengthCount.get(len) || 0) + 1);
 }
</code></pre>
<ul>
<li><code>str.length</code>를 이용하여 문자열 길이를 가져옵니다.</li>
<li><code>lengthCount.get(len) || 0</code>: 기존에 해당 길이가 <code>Map</code>에 존재하면 그 값을 가져오고, 없으면 <code>0</code>으로 설정.</li>
<li><code>set(len, count + 1)</code>: 해당 길이의 문자열 개수를 증가.</li>
</ul>
</li>
<li><p><strong>가장 개수가 많은 그룹 찾기</strong></p>
<pre><code class="language-jsx"> return Math.max(...lengthCount.values());
</code></pre>
<ul>
<li><code>lengthCount.values()</code>는 <code>Map</code>에 저장된 모든 문자열 개수를 반환.</li>
<li><code>Math.max(...)</code>를 이용하여 가장 큰 값을 찾음.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 배열 비교하기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</guid>
            <pubDate>Mon, 24 Feb 2025 12:03:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181856">배열 비교하기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>이 문제에서 두 정수 배열의 대소관계를 다음과 같이 정의합니다.</p>
<ul>
<li>두 배열의 길이가 다르다면, 배열의 길이가 긴 쪽이 더 큽니다.</li>
<li>배열의 길이가 같다면 각 배열에 있는 모든 원소의 합을 비교하여 다르다면 더 큰 쪽이 크고, 같다면 같습니다.</li>
</ul>
<p>두 정수 배열 <code>arr1</code>과 <code>arr2</code>가 주어질 때, 위에서 정의한 배열의 대소관계에 대하여 <code>arr2</code>가 크다면 -1, <code>arr1</code>이 크다면 1, 두 배열이 같다면 0을 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr1</code>의 길이 ≤ 100</li>
<li>1 ≤ <code>arr2</code>의 길이 ≤ 100</li>
<li>1 ≤ <code>arr1</code>의 원소 ≤ 100</li>
<li>1 ≤ <code>arr2</code>의 원소 ≤ 100</li>
<li>문제에서 정의한 배열의 대소관계가 일반적인 프로그래밍 언어에서 정의된 배열의 대소관계와 다를 수 있는 점에 유의해주세요.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr1</th>
<th>arr2</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[49, 13]</td>
<td>[70, 11, 2]</td>
<td>-1</td>
</tr>
<tr>
<td>[100, 17, 84, 1]</td>
<td>[55, 12, 65, 36]</td>
<td>1</td>
</tr>
<tr>
<td>[1, 2, 3, 4, 5]</td>
<td>[3, 3, 3, 3, 3]</td>
<td>0</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번에서는 <code>arr1</code>의 길이는 2이고 <code>arr2</code>의 길이는 3으로 <code>arr2</code>의 길이가 더 깁니다. 따라서 <code>arr2</code>가 <code>arr1</code>보다 크므로 -1을 return 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>예제 2번에서는 <code>arr1</code>의 길이과 <code>arr2</code>의 길이가 4로 같습니다. <code>arr1</code>의 모든 원소의 합은 100 + 17 + 84 + 1 = 202이고 <code>arr2</code>의 모든 원소의 합은 55 + 12 + 65 + 36 = 168으로 <code>arr1</code>의 모든 원소의 합이 더 큽니다. 따라서 <code>arr1</code>이 <code>arr2</code>보다 크므로 1을 return 합니다.</li>
</ul>
<p>입출력 예 #3</p>
<ul>
<li>예제 3번에서는 <code>arr1</code>의 길이와 <code>arr2</code>의 길이가 5로 같고 각 배열의 모든 원소의 합 또한 15로 같습니다. 따라서 <code>arr1</code>과 <code>arr2</code>가 같으므로 0을 return 합니다.</li>
</ul>
<hr>
<pre><code class="language-jsx">function solution(arr1, arr2) {
    if (arr1.length !== arr2.length) {
        return arr1.length &gt; arr2.length ? 1 : -1;
    }

    const sum1 = arr1.reduce((acc, num) =&gt; acc + num, 0);
    const sum2 = arr2.reduce((acc, num) =&gt; acc + num, 0);

    return sum1 === sum2 ? 0 : sum1 &gt; sum2 ? 1 : -1;
}
</code></pre>
<hr>
<h3 id="코드설명"><strong>코드설명</strong></h3>
<ol>
<li><p><strong>배열 길이 비교</strong></p>
<pre><code class="language-jsx"> if (arr1.length !== arr2.length) {
     return arr1.length &gt; arr2.length ? 1 : -1;
 }
</code></pre>
<ul>
<li>두 배열의 길이가 다를 경우, 더 긴 배열이 크므로 <strong>길이를 비교하여 결과를 반환</strong>합니다.</li>
<li><code>arr1.length &gt; arr2.length</code>이면 <code>1</code> 반환 (arr1이 더 김).</li>
<li><code>arr1.length &lt; arr2.length</code>이면 <code>1</code> 반환 (arr2가 더 김).</li>
</ul>
</li>
<li><p><strong>배열 원소의 합 비교</strong></p>
<pre><code class="language-jsx"> const sum1 = arr1.reduce((acc, num) =&gt; acc + num, 0);
 const sum2 = arr2.reduce((acc, num) =&gt; acc + num, 0);
</code></pre>
<ul>
<li><code>reduce</code>를 사용하여 배열의 합을 계산합니다.</li>
<li><code>reduce((acc, num) =&gt; acc + num, 0)</code>은 배열의 모든 원소를 더하는 역할을 합니다.</li>
</ul>
</li>
<li><p><strong>합을 비교하여 결과 반환</strong></p>
<pre><code class="language-jsx"> return sum1 === sum2 ? 0 : sum1 &gt; sum2 ? 1 : -1;
</code></pre>
<ul>
<li>두 배열의 합이 같으면 <code>0</code> 반환.</li>
<li><code>sum1</code>이 크면 <code>1</code>, <code>sum2</code>가 크면 <code>1</code> 반환.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 배열의 길이를 2의 거듭제곱으로 만들기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EA%B8%B8%EC%9D%B4%EB%A5%BC-2%EC%9D%98-%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0-6c88din5</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EA%B8%B8%EC%9D%B4%EB%A5%BC-2%EC%9D%98-%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0-6c88din5</guid>
            <pubDate>Sat, 22 Feb 2025 15:19:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181857">배열의 길이를 2의 거듭제곱으로 만들기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>정수 배열 <code>arr</code>이 매개변수로 주어집니다. <code>arr</code>의 길이가 2의 정수 거듭제곱이 되도록 <code>arr</code> 뒤에 정수 0을 추가하려고 합니다. <code>arr</code>에 최소한의 개수로 0을 추가한 배열을 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 1,000</li>
<li>1 ≤ <code>arr</code>의 원소 ≤ 1,000</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[1, 2, 3, 4, 5, 6]</td>
<td>[1, 2, 3, 4, 5, 6, 0, 0]</td>
</tr>
<tr>
<td>[58, 172, 746, 89]</td>
<td>[58, 172, 746, 89]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번의 <code>arr</code>의 길이는 6입니다. <code>arr</code>의 길이를 2의 정수 거듭제곱으로 만드는 방법은 0을 2개, 10개, 26개,..., 추가하는 방법이 있고 그중 최소한으로 0을 추가하는 방법은 2개를 추가하는 것입니다. 따라서 [1, 2, 3, 4, 5, 6, 0, 0]을 return 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>예제 2번의 <code>arr</code>의 길이는 4이고 이미 2의 정수 거듭제곱입니다. 따라서 뒤에 0을 추가하지 않아도 되므로 [58, 172, 746, 89]를 return 합니다.</li>
</ul>
<hr>
<pre><code class="language-jsx">function solution(arr) {
    const length = arr.length;
    const targetLength = 2 ** Math.ceil(Math.log2(length)); // 가장 가까운 2의 거듭제곱 계산
    return [...arr, ...Array(targetLength - length).fill(0)]; // 부족한 부분 0으로 채우기
}
</code></pre>
<hr>
<h3 id="코드설명"><strong>코드설명</strong></h3>
<ol>
<li><p><strong>현재 배열 길이 계산</strong></p>
<pre><code class="language-jsx"> const length = arr.length;
</code></pre>
<ul>
<li>현재 <code>arr</code>의 길이를 <code>length</code> 변수에 저장합니다.</li>
</ul>
</li>
<li><p><strong>가장 가까운 2의 거듭제곱 찾기</strong></p>
<pre><code class="language-jsx"> const targetLength = 2 ** Math.ceil(Math.log2(length));
</code></pre>
<ul>
<li><code>Math.log2(length)</code>: 현재 길이의 로그(base 2)를 구합니다.</li>
<li><code>Math.ceil(...)</code>: 올림하여 가장 가까운 2의 거듭제곱을 찾습니다.</li>
<li><code>2 ** ...</code>: 2의 거듭제곱을 계산하여 <code>targetLength</code>에 저장합니다.</li>
</ul>
</li>
<li><p><strong>부족한 부분을 0으로 채우기</strong></p>
<pre><code class="language-jsx"> return [...arr, ...Array(targetLength - length).fill(0)];
</code></pre>
<ul>
<li><code>Array(targetLength - length).fill(0)</code>: 부족한 길이만큼 0을 채운 배열을 생성합니다.</li>
<li><code>...arr, ...Array(...)</code>: 스프레드 연산자로 <code>arr</code>의 기존 값과 0을 추가한 배열을 합칩니다.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 무작위로 K개의 수 뽑기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-6</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-6</guid>
            <pubDate>Sat, 22 Feb 2025 11:02:26 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181858">무작위로 K개의 수 뽑기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>랜덤으로 서로 다른 k개의 수를 저장한 배열을 만드려고 합니다. 적절한 방법이 떠오르지 않기 때문에 일정한 범위 내에서 무작위로 수를 뽑은 후, 지금까지 나온적이 없는 수이면 배열 맨 뒤에 추가하는 방식으로 만들기로 합니다.</p>
<p>이미 어떤 수가 무작위로 주어질지 알고 있다고 가정하고, 실제 만들어질 길이 <code>k</code>의 배열을 예상해봅시다.</p>
<p>정수 배열 <code>arr</code>가 주어집니다. 문제에서의 무작위의 수는 <code>arr</code>에 저장된 순서대로 주어질 예정이라고 했을 때, 완성될 배열을 return 하는 solution 함수를 완성해 주세요.</p>
<p>단, 완성될 배열의 길이가 <code>k</code>보다 작으면 나머지 값을 전부 -1로 채워서 return 합니다.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 100,000<ul>
<li>0 ≤ <code>arr</code>의 원소 ≤ 100,000</li>
</ul>
</li>
<li>1 ≤ <code>k</code> ≤ 1,000</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>k</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[0, 1, 1, 2, 2, 3]</td>
<td>3</td>
<td>[0, 1, 2]</td>
</tr>
<tr>
<td>[0, 1, 1, 1, 1]</td>
<td>4</td>
<td>[0, 1, -1, -1]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>앞에서부터 서로 다른 <code>k</code>개의 수를 골라내면 [0, 1, 2]가 됩니다. 따라서 [0, 1, 2]를 return 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>서로 다른 수의 개수가 2개 뿐이므로 서로 다른 수들을 앞에서부터 차례대로 저장한 [0, 1]에서 이후 2개의 인덱스를 -1로 채워넣은 [0, 1, -1, -1]을 return 합니다.</li>
</ul>
<hr>
<pre><code class="language-jsx">function solution(arr, k) {
    const set = new Set(arr); // 중복 제거된 값들을 저장
    return set.size &gt; k
        ? [...set].slice(0, k)  // k개까지만 추출
        : [...set, ...Array(k - set.size).fill(-1)]; // 부족하면 -1 채우기
}
</code></pre>
<hr>
<h3 id="코드-설명"><strong>코드 설명</strong></h3>
<h3 id="1-중복-제거-set-활용"><strong>1. 중복 제거 (<code>Set</code> 활용)</strong></h3>
<ul>
<li><code>new Set(arr)</code>을 이용하여 배열 <code>arr</code>에서 <strong>중복을 제거</strong>하고 고유한 값들만 저장합니다.</li>
<li>예: <code>[0, 1, 1, 2, 2, 3]</code> → <code>{0, 1, 2, 3}</code>.</li>
</ul>
<h3 id="2-k-개수-확인-후-처리"><strong>2. <code>k</code> 개수 확인 후 처리</strong></h3>
<ul>
<li><code>set.size &gt; k</code> (고유한 숫자가 <code>k</code>보다 많을 경우)<ul>
<li><code>slice(0, k)</code>를 사용하여 <code>k</code>개까지만 선택.</li>
</ul>
</li>
<li><code>set.size &lt;= k</code> (고유한 숫자가 <code>k</code>보다 적을 경우)<ul>
<li>부족한 개수만큼 <code>-1</code> 을 추가.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 배열 만들기 6]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-6</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-6</guid>
            <pubDate>Fri, 21 Feb 2025 11:29:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181859">배열 만들기 6</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>0과 1로만 이루어진 정수 배열 <code>arr</code>가 주어집니다. <code>arr</code>를 이용해 새로운 배열 <code>stk</code>을 만드려고 합니다.</p>
<p><code>i</code>의 초기값을 0으로 설정하고 <code>i</code>가 <code>arr</code>의 길이보다 작으면 다음을 반복합니다.</p>
<ul>
<li>만약 <code>stk</code>이 빈 배열이라면 <code>arr[i]</code>를 <code>stk</code>에 추가하고 <code>i</code>에 1을 더합니다.</li>
<li><code>stk</code>에 원소가 있고, <code>stk</code>의 마지막 원소가 <code>arr[i]</code>와 같으면 <code>stk</code>의 마지막 원소를 <code>stk</code>에서 제거하고 <code>i</code>에 1을 더합니다.</li>
<li><code>stk</code>에 원소가 있는데 <code>stk</code>의 마지막 원소가 <code>arr[i]</code>와 다르면 <code>stk</code>의 맨 마지막에 <code>arr[i]</code>를 추가하고 <code>i</code>에 1을 더합니다.</li>
</ul>
<p>위 작업을 마친 후 만들어진 <code>stk</code>을 return 하는 solution 함수를 완성해 주세요.</p>
<p>단, 만약 빈 배열을 return 해야한다면 [-1]을 return 합니다.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 1,000,000<ul>
<li><code>arr</code>의 원소는 0 또는 1 입니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[0, 1, 1, 1, 0]</td>
<td>[0, 1, 0]</td>
</tr>
<tr>
<td>[0, 1, 0, 1, 0]</td>
<td>[0, 1, 0, 1, 0]</td>
</tr>
<tr>
<td>[0, 1, 1, 0]</td>
<td>[-1]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>각 작업을 마친 후에 배열의 변화를 나타내면 다음 표와 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>idx</th>
<th>arr[idx]</th>
<th>stk</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>0</td>
<td>[]</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>[0]</td>
</tr>
<tr>
<td>2</td>
<td>1</td>
<td>[0, 1]</td>
</tr>
<tr>
<td>3</td>
<td>1</td>
<td>[0]</td>
</tr>
<tr>
<td>4</td>
<td>0</td>
<td>[0, 1]</td>
</tr>
<tr>
<td>5</td>
<td>-</td>
<td>[0, 1, 0]</td>
</tr>
<tr>
<td>- 따라서 [0, 1, 0]을 return 합니다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>입출력 예 #2</p>
<ul>
<li>각 작업을 마친 후에 배열의 변화를 나타내면 다음 표와 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>idx</th>
<th>arr[idx]</th>
<th>stk</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>0</td>
<td>[]</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>[0]</td>
</tr>
<tr>
<td>2</td>
<td>0</td>
<td>[0, 1]</td>
</tr>
<tr>
<td>3</td>
<td>1</td>
<td>[0, 1, 0]</td>
</tr>
<tr>
<td>4</td>
<td>0</td>
<td>[0, 1, 0, 1]</td>
</tr>
<tr>
<td>5</td>
<td>-</td>
<td>[0, 1, 0, 1, 0]</td>
</tr>
<tr>
<td>- 따라서 [0, 1, 0, 1, 0]을 return 합니다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<p>입출력 예 #3</p>
<ul>
<li>각 작업을 마친 후에 배열의 변화를 나타내면 다음 표와 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>idx</th>
<th>arr[idx]</th>
<th>stk</th>
</tr>
</thead>
<tbody><tr>
<td>0</td>
<td>0</td>
<td>[]</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>[0]</td>
</tr>
<tr>
<td>2</td>
<td>1</td>
<td>[0, 1]</td>
</tr>
<tr>
<td>3</td>
<td>0</td>
<td>[0]</td>
</tr>
<tr>
<td>4</td>
<td>-</td>
<td>[]</td>
</tr>
<tr>
<td>- 마지막에 빈 배열이 되었으므로 [-1]을 return 합니다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<hr>
<pre><code class="language-jsx">function solution(arr) {
    const stk = [];

    for (const num of arr) {
        if (stk.length === 0 || stk[stk.length - 1] !== num) {
            stk.push(num);
        } else {
            stk.pop();
        }
    }

    return stk.length ? stk : [-1];
}
</code></pre>
<hr>
<h3 id="코드설명"><strong>코드설명</strong></h3>
<ol>
<li><strong>결과 배열 <code>stk</code> 초기화</strong><ul>
<li>결과를 저장할 빈 배열 <code>stk</code>을 생성합니다.</li>
</ul>
</li>
<li><strong><code>for ... of</code> 반복문을 사용하여 <code>arr</code> 순회</strong><ul>
<li><code>num</code>은 <code>arr</code>의 각 요소를 의미합니다.</li>
</ul>
</li>
<li><strong>조건 처리</strong><ul>
<li><code>stk</code>이 비어있거나 <code>stk</code>의 마지막 요소(<code>stk[stk.length - 1]</code>)와 현재 요소 <code>num</code>이 다르면 <code>stk.push(num)</code>을 실행하여 <code>stk</code>에 추가합니다.</li>
<li><code>stk</code>의 마지막 요소와 <code>num</code>이 같으면 <code>stk.pop()</code>을 실행하여 <code>stk</code>에서 마지막 요소를 제거합니다.</li>
</ul>
</li>
<li><strong>결과 반환</strong><ul>
<li>모든 반복이 끝난 후 <code>stk</code>이 비어있다면 <code>[-1]</code>을 반환합니다.</li>
<li>그렇지 않으면 <code>stk</code>을 그대로 반환합니다.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 빈 배열에 추가, 삭제하기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B9%88-%EB%B0%B0%EC%97%B4%EC%97%90-%EC%B6%94%EA%B0%80-%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0-v39dnm8w</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B9%88-%EB%B0%B0%EC%97%B4%EC%97%90-%EC%B6%94%EA%B0%80-%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0-v39dnm8w</guid>
            <pubDate>Thu, 20 Feb 2025 11:36:08 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181860">빈 배열에 추가, 삭제하기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>아무 원소도 들어있지 않은 빈 배열 X가 있습니다. 길이가 같은 정수 배열 <code>arr</code>과 boolean 배열 <code>flag</code>가 매개변수로 주어질 때, <code>flag</code>를 차례대로 순회하며 <code>flag[i]</code>가 true라면 X의 뒤에 <code>arr[i]</code>를 <code>arr[i]</code> × 2 번 추가하고, <code>flag[i]</code>가 false라면 X에서 마지막 <code>arr[i]</code>개의 원소를 제거한 뒤 X를 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 = <code>flag</code>의 길이 ≤ 100</li>
<li><code>arr</code>의 모든 원소는 1 이상 9 이하의 정수입니다.</li>
<li>현재 X의 길이보다 더 많은 원소를 빼는 입력은 주어지지 않습니다.</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>flag</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[3, 2, 4, 1, 3]</td>
<td>[true, false, true, false, false]</td>
<td>[3, 3, 3, 3, 4, 4, 4, 4]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번에서 X의 변화를 표로 나타내면 다음과 같습니다</li>
</ul>
<table>
<thead>
<tr>
<th>i</th>
<th>flag[i]</th>
<th>arr[i]</th>
<th>X</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td></td>
<td></td>
<td>[]</td>
</tr>
<tr>
<td>0</td>
<td>true</td>
<td>3</td>
<td>[3, 3, 3, 3, 3, 3]</td>
</tr>
<tr>
<td>1</td>
<td>false</td>
<td>2</td>
<td>[3, 3, 3, 3]</td>
</tr>
<tr>
<td>2</td>
<td>true</td>
<td>4</td>
<td>[3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4]</td>
</tr>
<tr>
<td>3</td>
<td>false</td>
<td>1</td>
<td>[3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4]</td>
</tr>
<tr>
<td>4</td>
<td>false</td>
<td>3</td>
<td>[3, 3, 3, 3, 4, 4, 4, 4]</td>
</tr>
</tbody></table>
<p><code>따라서 [3, 3, 3, 3, 4, 4, 4, 4]를 return 합니다.</code></p>
<hr>
<pre><code class="language-jsx">function solution(arr, flag) {
    const X = []; // 결과 배열 초기화

    arr.forEach((num, i) =&gt; {
        if (flag[i]) {
            // flag[i]가 true이면 num을 num * 2번 추가
            X.push(...Array(num * 2).fill(num));
        } else {
            // flag[i]가 false이면 X에서 num개의 원소 제거
            X.splice(-num, num);
        }
    });

    return X;
}
</code></pre>
<hr>
<h3 id="코드설명"><strong>코드설명</strong></h3>
<ol>
<li><p><strong>결과 배열 <code>X</code> 초기화</strong></p>
<pre><code class="language-jsx"> const X = [];
</code></pre>
<ul>
<li>초기에는 빈 배열.</li>
</ul>
</li>
<li><p><strong><code>arr</code>와 <code>flag</code>를 순회하며 처리</strong></p>
<pre><code class="language-jsx"> arr.forEach((num, i) =&gt; { ... });
</code></pre>
<ul>
<li><code>arr[i]</code>의 값 <code>num</code>과 <code>flag[i]</code> 값을 가져와 처리.</li>
</ul>
</li>
<li><p><strong><code>flag[i]</code>가 <code>true</code>일 경우</strong></p>
<pre><code class="language-jsx"> X.push(...Array(num * 2).fill(num));
</code></pre>
<ul>
<li><code>Array(num * 2).fill(num)</code>: 길이가 <code>num * 2</code>인 배열을 만들고, <code>num</code> 값으로 채움.</li>
<li><code>push(...Array(...))</code>: 스프레드 연산자를 사용하여 배열을 <code>X</code>에 추가.</li>
</ul>
</li>
<li><p><strong><code>flag[i]</code>가 <code>false</code>일 경우</strong></p>
<pre><code class="language-jsx"> X.splice(-num, num);
</code></pre>
<ul>
<li><code>splice(-num, num)</code>: 배열의 끝에서 <code>num</code>개의 원소를 제거.</li>
</ul>
</li>
<li><p><strong>최종 결과 반환</strong></p>
<pre><code class="language-jsx"> return X;
</code></pre>
<ul>
<li>모든 연산을 마친 후 배열 <code>X</code>를 반환.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 배열의 원소만큼 추가하기]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EC%9B%90%EC%86%8C%EB%A7%8C%ED%81%BC-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0-7frl1e21</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EC%9B%90%EC%86%8C%EB%A7%8C%ED%81%BC-%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0-7frl1e21</guid>
            <pubDate>Wed, 19 Feb 2025 13:45:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181861">배열의 원소만큼 추가하기</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>아무 원소도 들어있지 않은 빈 배열 X가 있습니다. 양의 정수 배열 <code>arr</code>가 매개변수로 주어질 때, <code>arr</code>의 앞에서부터 차례대로 원소를 보면서 원소가 a라면 X의 맨 뒤에 a를 a번 추가하는 일을 반복한 뒤의 배열 X를 return 하는 solution 함수를 작성해 주세요.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 100</li>
<li>1 ≤ <code>arr</code>의 원소 ≤ 100</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>arr</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>[5, 1, 4]</td>
<td>[5, 5, 5, 5, 5, 1, 4, 4, 4, 4]</td>
</tr>
<tr>
<td>[6, 6]</td>
<td>[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]</td>
</tr>
<tr>
<td>[1]</td>
<td>[1]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>예제 1번에 대해서 a와 X를 나타내보면 다음 표와 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>a</th>
<th>X</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td>[]</td>
</tr>
<tr>
<td>5</td>
<td>[5, 5, 5, 5, 5]</td>
</tr>
<tr>
<td>1</td>
<td>[5, 5, 5, 5, 5, 1]</td>
</tr>
<tr>
<td>4</td>
<td>[5, 5, 5, 5, 5, 1, 4, 4, 4, 4]</td>
</tr>
</tbody></table>
<p><code>따라서 [5, 5, 5, 5, 5, 1, 4, 4, 4, 4]를 return 합니다.</code></p>
<p>입출력 예 #2</p>
<ul>
<li>예제 2번에 대해서 a와 X를 나타내보면 다음 표와 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>a</th>
<th>X</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td>[]</td>
</tr>
<tr>
<td>6</td>
<td>[6, 6, 6, 6, 6, 6]</td>
</tr>
<tr>
<td>6</td>
<td>[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]</td>
</tr>
</tbody></table>
<p><code>따라서 [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6]를 return 합니다.</code></p>
<p>입출력 예 #3</p>
<ul>
<li>예제 2번에 대해서 a와 X를 나타내보면 다음 표와 같습니다.</li>
</ul>
<table>
<thead>
<tr>
<th>a</th>
<th>X</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td>[]</td>
</tr>
<tr>
<td>1</td>
<td>[1]</td>
</tr>
</tbody></table>
<p><code>따라서 [1]을 return 합니다.</code></p>
<hr>
<pre><code class="language-jsx">function solution(arr) {
    return arr.flatMap((num) =&gt; Array(num).fill(num));
}
</code></pre>
<hr>
<h3 id="코드설명">코드설명</h3>
<ol>
<li><strong><code>Array(num).fill(num)</code></strong>:<ul>
<li><code>Array(num)</code>는 길이가 <code>num</code>인 빈 배열을 생성합니다.</li>
<li><code>.fill(num)</code>은 배열의 모든 요소를 <code>num</code>으로 채웁니다.</li>
<li>예: <code>Array(5).fill(5)</code> → <code>[5, 5, 5, 5, 5]</code>.</li>
</ul>
</li>
<li><strong><code>flatMap</code> 메서드</strong>:<ul>
<li><code>flatMap</code>은 각 배열 요소에 대해 콜백을 실행하여 반환된 배열을 평탄화(flatten)하여 하나의 배열로 만듭니다.</li>
<li>예: <code>[5, 1, 4].flatMap(...)</code>에서 각 요소마다 배열을 생성하고 결과를 하나의 배열로 병합합니다.</li>
<li>평탄화를 통해 중첩 배열 없이 원하는 결과를 바로 얻을 수 있습니다.</li>
</ul>
</li>
<li><strong>결과 반환</strong>:<ul>
<li>각 요소를 필요한 만큼 배열에 추가하고, 병합된 최종 배열을 반환합니다.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Lv0 - 세 개의 구분자]]></title>
            <link>https://velog.io/@moon_dev/JavaScript-Lv0-%EC%84%B8-%EA%B0%9C%EC%9D%98-%EA%B5%AC%EB%B6%84%EC%9E%90-dns3ck1t</link>
            <guid>https://velog.io/@moon_dev/JavaScript-Lv0-%EC%84%B8-%EA%B0%9C%EC%9D%98-%EA%B5%AC%EB%B6%84%EC%9E%90-dns3ck1t</guid>
            <pubDate>Tue, 18 Feb 2025 13:12:44 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181862">세 개의 구분자</a></p>
</blockquote>
<h3 id="문제-설명"><strong>문제 설명</strong></h3>
<p>임의의 문자열이 주어졌을 때 문자 &quot;a&quot;, &quot;b&quot;, &quot;c&quot;를 구분자로 사용해 문자열을 나누고자 합니다.</p>
<p>예를 들어 주어진 문자열이 &quot;baconlettucetomato&quot;라면 나눠진 문자열 목록은 [&quot;onlettu&quot;, &quot;etom&quot;, &quot;to&quot;] 가 됩니다.</p>
<p>문자열 <code>myStr</code>이 주어졌을 때 위 예시와 같이 &quot;a&quot;, &quot;b&quot;, &quot;c&quot;를 사용해 나눠진 문자열을 순서대로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.</p>
<p>단, 두 구분자 사이에 다른 문자가 없을 경우에는 아무것도 저장하지 않으며, return할 배열이 빈 배열이라면 [&quot;EMPTY&quot;]를 return 합니다.</p>
<hr>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>1 ≤ <code>myStr</code>의 길이 ≤ 1,000,000<ul>
<li><code>myStr</code>은 알파벳 소문자로 이루어진 문자열 입니다.</li>
</ul>
</li>
</ul>
<hr>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th>myStr</th>
<th>result</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;baconlettucetomato&quot;</td>
<td>[&quot;onlettu&quot;, &quot;etom&quot;, &quot;to&quot;]</td>
</tr>
<tr>
<td>&quot;abcd&quot;</td>
<td>[&quot;d&quot;]</td>
</tr>
<tr>
<td>&quot;cabab&quot;</td>
<td>[&quot;EMPTY&quot;]</td>
</tr>
</tbody></table>
<hr>
<h3 id="입출력-예-설명">입출력 예 설명</h3>
<p>입출력 예 #1</p>
<ul>
<li>문제 설명의 예시와 같습니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>&quot;c&quot; 이전에는 &quot;a&quot;, &quot;b&quot;, &quot;c&quot; 이외의 문자가 없습니다.</li>
<li>&quot;c&quot; 이후에 문자열 &quot;d&quot;가 있으므로 &quot;d&quot;를 저장합니다.</li>
<li>따라서 [&quot;d&quot;]를 return 합니다.</li>
</ul>
<p>입출력 예 #3</p>
<ul>
<li>&quot;a&quot;, &quot;b&quot;, &quot;c&quot; 이외의 문자가 존재하지 않습니다. 따라서 저장할 문자열이 없습니다.</li>
<li>따라서 [&quot;EMPTY&quot;]를 return 합니다.</li>
</ul>
<hr>
<pre><code class="language-jsx">function solution(myStr) {
   return myStr.match(/[^a-c]+/g) || [&#39;EMPTY&#39;];
}

console.log(solution(&quot;baconlettucetomato&quot;)); // [&quot;onlettu&quot;, &quot;etom&quot;, &quot;to&quot;]
console.log(solution(&quot;cabab&quot;)); // [&quot;EMPTY&quot;]
</code></pre>
<hr>
<h3 id="코드설명">코드설명</h3>
<ol>
<li><strong>정규표현식 <code>[^a-c]+</code></strong>:<ul>
<li><code>[^a-c]</code>:<ul>
<li><code>a</code>, <code>b</code>, <code>c</code>를 제외한 문자를 매칭합니다.</li>
<li><code>^</code>는 부정을 의미하며, 대괄호 안에서 사용하면 &quot;해당 범위에 포함되지 않는 문자&quot;를 나타냅니다.</li>
</ul>
</li>
<li><code>+</code>:<ul>
<li>한 번 이상 연속으로 나타나는 경우를 매칭합니다.</li>
</ul>
</li>
<li><code>/[^a-c]+/g</code>:<ul>
<li>&quot;a&quot;, &quot;b&quot;, &quot;c&quot;가 아닌 문자들의 연속된 그룹을 모두 검색합니다(<code>g</code> 플래그: 전체 검색).</li>
</ul>
</li>
</ul>
</li>
<li><strong><code>match</code> 메서드</strong>:<ul>
<li><code>myStr.match(/[^a-c]+/g)</code>는 &quot;a&quot;, &quot;b&quot;, &quot;c&quot;가 아닌 연속된 문자열들을 배열로 반환합니다.</li>
<li>매칭되는 항목이 없을 경우 <code>null</code>을 반환합니다.</li>
</ul>
</li>
<li><strong><code>|| [&#39;EMPTY&#39;]</code></strong>:<ul>
<li><code>match</code>가 <code>null</code>을 반환하면, 결과를 <code>[&#39;EMPTY&#39;]</code>로 설정합니다.</li>
<li>이를 통해 빈 배열 대신 &quot;EMPTY&quot; 문자열을 반환하도록 처리합니다.</li>
</ul>
</li>
<li><strong>결과 반환</strong>:<ul>
<li>매칭된 문자열 배열을 반환하거나, 매칭되지 않는 경우 <code>[&#39;EMPTY&#39;]</code>를 반환합니다.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
    </channel>
</rss>