<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dobby-sense.log</title>
        <link>https://velog.io/</link>
        <description>i am korean dobby</description>
        <lastBuildDate>Fri, 12 Dec 2025 03:52:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dobby-sense.log</title>
            <url>https://images.velog.io/images/dobby-sense/profile/ee358ff1-0c01-4397-a097-413fb7f27d64/소여니.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dobby-sense.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dobby-sense" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[웹접근성 pc와 모바일 각각 해야하는 이유]]></title>
            <link>https://velog.io/@dobby-sense/%EC%9B%B9%EC%A0%91%EA%B7%BC%EC%84%B1-pc%EC%99%80-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EA%B0%81%EA%B0%81-%ED%95%B4%EC%95%BC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@dobby-sense/%EC%9B%B9%EC%A0%91%EA%B7%BC%EC%84%B1-pc%EC%99%80-%EB%AA%A8%EB%B0%94%EC%9D%BC-%EA%B0%81%EA%B0%81-%ED%95%B4%EC%95%BC%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Fri, 12 Dec 2025 03:52:14 GMT</pubDate>
            <description><![CDATA[<h2 id="1-원칙-wcag-기준은-공통-→-체크리스트는-한-장으로">1. 원칙: WCAG 기준은 공통 → 체크리스트는 한 장으로</h2>
<p>웹접근성 기준(WCAG, KWCAG)은
“PC용/모바일용” 이렇게 나뉘지 않고 서비스 전체를 대상으로 합니다.</p>
<p>하나의 마스터 체크리스트/QA 시트를 만듭니다.</p>
<p>항목은 공통으로 두고,각 항목마다 PC / 모바일 결과 컬럼을 나눠서 체크하는 방식입니다.</p>
<p>예를 들면 엑셀에 이런 식:</p>
<table>
<thead>
<tr>
<th align="left">항목</th>
<th>내용</th>
<th align="center">PC 결과</th>
<th align="center">모바일 결과</th>
<th align="left">비고</th>
</tr>
</thead>
<tbody><tr>
<td align="left">1-1</td>
<td>키보드만으로 주요 기능 이용 가능</td>
<td align="center">O</td>
<td align="center">△(팝업 닫기 버튼 포커스 안 감)</td>
<td align="left">수정 필요</td>
</tr>
<tr>
<td align="left">1-2</td>
<td>포커스 이동 시 시각적 표시</td>
<td align="center">O</td>
<td align="center">O</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">1-3</td>
<td>스크린리더 제목/레이블 읽기</td>
<td align="center">△</td>
<td align="center">O</td>
<td align="left">PC h 태그 구조 수정</td>
</tr>
</tbody></table>
<p>즉, 체크 구조는 한 번 설계하고, PC/모바일은 그 안에서 각각 결과를 적는 느낌이 가장 깔끔합니다.</p>
<h2 id="2-실제-테스트는-pc모바일-따로-도는-게-맞음">2. 실제 테스트는 PC/모바일 따로 도는 게 맞음</h2>
<h3 id="pc-쪽에서-특히-볼-것">PC 쪽에서 특히 볼 것</h3>
<ul>
<li>키보드 탭 이동(포커스 트랩, 포커스 회귀)</li>
<li>스크린리더 (NVDA, JAWS, 또는 크롬Vox 등)</li>
<li>마우스와 키보드 겸용일 때 포커스가 튀는지</li>
<li>마우스 hover에만 의존하는 인터랙션 있는지(모바일 대비)</li>
</ul>
<h3 id="모바일-쪽에서-특히-볼-것">모바일 쪽에서 특히 볼 것</h3>
<ul>
<li>터치로만 조작 가능한지 (작은 터치 타겟, 간격 등)</li>
<li>스와이프 동작과 포커스 순서가 충돌 안 하는지</li>
<li>모바일 스크린리더 (TalkBack, VoiceOver)로</li>
<li>버튼/탭명 제대로 읽히는지</li>
<li>스와이프로 이동할 때 논리 순서 맞는지</li>
<li>모바일에서 떠 있는 고정 요소(고정 탭, 플로팅 버튼 등)가 스크린리더/포커스 방해 안 하는지</li>
</ul>
<h3 id="작업-순서-추천">작업 순서 추천</h3>
<ol>
<li><p>PC 기준으로 구조/ARIA/포커스 로직 다잡기</p>
<ul>
<li>시맨틱 마크업, role/aria, 포커스 회귀, 키보드 동작 등.</li>
</ul>
</li>
<li><p>모바일 브레이크포인트 + 터치/스크린리더 테스트</p>
<ul>
<li>이미 짜둔 팝업/포커스 로직이 터치 환경에서 깨지는 부분만 보정.</li>
</ul>
</li>
<li><p>최종 QA 시트</p>
<ul>
<li>각 항목에 대해 PC: O/X, 모바일: O/X 식으로 결과 기록.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[웹접근성] 공통 팝업 + 포커스 회귀 접근성]]></title>
            <link>https://velog.io/@dobby-sense/%EC%9B%B9%EC%A0%91%EA%B7%BC%EC%84%B1-%EA%B3%B5%ED%86%B5-%ED%8C%9D%EC%97%85-%ED%8F%AC%EC%BB%A4%EC%8A%A4-%ED%9A%8C%EA%B7%80-%EC%A0%91%EA%B7%BC%EC%84%B1</link>
            <guid>https://velog.io/@dobby-sense/%EC%9B%B9%EC%A0%91%EA%B7%BC%EC%84%B1-%EA%B3%B5%ED%86%B5-%ED%8C%9D%EC%97%85-%ED%8F%AC%EC%BB%A4%EC%8A%A4-%ED%9A%8C%EA%B7%80-%EC%A0%91%EA%B7%BC%EC%84%B1</guid>
            <pubDate>Thu, 04 Dec 2025 00:51:03 GMT</pubDate>
            <description><![CDATA[<h2 id="웹-접근성이란">웹 접근성이란?</h2>
<ul>
<li>장애인이나 고령자 등 다양한 사용자가 웹사이트의 정보에 비장애인과 동등하게 접근하고 이해할 수 있도록 보장하는 것을 말합니다.</li>
<li>단순히 장애인을 위한 것이 아니라, 지역, 나이, 기술 수준 등 다양한 제약을 고려하여 가능한 많은 사용자가 불편 없이 웹 서비스를 이용하도록 하는 기준입니다. </li>
</ul>
<h2 id="현-프로젝트의-웹-접근성-이슈-정리포커스-회귀-문제">현 프로젝트의 웹 접근성 이슈 정리(포커스 회귀 문제)</h2>
<p>운영 프로젝트 특성상 과거 구축 단계에서 사용하던 공통 팝업 스크립트가 계속 재사용되고 있는데, 이 과정에서 웹 접근성(특히 포커스 회귀) 관련 문제가 반복적으로 발생하고 있습니다.</p>
<p>현재 공통 팝업 JS에서 포커스 회귀를 위한 인자를 전달받도록 되어 있으나,</p>
<p><strong>- 인자 검증이 제대로 이루어지지 않거나,</strong></p>
<p><strong>- 전달받은 인자가 정상적으로 실행되지 않는 경우가 잦습니다.</strong></p>
<p>또한 팝업 가이드에 스크립트 활용 방식에 대한 명확한 기준이 없다 보니, 작업자마다</p>
<p><strong>- 인자를 사용하는 경우와 사용하지 않는 경우가 혼재되어 있고,</strong></p>
<p><strong>- 인자를 주었음에도 회귀가 정상적으로 이루어지지 않거나,</strong></p>
<p><strong>- 반대로 인자를 주지 않았는데도 우연히 회귀가 정상 동작하는 등</strong></p>
<p>로직이 일관적으로 적용되지 않는 상황입니다.</p>
<p>결과적으로, 공통 팝업 스크립트가 페이지별로 예측 불가능하게 동작하며, 접근성 검수 단계에서 포커스가 팝업 열림/닫힘 시 올바르게 이동하지 않는 문제가 지속적으로 발생하고 있습니다.</p>
<h2 id="공통팝업-가이드-작업">공통팝업 가이드 작업</h2>
<h3 id="html">HTML</h3>
<pre><code>&lt;!-- 여러 개의 열기 버튼이 있어도 공통 스크립트로 처리 --&gt;
&lt;button
    type=&quot;button&quot;
    class=&quot;btn-open-popup&quot; &lt;!--팝업 버튼 공통 클래스--&gt;
    data-popup-target=&quot;#popupFilter&quot; &lt;!--각각 팝업에 대한 데이터 속성으로 팝업 타깃--&gt;
&gt;
  필터 팝업 열기
&lt;/button&gt;

&lt;button
    type=&quot;button&quot;
    class=&quot;btn-open-popup&quot;
    data-popup-target=&quot;#popupNotice&quot;
&gt;
  안내 팝업 열기
&lt;/button&gt;

&lt;!-- ===== 팝업 1: 필터 팝업 ===== --&gt;
&lt;div
    id=&quot;popupFilter&quot;
    class=&quot;pop-dx pop_wrap point_filter_pop small_tf&quot;
    role=&quot;dialog&quot;
    aria-modal=&quot;true&quot;
    aria-labelledby=&quot;popupFilterTitle&quot;
    aria-describedby=&quot;popupFilterDesc&quot;
&gt;
  &lt;div class=&quot;pop_overlay&quot; data-popup-close=&quot;overlay&quot;&gt;&lt;/div&gt;

  &lt;article class=&quot;popup popup_type01&quot;&gt;
    &lt;h2 id=&quot;popupFilterTitle&quot;&gt;포인트 필터 설정&lt;/h2&gt;
    &lt;div id=&quot;popupFilterDesc&quot; class=&quot;popup_content&quot;&gt;
      기간, 사용처, 혜택 유형 등을 선택해 필터링할 수 있습니다.
    &lt;/div&gt;

    &lt;div class=&quot;pop_btn btn_wrap btn-wrap-dx type2&quot;&gt;
      &lt;button type=&quot;button&quot;&gt;초기화&lt;/button&gt;
      &lt;button type=&quot;button&quot; class=&quot;ui-pop-close&quot; data-popup-close=&quot;button&quot;&gt;적용&lt;/button&gt;
    &lt;/div&gt;

    &lt;button type=&quot;button&quot; class=&quot;btn_close ui-pop-close&quot; data-popup-close=&quot;button&quot;&gt;
      &lt;span&gt;팝업 닫기&lt;/span&gt;
    &lt;/button&gt;
  &lt;/article&gt;
&lt;/div&gt;

&lt;!-- ===== 팝업 2: 안내 팝업 ===== --&gt;
&lt;div
    id=&quot;popupNotice&quot;
    class=&quot;pop-dx pop_wrap&quot;
    role=&quot;dialog&quot;
    aria-modal=&quot;true&quot;
    aria-labelledby=&quot;popupNoticeTitle&quot;
    aria-describedby=&quot;popupNoticeDesc&quot;
&gt;
  &lt;div class=&quot;pop_overlay&quot; data-popup-close=&quot;overlay&quot;&gt;&lt;/div&gt;

  &lt;article class=&quot;popup popup_type01&quot;&gt;
    &lt;h2 id=&quot;popupNoticeTitle&quot;&gt;안내사항&lt;/h2&gt;
    &lt;div id=&quot;popupNoticeDesc&quot; class=&quot;popup_content&quot;&gt;
      시스템 점검으로 오늘 밤 1시부터 3시까지 일부 서비스 이용이 제한됩니다.
    &lt;/div&gt;
    &lt;div class=&quot;btn-wrap-dx&quot;&gt;
      &lt;button type=&quot;button&quot; class=&quot;ui-pop-close&quot; data-popup-close=&quot;button&quot;&gt;
        확인
      &lt;/button&gt;
    &lt;/div&gt;
    &lt;button type=&quot;button&quot; class=&quot;btn_close ui-pop-close&quot; data-popup-close=&quot;button&quot;&gt;
      &lt;span&gt;팝업 닫기&lt;/span&gt;
    &lt;/button&gt;
  &lt;/article&gt;
&lt;/div&gt;</code></pre><h3 id="css">CSS</h3>
<pre><code>body {
    margin: 0;
    padding: 40px;
    line-height: 1.5;
}

h1 {
    margin-top: 0;
    margin-bottom: 24px;
}

button {
    font-family: inherit;
}

/* ==== 팝업 열기 버튼 ==== */
.btn-open-popup {
    padding: 10px 16px;
    border-radius: 4px;
    border: 1px solid #ddd;
    background: #fff;
    cursor: pointer;
    margin-right: 8px;
}

/* ==== 공통 팝업 레이아웃 ==== */
.pop_wrap {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}
.pop_wrap.is-open {
    display: flex;
}

.pop_overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
}

.popup {
    position: relative;
    z-index: 1;
    background: #fff;
    border-radius: 8px;
    padding: 24px 24px 18px;
    max-width: 420px;
    width: 90%;
    box-shadow: 0 8px 20px rgba(0,0,0,0.2);
}

.popup h2 {
    margin: 0 0 8px;
    font-size: 18px;
}

.popup .popup_content {
    font-size: 14px;
    margin-bottom: 16px;
}

.btn-wrap-dx {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 12px;
}

.btn-wrap-dx button {
    padding: 8px 14px;
    border-radius: 4px;
    border: 1px solid #ddd;
    background: #f8f8f8;
    cursor: pointer;
    font-size: 14px;
}

/* 우측 상단 닫기 버튼 */
.btn_close {
    position: absolute;
    top: 8px;
    right: 8px;
    border: none;
    background: none;
    cursor: pointer;
    padding: 6px;
}
.btn_close span {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.btn_close::before {
    content: &quot;✕&quot;;
    font-size: 16px;
    line-height: 1;
}</code></pre><h3 id="javascript">Javascript</h3>
<pre><code>(function () {
  // ===== 공통: 포커스 가능한 요소 셀렉터 =====
  const FOCUSABLE_SELECTOR = [
    &#39;a[href]&#39;,
    &#39;area[href]&#39;,
    &#39;button:not([disabled])&#39;,
    &#39;input:not([disabled]):not([type=&quot;hidden&quot;])&#39;,
    &#39;select:not([disabled])&#39;,
    &#39;textarea:not([disabled])&#39;,
    &#39;[tabindex]:not([tabindex=&quot;-1&quot;])&#39;
  ].join(&#39;,&#39;);

  // 팝업별로 &quot;어디서 열렸는지&quot; 기억하는 Map ,, &lt;-- 포커스 회귀인자를 따로 받지 않고 처리
  const focusPopUpMemory = new Map(); // popupElement -&gt; triggerButton

  const openPopUpButtons = document.querySelectorAll(&#39;.btn-open-popup&#39;);

  openPopUpButtons.forEach((btn) =&gt; {
    btn.addEventListener(&#39;click&#39;, () =&gt; {
      const target = btn.getAttribute(&#39;data-popup-target&#39;);
      if (!target) return;
      const popup = document.querySelector(target);
      if (!popup) return;

      openPopup(popup, btn);
    });
  });

  function openPopup(popup, triggerButton) {
    // 1) 팝업을 어디서 열었는지 기억 (포커스 회귀용 ★핵심)
    focusPopUpMemory.set(popup, triggerButton);

    // 2) 팝업 열기
    popup.classList.add(&#39;is-open&#39;);

    // 3) 팝업 내부의 첫 번째 포커스 가능한 요소로 포커스 이동
    const focusableEls = popup.querySelectorAll(FOCUSABLE_SELECTOR);
    if (focusableEls.length &gt; 0) {
      focusableEls[0].focus();
    } else {
      // 차선책: popup 자체에 tabindex를 주고 포커스
      popup.setAttribute(&#39;tabindex&#39;, &#39;-1&#39;);
      popup.focus();
    }

    // 4) ESC, Tab 포커스 트랩, etc
    popup.addEventListener(&#39;keydown&#39;, handleKeyDown);
    // 5) 오버레이 / 닫기 버튼 공통 처리
    const overlay = popup.querySelector(&#39;[data-popup-close=&quot;overlay&quot;]&#39;);
    if (overlay) {
      overlay.addEventListener(&#39;click&#39;, handleCloseEvent);
    }
    const closeButtons = popup.querySelectorAll(&#39;[data-popup-close=&quot;button&quot;]&#39;);
    closeButtons.forEach((btn) =&gt; {
      btn.addEventListener(&#39;click&#39;, handleCloseEvent);
    });
  }

  function closePopup(popup) {
    popup.classList.remove(&#39;is-open&#39;);
    popup.removeEventListener(&#39;keydown&#39;, handleKeyDown);

    const overlay = popup.querySelector(&#39;[data-popup-close=&quot;overlay&quot;]&#39;);
    if (overlay) {
      overlay.removeEventListener(&#39;click&#39;, handleCloseEvent);
    }
    const closeButtons = popup.querySelectorAll(&#39;[data-popup-close=&quot;button&quot;]&#39;);
    closeButtons.forEach((btn) =&gt; {
      btn.removeEventListener(&#39;click&#39;, handleCloseEvent);
    });

    // ★★★ 포커스 회귀: 이 팝업을 열었던 버튼으로 포커스 이동 ★★★
    const triggerButton = focusPopUpMemory.get(popup);
    if (triggerButton &amp;&amp; typeof triggerButton.focus === &#39;function&#39;) {
      triggerButton.focus();
    }

    // 기록 제거
    focusPopUpMemory.delete(popup);
  }

  function handleCloseEvent(event) {
    const popup = event.currentTarget.closest(&#39;[role=&quot;dialog&quot;]&#39;);
    if (!popup) return;
    closePopup(popup);
  }

  function handleKeyDown(event) {
    const popup = event.currentTarget;
    const focusableEls = popup.querySelectorAll(FOCUSABLE_SELECTOR);
    const first = focusableEls[0];
    const last = focusableEls[focusableEls.length - 1];

    // ESC로 닫기
    if (event.key === &#39;Escape&#39; || event.key === &#39;Esc&#39;) {
      event.preventDefault();
      closePopup(popup);
      return;
    }

    // Tab 포커스 트랩 (팝업 안에서만 돌도록)
    if (event.key === &#39;Tab&#39;) {
      if (focusableEls.length === 0) {
        event.preventDefault();
        return;
      }

      if (event.shiftKey) {
        if (document.activeElement === first) {
          event.preventDefault();
          last.focus();
        }
      } else {
        if (document.activeElement === last) {
          event.preventDefault();
          first.focus();
        }
      }
    }
  }
})();
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV0 뒤집힌 문자열]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV0-%EB%92%A4%EC%A7%91%ED%9E%8C-%EB%AC%B8%EC%9E%90%EC%97%B4</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV0-%EB%92%A4%EC%A7%91%ED%9E%8C-%EB%AC%B8%EC%9E%90%EC%97%B4</guid>
            <pubDate>Wed, 05 Nov 2025 00:43:38 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>문자열 my_string이 매개변수로 주어집니다. my_string을 거꾸로 뒤집은 문자열을 return하도록 solution 함수를 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>1 ≤ my_string의 길이 ≤ 1,000</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">my_string</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&quot;jaron&quot;</td>
<td align="center">&quot;noraj&quot;</td>
</tr>
<tr>
<td align="center">&quot;bread&quot;</td>
<td align="center">&quot;daerb&quot;</td>
</tr>
</tbody></table>
<h4 id="입출력-예-설명">[입출력 예 설명]</h4>
<p>입출력 예 #1</p>
<p>my_string이 &quot;jaron&quot;이므로 거꾸로 뒤집은 &quot;noraj&quot;를 return합니다.
입출력 예 #2</p>
<p>my_string이 &quot;bread&quot;이므로 거꾸로 뒤집은 &quot;daerb&quot;를 return합니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(my_string) {
    var answer = &#39;&#39;;
    answer = my_string.split(&quot;&quot;).reverse().join(&quot;&quot;);
    return answer;
}</code></pre><h4 id="리팩토링">[리팩토링]</h4>
<pre><code>//스프레드 문법!!
function solution(my_string) {
    var answer = [...my_string].reverse().join(&quot;&quot;);
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV0 배열 뒤집기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV0-%EB%B0%B0%EC%97%B4-%EB%92%A4%EC%A7%91%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV0-%EB%B0%B0%EC%97%B4-%EB%92%A4%EC%A7%91%EA%B8%B0</guid>
            <pubDate>Wed, 05 Nov 2025 00:32:27 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>정수가 들어 있는 배열 num_list가 매개변수로 주어집니다. num_list의 원소의 순서를 거꾸로 뒤집은 배열을 return하도록 solution 함수를 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>1 ≤ num_list의 길이 ≤ 1,000</li>
<li>0 ≤ num_list의 원소 ≤ 1,000</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">num_list</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[1, 2, 3, 4, 5]</td>
<td align="center">[5, 4, 3, 2, 1]</td>
</tr>
<tr>
<td align="center">[1, 1, 1, 1, 1, 2]</td>
<td align="center">[2, 1, 1, 1, 1, 1]</td>
</tr>
<tr>
<td align="center">[1, 0, 1, 1, 1, 3, 5]</td>
<td align="center">[5, 3, 1, 1, 1, 0, 1]</td>
</tr>
</tbody></table>
<h4 id="입출력-예-설명">[입출력 예 설명]</h4>
<p>입출력 예 #1</p>
<p>num_list가 [1, 2, 3, 4, 5]이므로 순서를 거꾸로 뒤집은 배열 [5, 4, 3, 2, 1]을 return합니다.
입출력 예 #2</p>
<p>num_list가 [1, 1, 1, 1, 1, 2]이므로 순서를 거꾸로 뒤집은 배열 [2, 1, 1, 1, 1, 1]을 return합니다.
입출력 예 #3</p>
<p>num_list가 [1, 0, 1, 1, 1, 3, 5]이므로 순서를 거꾸로 뒤집은 배열 [5, 3, 1, 1, 1, 0, 1]을 return합니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(num_list) {
    var answer = [];
    answer = num_list.reverse();
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 2021 KAKAO BLIND RECRUITMENT 신규 아이디 추천]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-2021-KAKAO-BLIND-RECRUITMENT-%EC%8B%A0%EA%B7%9C-%EC%95%84%EC%9D%B4%EB%94%94-%EC%B6%94%EC%B2%9C</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-2021-KAKAO-BLIND-RECRUITMENT-%EC%8B%A0%EA%B7%9C-%EC%95%84%EC%9D%B4%EB%94%94-%EC%B6%94%EC%B2%9C</guid>
            <pubDate>Tue, 04 Nov 2025 00:02:41 GMT</pubDate>
            <description><![CDATA[<h3 id="문제설명">[문제설명]</h3>
<p>카카오에 입사한 신입 개발자 네오는 &quot;카카오계정개발팀&quot;에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. &quot;네오&quot;에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.</p>
<p>아이디의 길이는 3자 이상 15자 이하여야 합니다.
아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.
&quot;네오&quot;는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,</p>
<blockquote>
</blockquote>
<p>1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 &quot;a&quot;를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
     만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.</p>
<p>예를 들어, new_id 값이 &quot;...!@BaT#*..y.abcdefghijklm&quot; 라면, 위 7단계를 거치고 나면 new_id는 아래와 같이 변경됩니다.</p>
<p>1단계 대문자 &#39;B&#39;와 &#39;T&#39;가 소문자 &#39;b&#39;와 &#39;t&#39;로 바뀌었습니다.</p>
<blockquote>
<p>&quot;...!@BaT#<em>..y.abcdefghijklm&quot; → &quot;...!@bat#</em>..y.abcdefghijklm&quot;</p>
</blockquote>
<p>2단계 &#39;!&#39;, &#39;@&#39;, &#39;#&#39;, &#39;*&#39; 문자가 제거되었습니다.</p>
<blockquote>
<p>&quot;...!@bat#*..y.abcdefghijklm&quot; → &quot;...bat..y.abcdefghijklm&quot;</p>
</blockquote>
<p>3단계 &#39;...&#39;와 &#39;..&#39; 가 &#39;.&#39;로 바뀌었습니다.</p>
<blockquote>
<p>&quot;...bat..y.abcdefghijklm&quot; → &quot;.bat.y.abcdefghijklm&quot;</p>
</blockquote>
<p>4단계 아이디의 처음에 위치한 &#39;.&#39;가 제거되었습니다.</p>
<blockquote>
<p>&quot;.bat.y.abcdefghijklm&quot; → &quot;bat.y.abcdefghijklm&quot;</p>
</blockquote>
<p>5단계 아이디가 빈 문자열이 아니므로 변화가 없습니다.</p>
<blockquote>
<p>&quot;bat.y.abcdefghijklm&quot; → &quot;bat.y.abcdefghijklm&quot;</p>
</blockquote>
<p>6단계 아이디의 길이가 16자 이상이므로, 처음 15자를 제외한 나머지 문자들이 제거되었습니다.</p>
<blockquote>
<p>&quot;bat.y.abcdefghijklm&quot; → &quot;bat.y.abcdefghi&quot;</p>
</blockquote>
<p>7단계 아이디의 길이가 2자 이하가 아니므로 변화가 없습니다.</p>
<blockquote>
<p>&quot;bat.y.abcdefghi&quot; → &quot;bat.y.abcdefghi&quot;</p>
</blockquote>
<p>따라서 신규 유저가 입력한 new_id가 &quot;...!@BaT#*..y.abcdefghijklm&quot;일 때, 네오의 프로그램이 추천하는 새로운 아이디는 &quot;bat.y.abcdefghi&quot; 입니다.</p>
<h3 id="문제">[문제]</h3>
<p>신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, &quot;네오&quot;가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.</p>
<h3 id="제한">[제한]</h3>
<p>new_id는 길이 1 이상 1,000 이하인 문자열입니다.
new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.
new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&amp;*()=+[{]}:?,&lt;&gt;/ 로 한정됩니다.</p>
<h3 id="입출력-예">[입출력 예]</h3>
<p><img src="https://velog.velcdn.com/images/dobby-sense/post/4219d1aa-3b39-413b-91c7-9fb6bd963c15/image.png" alt=""></p>
<h4 id="입출력-예-설명">[입출력 예 설명]</h4>
<p>입출력 예 #1
문제의 예시와 같습니다.</p>
<p>입출력 예 #2
7단계를 거치는 동안 new_id가 변화하는 과정은 아래와 같습니다.</p>
<p>1단계 변화 없습니다.
2단계 &quot;z-+.^.&quot; → &quot;z-..&quot;
3단계 &quot;z-..&quot; → &quot;z-.&quot;
4단계 &quot;z-.&quot; → &quot;z-&quot;
5단계 변화 없습니다.
6단계 변화 없습니다.
7단계 &quot;z-&quot; → &quot;z--&quot;</p>
<p>입출력 예 #3
7단계를 거치는 동안 new_id가 변화하는 과정은 아래와 같습니다.</p>
<p>1단계 변화 없습니다.
2단계 &quot;=.=&quot; → &quot;.&quot;
3단계 변화 없습니다.
4단계 &quot;.&quot; → &quot;&quot; (new_id가 빈 문자열이 되었습니다.)
5단계 &quot;&quot; → &quot;a&quot;
6단계 변화 없습니다.
7단계 &quot;a&quot; → &quot;aaa&quot;</p>
<p>입출력 예 #4
1단계에서 7단계까지 거치는 동안 new_id(&quot;123_.def&quot;)는 변하지 않습니다. 즉, new_id가 처음부터 카카오의 아이디 규칙에 맞습니다.</p>
<p>입출력 예 #5
1단계 변화 없습니다.
2단계 변화 없습니다.
3단계 변화 없습니다.
4단계 변화 없습니다.
5단계 변화 없습니다.
6단계 &quot;abcdefghijklmn.p&quot; → &quot;abcdefghijklmn.&quot; → &quot;abcdefghijklmn&quot;
7단계 변화 없습니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(new_id) {
    let answer = &#39;&#39;;
    // 1단계
    const firstStep = new_id.toLowerCase();
    let newIdArr = firstStep.split(&quot;&quot;);
    // 2단계
    newIdArr = newIdArr.filter(ch =&gt; /[a-z0-9._-]/.test(ch));
    // 3단계, 4단계
    let newIdStr = newIdArr.join(&quot;&quot;).replace(/\.{2,}/g, &quot;.&quot;).replace(/^\.|\.$/g, &quot;&quot;);
    if (newIdStr === &quot;&quot;) newIdStr = &quot;a&quot;;

    // 6단계
    if(newIdStr.length &gt;= 16){
      newIdStr = newIdStr.slice(0, 15).replace(/\.$/g, &quot;&quot;); 
    }
    // 7단계
    if(newIdStr.length &lt;= 2){
      while(newIdStr.length &lt; 3){
        newIdStr += newIdStr[newIdStr.length - 1]; 
      }   
    }

    answer = newIdStr; 
    return answer;
}</code></pre><h4 id="자-이제-다시-시작">자 이제 다시 시작~!!</h4>
<p><strong>[codesandbox]</strong>
<a href="https://codepen.io/soyean7979/pen/dPGQweq?editors=0011">https://codepen.io/soyean7979/pen/dPGQweq?editors=0011</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV0 자릿수 더하기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV0-%EC%9E%90%EB%A6%BF%EC%88%98-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV0-%EC%9E%90%EB%A6%BF%EC%88%98-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 07 Oct 2022 06:38:39 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>정수 n이 매개변수로 주어질 때 n의 각 자리 숫자의 합을 return하도록 solution 함수를 완성해주세요</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>0 ≤ n ≤ 1,000,000</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">n</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1234</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">930211</td>
<td align="center">16</td>
</tr>
</tbody></table>
<h4 id="입출력-예-설명">[입출력 예 설명]</h4>
<p>입출력 예 #1
1 + 2 + 3 + 4 = 10을 return합니다.</p>
<p>입출력 예 #2
9 + 3 + 0 + 2 + 1 + 1 = 16을 return합니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(n) {
  let answer = 0;
  const arr = (n + &quot;&quot;).split(&quot;&quot;);

  for (let i = 0; i &lt; arr.length; i++) {
    answer += Number(arr[i]);
  }
  return answer;
}</code></pre><h4 id="자-이제-다시-시작">자 이제 다시 시작~!!</h4>
<p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/kodingteseuteu-46-7vfnsh">https://codesandbox.io/s/kodingteseuteu-46-7vfnsh</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 소수 찾기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%86%8C%EC%88%98-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%86%8C%EC%88%98-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Tue, 14 Jun 2022 08:07:59 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.</p>
<p>소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.
(1은 소수가 아닙니다.)</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>n은 2이상 1000000이하의 자연수입니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">n</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">10</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">3</td>
</tr>
</tbody></table>
<h4 id="입출력-예-설명">[입출력 예 설명]</h4>
<p>입출력 예 #1
1부터 10 사이의 소수는 [2,3,5,7] 4개가 존재하므로 4를 반환</p>
<p>입출력 예 #2
1부터 5 사이의 소수는 [2,3,5] 3개가 존재하므로 3를 반환</p>
<h4 id="answer">[answer]</h4>
<pre><code>function isPrime(num) {
  for (let i = 2; i &lt;= Math.sqrt(num); i++) {
    if (num % i === 0) return false;
  }
  return true;
}

function solution(n) {
  let answer = 0;
  for (let i = 2; i &lt;= n; i++) {
    if (isPrime(i)) answer++;
  }
  return answer;
}</code></pre><h4 id="효율성-체크에서-땡">효율성 체크에서 땡!...</h4>
<p>소수판별함수인 isPrime() 함수를 이전에 풀었던 메소드를 가져와서 풀었는데, 효율성에서 땡땡땡!!! 아직 그 이유를 파악하지 못했다...ㅠㅠ</p>
<pre><code> function isPrime(sum) {
    if (sum === 2) return true;
    for (let i = 2; i &lt; sum; i++) {
      if (sum % i === 0) return false;
    }
    return true;
  }</code></pre><p>코드를 돌리는데에 있어서 그렇게 차이가 없어 보이는데,, 왜... 그런걸까요?? 아시는분??ㅠㅠ </p>
<p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-45-hjngc4">https://codesandbox.io/s/coding-test-daily-45-hjngc4</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 시저 암호]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%8B%9C%EC%A0%80-%EC%95%94%ED%98%B8</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%8B%9C%EC%A0%80-%EC%95%94%ED%98%B8</guid>
            <pubDate>Tue, 14 Jun 2022 06:05:59 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 &quot;AB&quot;는 1만큼 밀면 &quot;BC&quot;가 되고, 3만큼 밀면 &quot;DE&quot;가 됩니다. &quot;z&quot;는 1만큼 밀면 &quot;a&quot;가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>공백은 아무리 밀어도 공백입니다.</li>
<li>s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.</li>
<li>s의 길이는 8000이하입니다.</li>
<li>n은 1 이상, 25이하인 자연수입니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">s</th>
<th align="center">n</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&quot;AB&quot;</td>
<td align="center">1</td>
<td align="center">&quot;BC&quot;</td>
</tr>
<tr>
<td align="center">&quot;z&quot;</td>
<td align="center">1</td>
<td align="center">&quot;a&quot;</td>
</tr>
<tr>
<td align="center">&quot;a B z&quot;</td>
<td align="center">4</td>
<td align="center">&quot;e F d&quot;</td>
</tr>
</tbody></table>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(s, n) {
  let answer = [];
  let arr = s.split(&quot;&quot;);
  arr.map((v) =&gt; {
    let stringASCII = v.charCodeAt();
    if (stringASCII === 32) {
      stringASCII += &quot; &quot;;
    } else if (stringASCII &gt;= 65 &amp;&amp; stringASCII &lt;= 90) {
      stringASCII += n;
      if (stringASCII &gt; 90) {
        stringASCII -= 26;
      }
    } else if (stringASCII &gt;= 97 &amp;&amp; stringASCII &lt;= 122) {
      stringASCII += n;
      if (stringASCII &gt; 122) {
        stringASCII -= 26;
      }
    }
    answer += String.fromCharCode(stringASCII);
  });
  return answer;
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-44-ifzbzh">https://codesandbox.io/s/coding-test-daily-44-ifzbzh</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 약수의 합]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%95%BD%EC%88%98%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%95%BD%EC%88%98%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Sun, 12 Jun 2022 09:23:00 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>정수 n을 입력받아 n의 약수를 모두 더한 값을 리턴하는 함수, solution을 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>n은 0 이상 3000이하인 정수입니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">n</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">12</td>
<td align="center">28</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">6</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>입출력 예 #1
12의 약수는 1, 2, 3, 4, 6, 12입니다. 이를 모두 더하면 28입니다.</p>
<p>입출력 예 #2
5의 약수는 1, 5입니다. 이를 모두 더하면 6입니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(n) {
  let answer = 0;
  for (let i = 1; i &lt;= n; i++) {
    if (n % i === 0) {
      answer += i;
    }
  }
  return answer;
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-43-yz6miw">https://codesandbox.io/s/coding-test-daily-43-yz6miw</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 정수 제곱근 판별]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%A0%95%EC%88%98-%EC%A0%9C%EA%B3%B1%EA%B7%BC-%ED%8C%90%EB%B3%84</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%A0%95%EC%88%98-%EC%A0%9C%EA%B3%B1%EA%B7%BC-%ED%8C%90%EB%B3%84</guid>
            <pubDate>Fri, 10 Jun 2022 05:32:37 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>임의의 양의 정수 n에 대해, n이 어떤 양의 정수 x의 제곱인지 아닌지 판단하려 합니다.
n이 양의 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 양의 정수 x의 제곱이 아니라면 -1을 리턴하는 함수를 완성하세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>n은 1이상, 50000000000000 이하인 양의 정수입니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">n</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">121</td>
<td align="center">144</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">-1</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>입출력 예#1
121은 양의 정수 11의 제곱이므로, (11+1)를 제곱한 144를 리턴합니다.</p>
<p>입출력 예#2
3은 양의 정수의 제곱이 아니므로, -1을 리턴합니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(n) {
  let answer = 0;
  let sqrt = Math.sqrt(n);
  if (sqrt % 1 !== 0) {
    answer = -1;
  } else {
    answer = Math.pow(sqrt + 1, 2);
  }
  return answer;
}</code></pre><h4 id="정수-제곱근">정수 제곱근</h4>
<h5 id="mathsqrt">Math.sqrt()</h5>
<p>숫자의 제곱근을 반환한다.</p>
<pre><code>Math.sqrt(9); // 3
Math.sqrt(2); // 1.414213562373095

Math.sqrt(1);  // 1
Math.sqrt(0);  // 0
Math.sqrt(-1); // NaN</code></pre><h5 id="mathpowbase-exponent">Math.pow(base, exponent)</h5>
<p>base(밑값)에 exponent(밑을 제곱하기 위해 사용하는 지수)를 제곱한 값을 반환한다.</p>
<pre><code>// 간단한 예
Math.pow(7, 2);    // 49 :: 7의 2제곱근
Math.pow(7, 3);    // 343 :: 7의 3제곱근
Math.pow(2, 10);   // 1024
// 분수 지수
Math.pow(4, 0.5);  // 2 (4의 제곱근)
Math.pow(8, 1/3);  // 2 (8의 세제곱근)
Math.pow(2, 0.5);  // 1.4142135623730951 (2의 제곱근)
Math.pow(2, 1/3);  // 1.2599210498948732 (2의 세제곱근)
// 양의 지수
Math.pow(7, -2);   // 0.02040816326530612 (1/49)
Math.pow(8, -1/3); // 0.5
// 양의 밑
Math.pow(-7, 2);   // 49 (제곱의 결과값은 양수입니다.)
Math.pow(-7, 3);   // -343 (세제곱은 음수가 될 수 있습니다.)
Math.pow(-7, 0.5); // NaN (음수는 실제 제곱근을 가지지 않습니다.)
// &quot;짝수&quot;와 &quot;홀수&quot; 근이 서로 가깝게 놓여 있고
// 부동소수점 정밀도의 한계로 인해,
// 밑이 음수이며 지수가 분수라면 언제나 NaN을 반환합니다.
Math.pow(-7, 1/3); // NaN</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-42-og79i2">https://codesandbox.io/s/coding-test-daily-42-og79i2</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 이상한 문자 만들기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%9D%B4%EC%83%81%ED%95%9C-%EB%AC%B8%EC%9E%90-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%9D%B4%EC%83%81%ED%95%9C-%EB%AC%B8%EC%9E%90-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Thu, 09 Jun 2022 07:25:10 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성하세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단해야합니다.</li>
<li>첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리해야 합니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">s</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&quot;try hello world&quot;</td>
<td align="center">&quot;TrY HeLlO WoRlD&quot;</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>&quot;try hello world&quot;는 세 단어 &quot;try&quot;, &quot;hello&quot;, &quot;world&quot;로 구성되어 있습니다. 각 단어의 짝수번째 문자를 대문자로, 홀수번째 문자를 소문자로 바꾸면 &quot;TrY&quot;, &quot;HeLlO&quot;, &quot;WoRlD&quot;입니다. 따라서 &quot;TrY HeLlO WoRlD&quot; 를 리턴합니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(s) {
  let answer = [];
  const arr = s.split(&quot; &quot;);
  arr.forEach((val, idx) =&gt; {
    const chk = arr[idx].split(&quot;&quot;);
    let mapArr = chk.map((el, i) =&gt; {
      if (i % 2 === 0) {
        return el.toUpperCase();
      } else {
        return el.toLowerCase();
      }
    });
    answer.push(mapArr.join(&quot;&quot;));
  });
  return answer.join(&quot; &quot;);
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-41-whf65q">https://codesandbox.io/s/coding-test-daily-41-whf65q</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 최대공약수와 최소공배수]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98%EC%99%80-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98%EC%99%80-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98</guid>
            <pubDate>Wed, 08 Jun 2022 03:26:44 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수, solution을 완성해 보세요. 배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다. 예를 들어 두 수 3, 12의 최대공약수는 3, 최소공배수는 12이므로 solution(3, 12)는 [3, 12]를 반환해야 합니다.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>두 수는 1이상 1000000이하의 자연수입니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">n</th>
<th align="center">m</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">3</td>
<td align="center">12</td>
<td align="center">[3, 12]</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">5</td>
<td align="center">[1, 10]</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>입출력 예 #1
위의 설명과 같습니다.</p>
<p>입출력 예 #2
자연수 2와 5의 최대공약수는 1, 최소공배수는 10이므로 [1, 10]을 리턴해야 합니다.</p>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(n, m) {
  return [gcd(n, m), lcm(n, m)];
}
//최대공약수 유클리드 호제법
let gcd = (n, m) =&gt; {
  if (m === 0) return n;
  return n &gt; m ? gcd(m, n % m) : gcd(n, m % n);
};
//최소 공배수 = 주어진 인자들의 곱 후 최대공약수로 나누기
let lcm = (n, m) =&gt; {
  return (n * m) / gcd(n, m);
};</code></pre><h3 id="문제의-해석">문제의 해석</h3>
<h4 id="최대공약수를-구하는-방법---유클리드-호제법">최대공약수를 구하는 방법 - &lt;유클리드 호제법&gt;</h4>
<ul>
<li>유클리드 호제법의 원리<blockquote>
<p>1) 두 수 중에서 큰 수를 작은 수로 나눈다.
2-1) 나누고 난 나머지가 0 이면, 작은 수가 최대 공약수가 된다
2-2) 나머지가 0이 아니라면, 작은 수를 다시 나머지로 나눈다.
3) 나머지가 0이 될때까지 반복하면, 그 수가 최대공약수가 된다.</p>
</blockquote>
</li>
</ul>
<h4 id="최소공배수를-구하는-방법">최소공배수를 구하는 방법</h4>
<ul>
<li>주어진 두 수의 곱하기를 한 후 최대공약수로 나누면 된다.</li>
</ul>
<p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-40-2rml4r">https://codesandbox.io/s/coding-test-daily-40-2rml4r</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV2 최솟값 만들기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV2-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV2-%EC%B5%9C%EC%86%9F%EA%B0%92-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Tue, 07 Jun 2022 04:07:44 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>길이가 같은 배열 A, B 두개가 있습니다. 각 배열은 자연수로 이루어져 있습니다.
배열 A, B에서 각각 한 개의 숫자를 뽑아 두 수를 곱합니다. 이러한 과정을 배열의 길이만큼 반복하며, 두 수를 곱한 값을 누적하여 더합니다. 이때 최종적으로 누적된 값이 최소가 되도록 만드는 것이 목표입니다. (단, 각 배열에서 k번째 숫자를 뽑았다면 다음에 k번째 숫자는 다시 뽑을 수 없습니다.)</p>
<p>예를 들어 A = [1, 4, 2] , B = [5, 4, 4] 라면</p>
<ul>
<li>A에서 첫번째 숫자인 1, B에서 첫번째 숫자인 5를 뽑아 곱하여 더합니다. (누적된 값 : 0 + 5(1x5) = 5)</li>
<li>A에서 두번째 숫자인 4, B에서 세번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 5 + 16(4x4) = 21)</li>
<li>A에서 세번째 숫자인 2, B에서 두번째 숫자인 4를 뽑아 곱하여 더합니다. (누적된 값 : 21 + 8(2x4) = 29)
즉, 이 경우가 최소가 되므로 29를 return 합니다.</li>
</ul>
<p>배열 A, B가 주어질 때 최종적으로 누적된 최솟값을 return 하는 solution 함수를 완성해 주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>배열 A, B의 크기 : 1,000 이하의 자연수</li>
<li>배열 A, B의 원소의 크기 : 1,000 이하의 자연수</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">A</th>
<th align="center">B</th>
<th align="center">answer</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[1, 4, 2]</td>
<td align="center">[5, 4, 4]</td>
<td align="center">29</td>
</tr>
<tr>
<td align="center">[1,2]</td>
<td align="center">[3,4]</td>
<td align="center">10</td>
</tr>
</tbody></table>
<h4 id="answer">[answer]</h4>
<pre><code>function solution(A, B) {
  let answer = 0;
  A = A.sort((a, b) =&gt; a - b); // 오름차순 정렬
  B = B.sort((a, b) =&gt; b - a); // 내림차순 정렬
  for (let i = 0; i &lt; A.length; i++) {
    answer += A[i] * B[i];
  }
  return answer;
}</code></pre><h3 id="문제의-해석">문제의 해석</h3>
<p>&quot;최종적으로 누적된 값이 최소가 되도록 만드는 것이 목표&quot; 이므로, 
A배열에서의 최솟값 * B배열에서의 최댓값을 구하면 최소가 된다...(알아두자...)
A는 오름차순 정렬을 하고 B는 내림차순 정렬을 해야한다.</p>
<p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-39-ovrlpv">https://codesandbox.io/s/coding-test-daily-39-ovrlpv</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV2 JadenCase 문자열 만들기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV2-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-cuurirju</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV2-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-cuurirju</guid>
            <pubDate>Mon, 06 Jun 2022 05:44:39 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)
문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>s는 길이 1 이상 200 이하인 문자열입니다.</li>
<li>s는 알파벳과 숫자, 공백문자(&quot; &quot;)로 이루어져 있습니다.<ul>
<li>숫자는 단어의 첫 문자로만 나옵니다.</li>
<li>숫자로만 이루어진 단어는 없습니다.</li>
<li>공백문자가 연속해서 나올 수 있습니다.</li>
</ul>
</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">s</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&quot;3people unFollowed me&quot;</td>
<td align="center">&quot;3people Unfollowed Me&quot;</td>
</tr>
<tr>
<td align="center">&quot;for the last week&quot;</td>
<td align="center">&quot;For The Last Week&quot;</td>
</tr>
</tbody></table>
<h4 id="첫번째-답안-----땡">첫번째 답안 ---&gt; 땡!</h4>
<pre><code>function solution(s) {
  let arr = s.split(&quot; &quot;);
  let answer = arr.map((e) =&gt; {
    let str = e.split(&quot;&quot;);
    str[0] = str[0].toUpperCase();
    return str.join(&quot;&quot;);
  });
  return answer.join(&quot; &quot;);
}</code></pre><h4 id="answer">[answer]</h4>
<pre><code>function solution(s) {
  let arr = s.toLowerCase().split(&quot; &quot;);
  let answer = arr
    .map((e) =&gt; {
      let str = e.split(&quot;&quot;);
      if (str[0] != null) {
        str[0] = str[0].toUpperCase();
      }
      return str.join(&quot;&quot;);
    })
    .join(&quot; &quot;);
  return answer;
}</code></pre><h4 id="난-왜-틀렸을까">난 왜 틀렸을까?</h4>
<p>그동안 왜 틀렸는지 고민만 해보다가 구글링을 해보았다. 
&quot;문자열 s, 맨앞 맨뒤 공백인 경우도 있다....&quot;
그래서 if문 예외처리를 꼭 해줘야 한다...</p>
<p><a href="https://velog.io/@sso/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-JavaScript-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0">[출처 sso님]</a></p>
<p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-37-nh9965">https://codesandbox.io/s/coding-test-daily-37-nh9965</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV2 최댓값과 최솟값]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV2-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV2-JadenCase-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 04 Jun 2022 05:58:19 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>문자열 s에는 공백으로 구분된 숫자들이 저장되어 있습니다. str에 나타나는 숫자 중 최소값과 최대값을 찾아 이를 &quot;(최소값) (최대값)&quot;형태의 문자열을 반환하는 함수, solution을 완성하세요.
예를들어 s가 &quot;1 2 3 4&quot;라면 &quot;1 4&quot;를 리턴하고, &quot;-1 -2 -3 -4&quot;라면 &quot;-4 -1&quot;을 리턴하면 됩니다.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>s에는 둘 이상의 정수가 공백으로 구분되어 있습니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">s</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&quot;1 2 3 4&quot;</td>
<td align="center">&quot;1 4&quot;</td>
</tr>
<tr>
<td align="center">&quot;-1 -2 -3 -4&quot;</td>
<td align="center">&quot;-4 -1&quot;</td>
</tr>
<tr>
<td align="center">&quot;-1 -1&quot;</td>
<td align="center">&quot;-1 -1&quot;</td>
</tr>
</tbody></table>
<h4 id="첫번째-답안-----땡">첫번째 답안 ---&gt; 땡!</h4>
<pre><code>function solution(s) {
  const arr = s.split(&quot; &quot;);
  const maxNum = Math.max(...arr);
  const minNum = Math.min(...arr);
  const answer = minNum + &quot; &quot; + maxNum;
  return answer;
}</code></pre><h4 id="다른-사람-풀이-리팩토링">다른 사람 풀이, 리팩토링</h4>
<pre><code>function solution(s) {
  const arr = s.split(&quot; &quot;);
  return Math.min(...arr) + &quot; &quot; + Math.max(...arr);
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-38-8q8394">https://codesandbox.io/s/coding-test-daily-38-8q8394</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 없는 숫자 더하기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%97%86%EB%8A%94-%EC%88%AB%EC%9E%90-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%97%86%EB%8A%94-%EC%88%AB%EC%9E%90-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 31 May 2022 07:52:51 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>0부터 9까지의 숫자 중 일부가 들어있는 정수 배열 numbers가 매개변수로 주어집니다. numbers에서 찾을 수 없는 0부터 9까지의 숫자를 모두 찾아 더한 수를 return 하도록 solution 함수를 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>1 ≤ numbers의 길이 ≤ 9<ul>
<li>0 ≤ numbers의 모든 원소 ≤ 9</li>
<li>numbers의 모든 원소는 서로 다릅니다.</li>
</ul>
</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">numbers</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[1,2,3,4,6,7,8,0]</td>
<td align="center">14</td>
</tr>
<tr>
<td align="center">[5,8,4,0,6,7,9]</td>
<td align="center">6</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>입출력 예 #1</p>
<ul>
<li>5, 9가 numbers에 없으므로, 5 + 9 = 14를 return 해야 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>1, 2, 3이 numbers에 없으므로, 1 + 2 + 3 = 6을 return 해야 합니다.</li>
</ul>
<h4 id="answersjs">[answers.js]</h4>
<pre><code>function solution(numbers) {
  let answer = -1;
  const basicNum = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
  let filterArr = basicNum.filter((e) =&gt; !numbers.includes(e));
  answer = filterArr.reduce((num1, num2) =&gt; {
    return num1 + num2;
  }, 0);
  return answer;
}</code></pre><h4 id="다른-사람-풀이">다른 사람 풀이</h4>
<p>0-9 까지 전체 합에서 numbers 숫자 합을 빼면 된다니.........</p>
<pre><code>function solution(numbers) {
    return 45 - numbers.reduce((cur, acc) =&gt; cur + acc, 0);
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-36-kl93dm">https://codesandbox.io/s/coding-test-daily-36-kl93dm</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[javascript array methods]]></title>
            <link>https://velog.io/@dobby-sense/javascript-array-methods</link>
            <guid>https://velog.io/@dobby-sense/javascript-array-methods</guid>
            <pubDate>Tue, 31 May 2022 07:34:53 GMT</pubDate>
            <description><![CDATA[<h2 id="array-배열">Array [&#39;배열&#39;]</h2>
<p>키를 사용해 식별할 수 있는 값을 담은 컬렉션은 객체라는 자료구조를 이용해 저장하는데, 객체만으로도 다양한 작업을 할 수 있다.</p>
<p>그런데 개발을 진행하다 보면 첫 번째 요소, 두 번째 요소, 세 번째 요소 등과 같이 순서가 있는 컬렉션이 필요할 때가 생기곤 한다. 사용자나 물건, HTML 요소 목록같이 일목요연하게 순서를 만들어 정렬하기 위해서 말이다.</p>
<p>순서가 있는 컬렉션을 다뤄야 할 때 객체를 사용하면 순서와 관련된 메서드가 없어 그다지 편리하지 않다. 객체는 태생이 순서를 고려하지 않고 만들어진 자료구조이기 때문에 객체를 이용하면 새로운 프로퍼티를 기존 프로퍼티 ‘사이에’ 끼워 넣는 것도 불가능하다.</p>
<p>이럴 땐 순서가 있는 컬렉션을 저장할 때 쓰는 자료구조인 배열을 사용할 수 있다.</p>
<p>Array 메소드를 알아보자</p>
<h3 id="join">join()</h3>
<p>배열의 모든 요소를 하나의 문자열로 반환</p>
<pre><code>const fruits = [&#39;apple&#39;, &#39;banana&#39;, &#39;orange&#39;];
const answer = fruits.join(&#39; and &#39;);
//apple and banana and orange</code></pre><h3 id="split">split()</h3>
<p>문자열을 배열로 반환</p>
<pre><code>const fruits2 = &#39;🍎, 🥝, 🍌, 🍒&#39;;
const answer2 = fruits2.split(&#39;,&#39;);

//[&#39;🍎&#39;, &#39;🥝&#39;, &#39;🍌&#39;, &#39;🍒&#39;]</code></pre><h3 id="splice">splice()</h3>
<p>원본 배열에서 기존 요소를 삭제 또는 교체하여 원본 배열을 변경하고 제거된 배열 반환
start : 추출 시작점에 대한 인덱스
end : 추출을 종료할 기준의 인덱스, end 이전 까지 요소만 추출</p>
<h3 id="slice">slice()</h3>
<p>처음부터 끝 점까지의 복사본을 새로운 배열 객체로 반환, 즉 원본 배열 수정 되지 않음
start : 추출 시작점에 대한 인덱스
end : 추출을 종료할 기준의 인덱스, end 이전 까지 요소만 추출</p>
<pre><code>const array = [1, 2, 3, 4, 5];
const answer4 = array.splice(0, 2);

// array
// [3, 4, 5]

// answer4
// [1, 2]

const answer41 = array.slice(1, 3); 
// [2, 3]</code></pre><p>객체로 이루어진 배열 예시로 진행해보자</p>
<pre><code>students = [
    {​​​ 
        name: &#39;A&#39;, 
        age: 29, 
        enrolled: true, 
        score: 45
    }​​​​​​​​​​,
    {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 
        name: &#39;B&#39;, 
        age: 28, 
        enrolled: false, 
        score: 80
    }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​,
    {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 
        name: &#39;C&#39;, 
        age: 30, 
        enrolled: true, 
        score: 90
    }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​,
    {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 
        name: &#39;D&#39;, 
        age: 40, 
        enrolled: false, 
        score: 66
    }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​,
    {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 
        name: &#39;E&#39;, 
        age: 18, 
        enrolled: true, 
        score: 88
    }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​,
]</code></pre><h3 id="find">find()</h3>
<p>메서드는 주어진 판별 함수를 만족하는 첫 번째 요소의 값을 반환</p>
<pre><code>const answer5 = students.find((e) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
    return e.score &gt;= 79;
}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​);

// {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ name: &#39;B&#39;, age: 28, enrolled: false, score: 80 }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​</code></pre><h3 id="filter">filter()</h3>
<p>주어진 조건에 충족하는 요소를 모두 반환 (조건에 false면 버림)</p>
<pre><code>const answer6 = students.filter((e) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
    return e.enrolled;
}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​);

// 
{​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ name: &#39;A&#39;, age: 29, enrolled: true, score: 45}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
{​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ name: &#39;C&#39;, age: 30, enrolled: true, score: 90}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
{​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ name: &#39;E&#39;, age: 18, enrolled: true, score: 88}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​</code></pre><h3 id="map">map()</h3>
<p>요소를 각각 순서대로 돌아서 조건에 충족하는 결과값을 모아 새로운 배열로 반환</p>
<pre><code>const answer7 = students.map((e) =&gt; e.score * 3);

// [135, 240, 270, 198, 264]</code></pre><h3 id="foreach">forEach()</h3>
<p>각 배열 요소를 한번씩 돌아~, 배열을 변형하지않고, 콜백함수로 변형할 수 있다. 반복문
 for문을 사용했을 때보다 직관적이며 간결.</p>
<pre><code> for (let i = 0; i &lt; students.length; i++) {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  //console.log(students[i]);
 }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

students.forEach((e) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  //console.log(e);
 }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​);</code></pre><h3 id="some">some()</h3>
<p>배열의 요소 중 하나라도 true 면 true 반환</p>
<h3 id="every">every()</h3>
<p>배열의 요소 모두가 true여야만 true 반환, 아니면 false 반환</p>
<pre><code>const answer8 = students.some((e) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  return e.score &lt; 50;
}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​);
// true

const answer9 = students.every((e) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  return e.score &lt; 50;
}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​);
// false</code></pre><h3 id="indexof">indexOf()</h3>
<p>배열에서 지정된 요소를 찾을 수 있는 첫 번째 인덱스를 반환하고 ,
존재하지 않으면 -1</p>
<pre><code>const superheroes = [&#39;아이언맨&#39;, &#39;캡틴 아메리카&#39;, &#39;토르&#39;, &#39;닥터 스트레인지&#39;];
const index = superheroes.indexOf(&#39;토르&#39;);

//2</code></pre><h3 id="findeindex">findeIndex()</h3>
<p>주어진 판별 함수를 만족하는 배열의 첫 번째 요소에 대한 인덱스를 반환, 
존재하지 않으면 -1</p>
<pre><code>const aaa = students.findIndex((e) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  return e.age &gt; 29;
}​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​);

//2</code></pre><h3 id="reduce">reduce()</h3>
<p>배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 
하나의 결과값을 반환</p>
<pre><code>reduce((누적값, 현잿값, 인덱스, 요소) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ return 결과 }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​, 초깃값);
초깃값을 적어주지 않으면 자동으로 초깃값이 0번째 인덱스의 값이 됨

 const average = students.reduce((accumulator, current, index) =&gt; {​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
  if(index === students.length - 1){​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ // 마지막 index 이면
    return (accumulator + current.score) / students.length
  }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
    // console.log(&#39;---------------&#39;);
    // console.log(accumulator);
    // console.log(current.score)
    return accumulator + current.score
 }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​,0);

 // 73.8</code></pre><h3 id="sort">sort()</h3>
<p>배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환</p>
<pre><code> // 오름 차순
 const answer15 = students.map((student) =&gt; student.score).sort();
 //[45, 66, 80, 88, 90]</code></pre><pre><code> //내림 차순
 const answer16 = students
 .map((student) =&gt; student.score)
 .sort((a, b) =&gt; {​​​​​​​​​​​​​​​​​​​​​​
    return b - a;
 }​​​​​​​​​​​​​​​​​​​​​​);

 //[90, 88, 80, 66, 45]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 음양 더하기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%9D%8C%EC%96%91-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%9D%8C%EC%96%91-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 18 May 2022 04:18:03 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>어떤 정수들이 있습니다. 이 정수들의 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어집니다. 실제 정수들의 합을 구하여 return 하도록 solution 함수를 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>absolutes의 길이는 1 이상 1,000 이하입니다.<ul>
<li>absolutes의 모든 수는 각각 1 이상 1,000 이하입니다.</li>
</ul>
</li>
<li>signs의 길이는 absolutes의 길이와 같습니다.<ul>
<li>signs[i] 가 참이면 absolutes[i] 의 실제 정수가 양수임을, 그렇지 않으면 음수임을 의미합니다.</li>
</ul>
</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">absolutes</th>
<th align="center">signs</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[4,7,12]</td>
<td align="center">[true,false,true]</td>
<td align="center">9</td>
</tr>
<tr>
<td align="center">[1,2,3]</td>
<td align="center">[false,false,true]</td>
<td align="center">0</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>입출력 예 #1</p>
<ul>
<li>signs가 [true,false,true] 이므로, 실제 수들의 값은 각각 4, -7, 12입니다.</li>
<li>따라서 세 수의 합인 9를 return 해야 합니다.</li>
</ul>
<p>입출력 예 #2</p>
<ul>
<li>signs가 [false,false,true] 이므로, 실제 수들의 값은 각각 -1, -2, 3입니다.</li>
<li>따라서 세 수의 합인 0을 return 해야 합니다.</li>
</ul>
<h4 id="answersjs">[answers.js]</h4>
<pre><code>function solution(absolutes, signs) {
  let answer = 0;
  for (let i = 0; i &lt; absolutes.length; i++) {
    if (signs[i]) {
      answer += absolutes[i];
    } else {
      answer -= absolutes[i];
    }
  }
  return answer;
}</code></pre><h4 id="reduce-사용시">reduce 사용시</h4>
<pre><code>function solution(absolutes, signs) {
  let answer = 0;
  answer = absolutes.reduce(
    (acc, val, i) =&gt; (signs[i] ? acc + val : acc + -val),
    0
  );
  return answer;
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-35-9uhyky">https://codesandbox.io/s/coding-test-daily-35-9uhyky</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 소수만들기]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%86%8C%EC%88%98%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%86%8C%EC%88%98%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Tue, 17 May 2022 05:48:11 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>nums에 들어있는 숫자의 개수는 3개 이상 50개 이하입니다.</li>
<li>nums의 각 원소는 1 이상 1,000 이하의 자연수이며, 중복된 숫자가 들어있지 않습니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">nums</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[1,2,3,4]</td>
<td align="center">1</td>
</tr>
<tr>
<td align="center">[1,2,7,6,4]</td>
<td align="center">4</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>입출력 예 #1
[1,2,4]를 이용해서 7을 만들 수 있습니다.</p>
<p>입출력 예 #2
[1,2,4]를 이용해서 7을 만들 수 있습니다.
[1,4,6]을 이용해서 11을 만들 수 있습니다.
[2,4,7]을 이용해서 13을 만들 수 있습니다.
[4,6,7]을 이용해서 17을 만들 수 있습니다.</p>
<h4 id="answersjs">[answers.js]</h4>
<pre><code>function solution(nums) {
  let answer = 0;
  for (let i = 0; i &lt; nums.length; i++) {
    for (let j = i + 1; j &lt; nums.length; j++) {
      for (let f = j + 1; f &lt; nums.length; f++) {
        let sum = nums[i] + nums[j] + nums[f];
        if (isPrime(sum)) {
          answer++;
        }
      }
    }
  }

  function isPrime(sum) {
    if (sum === 2) return true;
    for (let i = 2; i &lt; sum; i++) {
      if (sum % i === 0) return false;
    }
    return true;
  }

  return answer;
}</code></pre><h3 id="소수란">소수란??</h3>
<pre><code>소수란, 1과 자신만으로 나누어 떨어지는 1보다 큰 양수를 뜻한다
ex) 2,5,11,71</code></pre><h3 id="소수-판별-함수">소수 판별 함수</h3>
<pre><code>function isPrime(number) {
  if (number === 2) return true; // 2부터 소수 판별이 가능한 숫자이기에 2는 소수니깐 true
  for (let i = 2; i &lt; number; i++) { // 2부터 주어진 인자까지 소수 판별 for문
    if (number % i === 0) return false; //나누어지면,false
  }
  return true; //for문을 다 돌고 빠져나올때까지 나누어지는 수가 없다면 true
}</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-34-yq8htd?file=/src/index.js">https://codesandbox.io/s/coding-test-daily-34-yq8htd?file=/src/index.js</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODING TEST]::LV1 완주하지 못한 선수]]></title>
            <link>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</link>
            <guid>https://velog.io/@dobby-sense/CODING-TESTLV1-%EC%99%84%EC%A3%BC%ED%95%98%EC%A7%80-%EB%AA%BB%ED%95%9C-%EC%84%A0%EC%88%98</guid>
            <pubDate>Mon, 16 May 2022 02:10:07 GMT</pubDate>
            <description><![CDATA[<h3 id="문제">[문제]</h3>
<p>수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.</p>
<p>마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.</p>
<h3 id="제한">[제한]</h3>
<ul>
<li>마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.</li>
<li>completion의 길이는 participant의 길이보다 1 작습니다.</li>
<li>참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.</li>
<li>참가자 중에는 동명이인이 있을 수 있습니다.</li>
</ul>
<h3 id="입출력-예">[입출력 예]</h3>
<table>
<thead>
<tr>
<th align="center">participant</th>
<th align="center">completion</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[&quot;leo&quot;, &quot;kiki&quot;, &quot;eden&quot;]</td>
<td align="center">[&quot;eden&quot;, &quot;kiki&quot;]</td>
<td align="center">&quot;leo&quot;</td>
</tr>
<tr>
<td align="center">[&quot;marina&quot;, &quot;josipa&quot;, &quot;nikola&quot;, &quot;vinko&quot;, &quot;filipa&quot;]</td>
<td align="center">[&quot;josipa&quot;, &quot;filipa&quot;, &quot;marina&quot;, &quot;nikola&quot;]</td>
<td align="center">&quot;vinko&quot;</td>
</tr>
<tr>
<td align="center">[&quot;mislav&quot;, &quot;stanko&quot;, &quot;mislav&quot;, &quot;ana&quot;]</td>
<td align="center">[&quot;stanko&quot;, &quot;ana&quot;, &quot;mislav&quot;]</td>
<td align="center">&quot;mislav&quot;</td>
</tr>
</tbody></table>
<h3 id="입출력-예-설명">[입출력 예 설명]</h3>
<p>예제 #1
&quot;leo&quot;는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.</p>
<p>예제 #2
&quot;vinko&quot;는 참여자 명단에는 있지만, 완주자 명단에는 없기 때문에 완주하지 못했습니다.</p>
<p>예제 #3
&quot;mislav&quot;는 참여자 명단에는 두 명이 있지만, 완주자 명단에는 한 명밖에 없기 때문에 한명은 완주하지 못했습니다.</p>
<h4 id="나의-첫-풀이---땡">나의 첫 풀이 - 땡!</h4>
<pre><code>function solution(participant, completion) {
  const answer = participant.filter((v, i) =&gt; {
    if (!completion.includes(v) || participant.indexOf(v) !== i) return v;
  });
  console.log(&quot;정답&quot;, answer.toString());
  return answer.toString();
}

solution([&quot;mislav&quot;, &quot;stanko&quot;, &quot;mislav&quot;, &quot;ana&quot;], [&quot;stanko&quot;, &quot;ana&quot;, &quot;mislav&quot;]);</code></pre><h4 id="answersjs">[answers.js]</h4>
<pre><code>function solution(participant, completion) {
  participant.sort();
  completion.sort();
  let answer = [];
  for (let i = 0; i &lt; participant.length; i++) {
    if (participant[i] !== completion[i]) {
      answer = participant[i];
      return answer;
    }
  }
}

solution([&quot;mislav&quot;, &quot;stanko&quot;, &quot;mislav&quot;, &quot;ana&quot;], [&quot;stanko&quot;, &quot;ana&quot;, &quot;mislav&quot;]);</code></pre><p>** ansers.js 에서...**</p>
<pre><code>sort 후 participant와 completion 의 index를 비교하면 될 일이었다... 
효율성과 정확성테스트... ㅜㅜ</code></pre><p><strong>[codesandbox]</strong>
<a href="https://codesandbox.io/s/coding-test-daily-33-p2f927">https://codesandbox.io/s/coding-test-daily-33-p2f927</a></p>
]]></description>
        </item>
    </channel>
</rss>