<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>lee-goeun.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 21 Feb 2024 08:12:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>lee-goeun.log</title>
            <url>https://velog.velcdn.com/images/lee-goeun/profile/bb99301b-7279-40ab-adf0-cb0ecb442284/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. lee-goeun.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/lee-goeun" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[C# + asp.net 용어 정리 모음집.zip]]></title>
            <link>https://velog.io/@lee-goeun/C-asp.net-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%AA%A8%EC%9D%8C%EC%A7%91.zip</link>
            <guid>https://velog.io/@lee-goeun/C-asp.net-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%AA%A8%EC%9D%8C%EC%A7%91.zip</guid>
            <pubDate>Wed, 21 Feb 2024 08:12:23 GMT</pubDate>
            <description><![CDATA[<p><em>들어가기 앞서..</em></p>
<blockquote>
<p> c#을 사용하는 이유 ? 
    C를 근간으로 하는 마이크로소프트에서 개발한 객체 지향 언어로, 대용량 데이터 처리 시 빠르게 수행된다는 장점이 있다.
    파이썬의 경우 빠르게 개발된다는 장점이 있지만 파일 변환해야 한다는 측면에서 속도가 느려지는 단점이 있다.
    이러한 이유(객체 지향 + 보안 + 속도)들로 빠르게 처리하고자 하는 프로젝트에서 C#을 선택하지 않았나 싶음.</p>
</blockquote>
<h1 id="aspnet">asp.net</h1>
<h3 id="함수이름">함수이름</h3>
<p>** 1. ViewBag ( View + Bag ) :**
    뷰의 가방. 컨트롤러에서 뷰를 반환하기 전에 뷰의 가방에 데이터를 넣어주면 뷰에서 가방에 있는 데이터를 꺼내 사용할 수 있음.
    ViewBag.변수명 = 값</p>
<p>** 2. Resoucres : **
    다국어 사용 자원. 다국어 별로 파일을 만들어 입력값 지정하면 가져다 사용 가능.</p>
<p>** 3. Html : **
    3-1. Partial(&quot;ViewName&quot;) : 
            VeiwEngine에 의해 ViewName에 해당하는 View를 찾아 해당 View를 Parsing하여 MvcHtmlString의 형태로 반환함.</p>
<p>3-2. ActionLink(htmlHelper, linkText, actionName) : 
            지정된 링크 텍스트 및 작업에 대한 앵커 요소를 반환.</p>
<p>3-3. AntiForgeryToken() : 
            token 형식으로 formMethod로 전달 할 수 있음.</p>
<p>3-4. BeginForm(htmlHelper, actionName, controllerName, routeValues, method): 
            데이터를 삽입, 수정, 삭제할 때 폼 데이터를 보내는 메서드.</p>
<p>3-5. ValidationSummary(bool excludeFieldErrors, string message, object htmlAttributes) : 
            excludeFieldErrors == true ? 필드 수준 유효성 검사 오류 메세지 제외.
            유효성 검사 해주는 메서드.</p>
<p>3-6. TextBox(htmlHelper, string name, object value, string format, object htmlAttributes) : 
            텍스트 입력 요소 반환.</p>
<p>** 4. RenderBody : **
    공통 레이아웃 사용 시, 변경되는 Layout은 RenderBody로 삽입하여 사용.
    Layout 지정 -&gt; Layout = &#39;경로 설정&#39;</p>
<p>** 5. Url : **
    5-1. Action(string actionName, string controllerName, System.Web.RouteValueDictionary routeValues) :
            routeValues -&gt; 경로의 매개 변수가 들어 있는 개체</p>
<p>** 6. Request : **
    6-1. IsAuthenticated :
        요청 보내는 클라이언트가 인증되었는 지 여부 확인 ( bool 타입 ) </p>
<p>** 7. User : **
    7-1. IsInRole : 
        현재 사용자가 특별한 역할이 있는지 확인 ( bool 타입 )</p>
<p>** 8. String : **
    8-1. IsNullOrEmpty: 
        빈 값이거나 null이면 true 반환, 아니면 false</p>
<h3 id="구조">구조</h3>
<p>** MVC : **
    URL Mapping (App_Start &gt; RouteConfig ): 
        url 구조 -&gt; &quot;Controller 이름 / ActionResult (액션) / 값&quot;</p>
<h1 id="c">C#</h1>
<p><strong>1. [Atuhorize] :</strong>
해당 구성 요소 인증 사용자에 대한 엑세스를 제한함.</p>
<p>*<em>2. View(&quot;Model&quot;): *</em>
해당 페이지로 인자값 가지고 전달. html 파일에서 Model로 인자값 받음.</p>
<p>*<em>3. TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) : *</em>
컨트롤러의 현재 값 공급자, 접두사, 제외할 속성 목록의 값을 사용하여 지정된 모델 인스턴스를 업데이트함. </p>
<p><strong>4. [ValidateAntiForgeryToken]:</strong>
 데이터 전송 시, 데이터 값의 위변조를 막기 위해 토큰값 일치 여부를 확인.</p>
<p>** 5. SelectList(System.Collections.IEnumerable items, string dataValueField, string dataTextField, string data dataGroupField, object selectedValue): **
목록에 지정된 항목에 데이터 값 필드, 데이터 텍스트 필드, 데이터 그룹 필드 및 선택한 값을 사용하여 SelectList 클래스의 새 인스턴스를 초기화함.</p>
<p>*<em>6. FileStream(String, FileMode, FileAccess) : *</em>
지정된 경로, 생성 모드 및 읽기/쓰기 권한을 사용하여 FileStream 클래스의 새 인스턴스를 초기화함.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TypeScript 이란 무엇일까]]></title>
            <link>https://velog.io/@lee-goeun/TypeScript-%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</link>
            <guid>https://velog.io/@lee-goeun/TypeScript-%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</guid>
            <pubDate>Wed, 21 Feb 2024 05:30:36 GMT</pubDate>
            <description><![CDATA[<p><em>Java에서 NodeJs로 리팩토링 하게 되면서 Java에서 구현되어 있던 interface를 NodeJs에서 사용하고 싶었는데 JavaScript에서 interface를 검색해보니 interface는 TypeScript에서만 쓸 수 있는 거 같았다. 좀 더 견고한 코딩을 하기 위해서는 TypeScript를 피할 수 없는 거 같아 이번 기회에 Crawling 기능을 NodeJs로 구현하면서 TypeScript 개념을 정리해보기로 했다. 나도 이제 고오급,,은 아니지만 중급(?)개발자까지 될 수 있을 것인가...</em></p>
<h2 id="개념">개념</h2>
<p> 타입스크립트(typeScript)는 자바스크립트(JavaScript)를 기반으로 정적 타입 문법을 추가한 프로그래밍 언어이다.</p>
<h2 id="javascript-vs-typescript">JavaScript vs TypeScript</h2>
<h2 id="기본-문법">기본 문법</h2>
<h4 id="기본-타입">기본 타입</h4>
<p>: Boolean, Number, String, Object, Array, Tuple, Enum, Any, Void, Null, Undefined, Never</p>
<ul>
<li><p>변수 타입 설정</p>
<pre><code>let str:string = &#39;hi&#39;;
let num:numger = 100;

let arr : Array = [1,2,3];
let arr2: number[] = [1,2,3];

let obj:object = {};
let obj2:{name:string, age:number} : {
   name :&#39;hoho&#39;,
   age : 22
};</code></pre></li>
<li><p>함수 타입 설정</p>
<pre><code>function add(a:number, b:number):number{
   return a+b;
 }
 //optional parameter
 function log(a:string, b?:string, c?:string){
   console.log(a);
 }</code></pre></li>
<li><p>Tuple : 배열의 타입 순서와 배열 길이를 지정할 수 있는 타입</p>
<pre><code>var arr:[string,number] = [&#39;aa&#39;, 100];</code></pre></li>
<li><p>Enum : Number 또는 String 값 집합에 고정된 이름을 부여할 수 있는 타입. 값의 종류가 일정한 범위로 정해져 있는 경우에 유용하다. 기본적으로 0부터 시작하며 값은 1씩 증가한다.</p>
<pre><code>enum Shoes{
 Nike = &#39;나이키&#39;,
 Adidas = &#39;아디다스&#39;
}</code></pre></li>
<li><p>Any : 모든 데이터 타입을 허용</p>
</li>
<li><p>Void : 변수에는 undefined와 null만 할당하고 함수에는 리턴 값을 설정할 수 없는 타입.</p>
</li>
<li><p>Never : 특정 값이 절대 발생할 수 없을 때 사용</p>
</li>
</ul>
<h4 id="인터페이스">인터페이스</h4>
<pre><code>    interface User {
        age : number;
        name : string;
    }   </code></pre><ul>
<li><p>변수와 함수에 활용한 인터페이스</p>
<pre><code>  var person:User ={
      age:30,
      name:&#39;aa&#39;
  }

  function getUser(user:User){
      console.log(user);
  }</code></pre></li>
<li><p>인덱싱</p>
<pre><code>  interface StringArray{
      [index:number]: string;
  }

  var arr2:StringArray = [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;];
  arr2[0]=10; //error;</code></pre><ul>
<li><p>딕셔너리 패턴</p>
<pre><code> interface StringRegexDictionary{
    [key:string]: RegExp
}

var obj:StringRegexDictionary = {
    cssFile : /\.css$/,
    jsFile : &#39;a&#39; // Error
}

obj[&#39;cssFile&#39;] = /\.css$/&#39;,
obj[&#39;jsFile&#39;] = &#39;a&#39; // Error</code></pre></li>
<li><p>인터페이스 확장</p>
<pre><code>  interface Person{
    name : string;
    age : number;
}

interface User extends Person{
    language : string;
}</code></pre><br/>

</li>
</ul>
</li>
</ul>
<h4 id="오퍼레이터">오퍼레이터</h4>
<ul>
<li><p>Union 타입 : 자바스크립트의 OR 연산자와 같은 의미의 타입. Union 타입으로 지정하면 각 타입의 공통된(보장된) 속성에만 접근 가능하다.</p>
<pre><code>   function askSomeone(someone: Developer2 | Person){
          console.log(someone);
   }</code></pre><ul>
<li>Intersaction 타입 : 자바스크립트의 AND 연산자와 같은 의미의 타입. 각각의 모든 타입이 포함된 객체를 넘기지 않으면 에러가 발생.<pre><code>function askSomenone(someone: Developer &amp; Person){
console.log(someone);
}</code></pre><br/>
#### 제네릭
한 가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트를 생성하는데 사용. 제네릭이란 타입을 마치 함수의 파라미터처럼 사용하는 것을 의미한다.
``` 
function logText<T> (text:T):T{
return text;
}

</li>
</ul>
<p>logText<string>(&quot;aa&quot;);
logText<number>(100);</p>
<pre><code>
&lt;br/&gt;
</code></pre></li>
</ul>
<h4 id="타입-추론">타입 추론</h4>
<p>  : 타입스크립트가 코드를 해석하는 과정.</p>
<pre><code>      var a = true;
      a = 100; //Error</code></pre><p>   -&gt; 해당 코드가 a 변수를 Boolean 타입으로 추론했기 때문에 Number타입을 할당하면 에러가 발생한다.
   -&gt; 가장 적절한 타입(Best Common Type) : 배열에 담긴 값들을 추론하여 Union타입으로 묶어나가는 것을 말한다.</p>
<pre><code>         var arr = [1, 2, true];</code></pre><p>   TypeScript는 해당 코드의 타입을 Number | Boolean으로 정의한다.</p>
<ul>
<li><p>인터페이스와 제네릭을 이용한 타입 추론 방식</p>
<pre><code>interface Dropdown&lt;T&gt;{
    value:T,
    text:&#39;String&#39;
}

var items:Dropdown&lt;boolean&gt;{
    value:true,
    text:&#39;aa&#39;
}</code></pre><br/>

</li>
</ul>
<h4 id=""></h4>
<p>🧐❓TypeScript에 type을 지정하지 않으면 어떻게 될까?</p>
<h2 id="nodejs에서-typescript-사용하기">NodeJs에서 TypeScript 사용하기</h2>
<ul>
<li>관련 모듈 설치<ul>
<li>@types/node : 모듈은 node에서 사용되는 TypeScript의 타입 정의를 가져오는 것이다.
=&gt; 명령어 : npm(yarn) add @tyeps/node</li>
<li>typescript : TypeScript 모듈이다.
=&gt; 명령어 : npm(yarn) add typescript</li>
<li>ts-node : 개발용으로 </li>
</ul>
</li>
</ul>
<p>참고사이트 : 
    <a href="https://offbyone.tistory.com/445">https://offbyone.tistory.com/445</a>
    <a href="https://www.samsungsds.com/kr/insights/typescript.html">https://www.samsungsds.com/kr/insights/typescript.html</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파이썬] 문법 정리]]></title>
            <link>https://velog.io/@lee-goeun/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@lee-goeun/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 12 Dec 2023 09:50:32 GMT</pubDate>
            <description><![CDATA[<ul>
<li>sort
a = list()
a.sort(key= lambda x : (x[0], -x[1]))
=&gt; 첫번째 값에서는 오름차순, 두번째 값에서는 내림차순 정렬이 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]우박수열 정적분]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%9A%B0%EB%B0%95%EC%88%98%EC%97%B4-%EC%A0%95%EC%A0%81%EB%B6%84</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%9A%B0%EB%B0%95%EC%88%98%EC%97%B4-%EC%A0%95%EC%A0%81%EB%B6%84</guid>
            <pubDate>Sun, 30 Jul 2023 05:37:54 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/134239">https://school.programmers.co.kr/learn/courses/30/lessons/134239</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>콜라츠 추측이란 로타르 콜라츠(Lothar Collatz)가 1937년에 제기한 추측으로 모든 자연수 n에 대해 다음 작업을 반복하면 항상 1로 만들 수 있다는 추측입니다.</p>
</blockquote>
<pre><code>1-1. 입력된 수가 짝수라면 2로 나눕니다.
1-2. 입력된 수가 홀수라면 3을 곱하고 1을 더합니다.
2.결과로 나온 수가 1보다 크다면 1번 작업을 반복합니다.
예를 들어 주어진 수가 5 라면 5 ⇒ 16 ⇒ 8 ⇒ 4 ⇒2 ⇒ 1 이되어 총 5번만에 1이 됩니다.</code></pre><blockquote>
</blockquote>
<p>수가 커졌다 작아지기를 반복하는 모습이 비구름에서 빗방울이 오르락내리락하며 우박이 되는 모습과 비슷하다고 하여 우박수 또는 우박수열로 불리기도 합니다. 현재 이 추측이 참인지 거짓인지 증명되지 않았지만 약 1해까지의 수에서 반례가 없음이 밝혀져 있습니다.</p>
<blockquote>
</blockquote>
<p>은지는 우박수열을 좌표 평면 위에 꺾은선 그래프로 나타내보려고 합니다. 초항이 K인 우박수열이 있다면, x = 0일때 y = K이고 다음 우박수는 x = 1에 표시합니다. 이런 식으로 우박수가 1이 될 때까지 점들을 찍고 인접한 점들끼리 직선으로 연결하면 다음과 같이 꺾은선 그래프를 만들 수 있습니다.
<img src="https://velog.velcdn.com/images/lee-goeun/post/c75969a9-1213-4dc0-84ae-f912213cfbec/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>은지는 이렇게 만든 꺾은선 그래프를 정적분 해보고 싶어졌습니다. x에 대한 어떤 범위 [a, b]가 주어진다면 이 범위에 대한 정적분 결과는 꺾은선 그래프와 x = a, x = b, y = 0 으로 둘러 쌓인 공간의 면적과 같습니다. 은지는 이것을 우박수열 정적분이라고 정의하였고 다양한 구간에 대해서 우박수열 정적분을 해보려고 합니다.</p>
<blockquote>
</blockquote>
<p>단, 우박수열 그래프의 가로축 길이를 미리 알 수 없기 때문에 구간의 시작은 음이 아닌 정수, 구간의 끝은 양이 아닌 정수로 표현합니다. 이는 각각 꺾은선 그래프가 시작하는 점과 끝나는 점의 x좌표에 대한 상대적인 오프셋을 의미합니다.</p>
<blockquote>
</blockquote>
<p>예를 들어, 5를 초항으로 하는 우박수열은 5 ⇒ 16 ⇒ 8 ⇒ 4 ⇒ 2 ⇒ 1 입니다. 이를 좌표 평면으로 옮기면 (0, 5), (1, 16), (2, 8), (3, 4), (4, 2), (5, 1) 에 점이 찍히고 점들을 연결하면 꺾은선 그래프가 나옵니다. 이를 [0,0] 구간에 대해 정적분 한다면 전체 구간에 대한 정적분이며, [1,-2] 구간에 대해 정적분 한다면 1 ≤ x ≤ 3인 구간에 대한 정적분입니다.</p>
<blockquote>
</blockquote>
<p>우박수의 초항 k와, 정적분을 구하는 구간들의 목록 ranges가 주어졌을 때 정적분의 결과 목록을 return 하도록 solution을 완성해주세요. 단, 주어진 구간의 시작점이 끝점보다 커서 유효하지 않은 구간이 주어질 수 있으며 이때의 정적분 결과는 -1로 정의합니다.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>2 ≤ k ≤ 10,000</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ ranges의 길이 ≤ 10,000<ul>
<li>ranges의 원소는 [a, b] 형식이며 0 ≤ a &lt; 200, -200 &lt; b ≤ 0 입니다.</li>
</ul>
</li>
<li>주어진 모든 입력에 대해 정적분의 결과는 227 을 넘지 않습니다.</li>
<li>본 문제는 정답에 실수형이 포함되는 문제입니다. 입출력 예의 소수 부분 .0이 코드 실행 버튼 클릭 후 나타나는 결괏값, 기댓값 표시와 다를 수 있습니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/7e518dc9-46f8-4b57-ad70-c0843378e09b/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>y위치값을 담을 배열을 만든다.</li>
<li>각 위치별 너비를 담을 배열을 만든다.</li>
<li>k값이 1이 될때까지 주어진 조건대로 값을 계산하여 y위치값 배열에 담는다.</li>
<li>생성된 y위치값 배열을 돌면서 각 위치에 해당하는 너비값을 너비 배열에 담는다.</li>
<li>ranges배열에 시작값과 끝값을 재설정하고 끝값이 시작값보다 크면 -1을 넣어주고 아니라면 시작값부터 끝값까지 반복문을 돌며 너비값을 더해서 해당 위치에 너비값을 넣어준다.</li>
</ol>
<h2 id="코드">코드</h2>
<pre><code>import java.util.*;

class Solution {
    public double[] solution(int k, int[][] ranges) {
        double[] answer = new double[ranges.length];

        List&lt;Integer&gt; dy = new LinkedList&lt;&gt;();
        List&lt;Double&gt; w = new LinkedList&lt;&gt;();

        dy.add(k);
        while(k != 1){
            k = k % 2 != 0 ? k * 3 + 1 : k / 2 ;
            dy.add(k);
        }

        for(int i=0; i&lt;dy.size()-1;i++)
            w.add((double)(dy.get(i) + dy.get(i+1)) / 2);

        for(int i=0; i&lt;ranges.length; i++){
            int start = ranges[i][0];
            int end = w.size() + ranges[i][1];
            if(end - start &lt; 0) answer[i] = -1;
            else  
                for(int j=start; j&lt;end; j++) answer[i] += w.get(j);
        }

        return answer;
    }
} 
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]줄 서는 방법]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%A4%84-%EC%84%9C%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%A4%84-%EC%84%9C%EB%8A%94-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Thu, 27 Jul 2023 13:19:29 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/12936">https://school.programmers.co.kr/learn/courses/30/lessons/12936</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>n명의 사람이 일렬로 줄을 서고 있습니다. n명의 사람들에게는 각각 1번부터 n번까지 번호가 매겨져 있습니다. n명이 사람을 줄을 서는 방법은 여러가지 방법이 있습니다. 예를 들어서 3명의 사람이 있다면 다음과 같이 6개의 방법이 있습니다.</p>
</blockquote>
<p>[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]</p>
<blockquote>
</blockquote>
<p>사람의 수 n과, 자연수 k가 주어질 때, 사람을 나열 하는 방법을 사전 순으로 나열 했을 때, k번째 방법을 return하는 solution 함수를 완성해주세요.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
</blockquote>
<p>n은 20이하의 자연수 입니다.
k는 n! 이하의 자연수 입니다.</p>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/962f9699-7892-49ba-8e43-05d5aa054498/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>정답을 반환할 배열을 선언한다.</li>
<li>정답에 값을 넣어줄 순차적으로 값을 증가시키는 배열을 선언한다.</li>
<li>배열의 값을 모두 곱한 값을 선언한다.</li>
<li>정답 배열에 값을 넣어줄 인덱스를 선언한다.</li>
<li>몫에 해당하는 index를 list에서 찾아서 정답배열에 넣어준다.</li>
<li>해당 값은 list에서 빼준다.</li>
<li>index가 정답 배열길이 만큼 돌면 반복문을 종료한다.</li>
</ol>
<h2 id="다른-사람-코드">다른 사람 코드</h2>
<p>어느 정도 규칙은 찾았는데 코드 구현이 어려웠다ㅠㅠ 다음에 다시 풀어봐야겠다ㅠㅠ</p>
<pre><code>import java.util.*;

class Solution {
    public int[] solution(int n, long k) {
        int[] ret = new int[n];
        List&lt;Integer&gt; list = new ArrayList&lt;&gt;();
        long num= 1;
        int idx = 0;
        for(int x=1; x&lt;=n; x++){
            list.add(x);
            num *= x;
        }
        k--;
        while(idx&lt;ret.length){
            num /= (n--);
            int i = (int)(k/num);

            ret[idx++] = list.get(i);
            list.remove(i);
            k %= num;
        }
        return ret;
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]롤케이크 자르기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%A1%A4%EC%BC%80%EC%9D%B4%ED%81%AC-%EC%9E%90%EB%A5%B4%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%A1%A4%EC%BC%80%EC%9D%B4%ED%81%AC-%EC%9E%90%EB%A5%B4%EA%B8%B0</guid>
            <pubDate>Sat, 22 Jul 2023 13:03:14 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/132265">https://school.programmers.co.kr/learn/courses/30/lessons/132265</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>철수는 롤케이크를 두 조각으로 잘라서 동생과 한 조각씩 나눠 먹으려고 합니다. 이 롤케이크에는 여러가지 토핑들이 일렬로 올려져 있습니다. 철수와 동생은 롤케이크를 공평하게 나눠먹으려 하는데, 그들은 롤케이크의 크기보다 롤케이크 위에 올려진 토핑들의 종류에 더 관심이 많습니다. 그래서 잘린 조각들의 크기와 올려진 토핑의 개수에 상관없이 각 조각에 동일한 가짓수의 토핑이 올라가면 공평하게 롤케이크가 나누어진 것으로 생각합니다.</p>
</blockquote>
<p>예를 들어, 롤케이크에 4가지 종류의 토핑이 올려져 있다고 합시다. 토핑들을 1, 2, 3, 4와 같이 번호로 표시했을 때, 케이크 위에 토핑들이 [1, 2, 1, 3, 1, 4, 1, 2] 순서로 올려져 있습니다. 만약 세 번째 토핑(1)과 네 번째 토핑(3) 사이를 자르면 롤케이크의 토핑은 [1, 2, 1], [3, 1, 4, 1, 2]로 나뉘게 됩니다. 철수가 [1, 2, 1]이 놓인 조각을, 동생이 [3, 1, 4, 1, 2]가 놓인 조각을 먹게 되면 철수는 두 가지 토핑(1, 2)을 맛볼 수 있지만, 동생은 네 가지 토핑(1, 2, 3, 4)을 맛볼 수 있으므로, 이는 공평하게 나누어진 것이 아닙니다. 만약 롤케이크의 네 번째 토핑(3)과 다섯 번째 토핑(1) 사이를 자르면 [1, 2, 1, 3], [1, 4, 1, 2]로 나뉘게 됩니다. 이 경우 철수는 세 가지 토핑(1, 2, 3)을, 동생도 세 가지 토핑(1, 2, 4)을 맛볼 수 있으므로, 이는 공평하게 나누어진 것입니다. 공평하게 롤케이크를 자르는 방법은 여러가지 일 수 있습니다. 위의 롤케이크를 [1, 2, 1, 3, 1], [4, 1, 2]으로 잘라도 공평하게 나뉩니다. 어떤 경우에는 롤케이크를 공평하게 나누지 못할 수도 있습니다.</p>
<blockquote>
</blockquote>
<p>롤케이크에 올려진 토핑들의 번호를 저장한 정수 배열 topping이 매개변수로 주어질 때, 롤케이크를 공평하게 자르는 방법의 수를 return 하도록 solution 함수를 완성해주세요.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>1 ≤ topping의 길이 ≤ 1,000,000</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ topping의 원소 ≤ 10,000</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/38ee0f5d-fd53-468b-b7e3-6b8ed8b03b03/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li><p>처음에는 철수가 다 갖고 있다고 가정하고 meSet 변수에 모든 토핑을 넣는다.</p>
</li>
<li><p>counter 변수를 선언해 각 토핑이 몇 개씩 있는 지 확인한다.</p>
</li>
<li><p>topping이 한 개 이상이면 counter에서 1씩 빼주면서 남아있는 topping을 확인한다.</p>
</li>
<li><p>counter가 0이면 topping이 없는것이기 때문에 내 토핑에서 해당 값을 빼준다.</p>
</li>
<li><p>동생 broSet에 해당 값을 넣어준다.</p>
</li>
<li><p>동생이 갖고 있는 갯수와 철수가 갖고 있는 갯수가 같으면 answer을 1씩 증가시킨다.
_slice로 풀었을 때 시간 초과가 나서 set으로 풀어야 겠다는 알았지만 어떻게 set을 사용하여 구현해야 할 지 잘 모르겠어서 다른 사람 코드를 확인하였다. 백만이 넘어가면 O(n)의 시간복잡도로 구현할 수 있도록 연습해야겠다.
_</p>
<h2 id="다른-사람-코드">다른 사람 코드</h2>
<pre><code>function solution(topping) {
 let answer = 0;
 let meSet = new Set();
 let broSet = new Set();
 let counter = new Array(10001).fill(0);

 if(topping.length == 1) return answer;

 topping.map(v =&gt; {
     baseSet.add(v);
     counter[v]++;
 })

 topping.map(v =&gt; {
     if(counter[v] &gt;= 1) counter[v]--;
     if(counter[v] == 0) meSet.delete(v);
     broSet.add(v);
     if(meSet.size == broSet.size) answer++;
 })

 return answer;
}
</code></pre></li>
</ol>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]조건별로 분류하여 주문상태 출력하기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%A1%B0%EA%B1%B4%EB%B3%84%EB%A1%9C-%EB%B6%84%EB%A5%98%ED%95%98%EC%97%AC-%EC%A3%BC%EB%AC%B8%EC%83%81%ED%83%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%A1%B0%EA%B1%B4%EB%B3%84%EB%A1%9C-%EB%B6%84%EB%A5%98%ED%95%98%EC%97%AC-%EC%A3%BC%EB%AC%B8%EC%83%81%ED%83%9C-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 22 Jul 2023 08:59:19 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/131113">https://school.programmers.co.kr/learn/courses/30/lessons/131113</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>다음은 식품공장의 주문정보를 담은 FOOD_ORDER 테이블입니다. FOOD_ORDER 테이블은 다음과 같으며 ORDER_ID, PRODUCT_ID, AMOUNT, PRODUCE_DATE, IN_DATE,OUT_DATE,FACTORY_ID, WAREHOUSE_ID는 각각 주문 ID, 제품 ID, 주문양, 생산일자, 입고일자, 출고일자, 공장 ID, 창고 ID를 의미합니다.
<img src="https://velog.velcdn.com/images/lee-goeun/post/c833e63d-a4e1-4c40-9fef-ae3a748e6cfd/image.png" alt=""></p>
</blockquote>
<h2 id="문제">문제</h2>
<blockquote>
<p>FOOD_ORDER 테이블에서 5월 1일을 기준으로 주문 ID, 제품 ID, 출고일자, 출고여부를 조회하는 SQL문을 작성해주세요. 출고여부는 5월 1일까지 출고완료로 이 후 날짜는 출고 대기로 미정이면 출고미정으로 출력해주시고, 결과는 주문 ID를 기준으로 오름차순 정렬해주세요.</p>
</blockquote>
<h2 id="예시">예시</h2>
<blockquote>
<p>FOOD_ORDER 테이블이 다음과 같을 때
<img src="https://velog.velcdn.com/images/lee-goeun/post/baa6a583-24a7-44b0-9295-1eaccbc1ecc3/image.png" alt="">
SQL을 실행하면 다음과 같이 출력되어야 합니다.
<img src="https://velog.velcdn.com/images/lee-goeun/post/5a03d565-fee7-442b-a1e6-8537fb5db4b3/image.png" alt=""></p>
</blockquote>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>출고일 기준으로 경우에 따라 케이스를 나눈다.</li>
<li>조건에 맞게 정렬한다.</li>
</ol>
<h2 id="코드">코드</h2>
<pre><code>SELECT ORDER_ID, PRODUCT_ID, date_format(OUT_DATE,&#39;%Y-%m-%d&#39;) OUT_DATE, 
    case 
        when OUT_DATE &lt;= &#39;2022-05-01&#39; then &#39;출고완료&#39;
        when OUT_DATE is null then &#39;출고미정&#39;
        else &#39;출고대기&#39;
    end &#39;출고여부&#39; 
from FOOD_ORDER 
    order by ORDER_ID</code></pre><h2 id="til">TIL</h2>
<ul>
<li>case when 조건 then &#39;반환값&#39;<pre><code>  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when 조건 then &#39;반환값&#39;
  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else &#39;반환값&#39;</code></pre>end</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]오프라인/온라인 판매 데이터 통합하기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%98%A4%ED%94%84%EB%9D%BC%EC%9D%B8%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%86%B5%ED%95%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%98%A4%ED%94%84%EB%9D%BC%EC%9D%B8%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%86%B5%ED%95%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 22 Jul 2023 07:30:47 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/131537">https://school.programmers.co.kr/learn/courses/30/lessons/131537</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>다음은 어느 의류 쇼핑몰의 온라인 상품 판매 정보를 담은 ONLINE_SALE 테이블과 오프라인 상품 판매 정보를 담은 OFFLINE_SALE 테이블 입니다. ONLINE_SALE 테이블은 아래와 같은 구조로 되어있으며 ONLINE_SALE_ID, USER_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는 각각 온라인 상품 판매 ID, 회원 ID, 상품 ID, 판매량, 판매일을 나타냅니다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/dfc71b66-e039-48a0-b8c6-a822344b51b7/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>동일한 날짜, 회원 ID, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.</p>
<blockquote>
</blockquote>
<p>OFFLINE_SALE 테이블은 아래와 같은 구조로 되어있으며 OFFLINE_SALE_ID, PRODUCT_ID, SALES_AMOUNT, SALES_DATE는 각각 오프라인 상품 판매 ID, 상품 ID, 판매량, 판매일을 나타냅니다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/af6e08a0-2fbe-4f98-a3bd-923337593b94/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>동일한 날짜, 상품 ID 조합에 대해서는 하나의 판매 데이터만 존재합니다.</p>
<h2 id="문제">문제</h2>
<blockquote>
</blockquote>
<p>ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요. OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요. 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.</p>
<h2 id="예시">예시</h2>
<blockquote>
</blockquote>
<p>예를 들어 ONLINE_SALE 테이블이 다음과 같고
<img src="https://velog.velcdn.com/images/lee-goeun/post/cc9c86a2-e742-44dc-a567-df1c50c7d07e/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>OFFLINE_SALE 테이블이 다음과 같다면
<img src="https://velog.velcdn.com/images/lee-goeun/post/2c8c8372-96f0-410a-9c4a-88a917d5b350/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>각 테이블의 2022년 3월의 판매 데이터를 합쳐서, 정렬한 결과는 다음과 같아야 합니다.
<img src="https://velog.velcdn.com/images/lee-goeun/post/4f0785bd-e224-40be-8da6-5a195b09a699/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>online 테이블과 offline 테이블을 합친다.</li>
<li>2022년 3월인 데이터만 필터한다.</li>
<li>조건에 맞게 정렬한다.</li>
</ol>
<h2 id="문제풀이-1">문제풀이</h2>
<pre><code>select * from (
    select date_format(SALES_DATE, &#39;%Y-%m-%d&#39;) SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT from ONLINE_SALE 
    union
    select date_format(SALES_DATE, &#39;%Y-%m-%d&#39;), PRODUCT_ID, NULL USER_ID, SALES_AMOUNT from OFFLINE_SALE 
) t
     where SALES_DATE like &#39;2022-03%&#39; 
    order by SALES_DATE, PRODUCT_ID, USER_ID</code></pre><h2 id="til">TIL</h2>
<ul>
<li>테이블 합치기<ul>
<li>밑으로 합치기 : union(중복제거), union all(중복 포함)</li>
<li>옆으로 합치기 : group by </li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]연속된 부분 수열의 합]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%97%B0%EC%86%8D%EB%90%9C-%EB%B6%80%EB%B6%84-%EC%88%98%EC%97%B4%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%97%B0%EC%86%8D%EB%90%9C-%EB%B6%80%EB%B6%84-%EC%88%98%EC%97%B4%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Mon, 10 Jul 2023 15:37:28 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/178870">https://school.programmers.co.kr/learn/courses/30/lessons/178870</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>비내림차순으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다.</p>
</blockquote>
<p>기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다.
부분 수열의 합은 k입니다.
합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다.
길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다.
수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 부분 수열의 시작 인덱스와 마지막 인덱스를 배열에 담아 return 하는 solution 함수를 완성해주세요. 이때 수열의 인덱스는 0부터 시작합니다.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>5 ≤ sequence의 길이 ≤ 1,000,000</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ sequence의 원소 ≤ 1,000</li>
<li>sequence는 비내림차순으로 정렬되어 있습니다.<ul>
<li>5 ≤ k ≤ 1,000,000,000</li>
</ul>
</li>
<li>k는 항상 sequence의 부분 수열로 만들 수 있는 값입니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/f2297ff0-06b6-4c83-a145-e65ce08442a0/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>포인터가 될 head변수와 합을 나타낼 sum변수를 선언한다. 그리고 정답을 담아줄 변수를 선언한다.</li>
<li>sequence배열을 돌면서 하나씩 더해준다.</li>
<li>만약 sum이 k값보다 크면 작을때까지 빼준다.(head를 포인터삼아 하나씩 늘려준다)</li>
<li>만약 sum이 k와 같다면 정답에 head와 i를 넣어준다.</li>
<li>배열을 다 돌게되면 정답 배열에 k와 값이 같은 index 배열들이 있다.</li>
<li>이 배열을 돌면서 길이값이 가장 작은 값을 찾는다. 가장 작은 값이 있으면 결과변수에 넣어준다.</li>
</ol>
<h2 id="다른사람-코드">다른사람 코드</h2>
<p><em>풀이 팁을 봐도 도저히 모르겠어서 다른 사람 코드를 봤다. 이제서야 하나씩 빼면서 더하라는 게 무슨 말인지 알겠다.</em></p>
<pre><code>function solution(sequence, k) {
    var answer = [];
    var sum = 0;
    var head = 0;
    for(var i=0; i&lt;sequence.length; i++){
        sum += sequence[i];
        if(sum&gt;k){
            while(sum&gt;k){
                sum -= sequence[head++];
            }
        }
        if(sum == k) answer.push([head,i]);
    }

    var min = sequence.length;
    var result = [];
    answer.forEach((element) =&gt; {
        if(min &gt; (element[1]-element[0])){
            min = (element[1]-element[0]);
            result = [element[0], element[1]];
        }
    })

    return result;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]숫자 변환하기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%88%AB%EC%9E%90-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%88%AB%EC%9E%90-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 20 Jun 2023 02:13:03 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/154538">https://school.programmers.co.kr/learn/courses/30/lessons/154538</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>자연수 x를 y로 변환하려고 합니다. 사용할 수 있는 연산은 다음과 같습니다.</p>
</blockquote>
<ul>
<li>x에 n을 더합니다</li>
<li>x에 2를 곱합니다.</li>
<li>x에 3을 곱합니다.
자연수 x, y, n이 매개변수로 주어질 때, x를 y로 변환하기 위해 필요한 최소 연산 횟수를 return하도록 solution 함수를 완성해주세요. 이때 x를 y로 만들 수 없다면 -1을 return 해주세요.</li>
</ul>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>1 ≤ x ≤ y ≤ 1,000,000</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ n &lt; y</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/6b1bbd92-8b7f-4bc2-8ddd-b07acd819760/image.png" alt=""></p>
<br/>

<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>y 길이값만큼 배열을 생성하여 무한값을 넣어준다.</li>
<li>x와 y가 같으면 변경할 필요가 없기 때문에 0으로 리턴해준다.</li>
<li>처음 값은 0으로 셋팅해준다.</li>
<li>y에서 x로 1씩 감소하면서
 4-1. i-n이 0보다 크면 해당 값에 작은 값을 넣어준다.
 4-2. i가 2로 나누어떨어지면 해당 위치의 값과 현재값에서 1을 더한 값중 작은 값을 넣어준다.
 4-3. i가 3으로 나누어떨어질 경우도 4-2로 동일.</li>
<li>x의 값이 무한이면 변경할 수 없기 때문에 -1을 반환하고 아니면 해당 값을 반환한다.</li>
</ol>
<br/>

<h2 id="코드">코드</h2>
<pre><code>function solution(x, y, n) {
    let arr = new Array(y+1).fill(Infinity);

    if(x==y) return 0;

    if(y-n&gt;0) arr[y-n] = 1;
    if(y%2==0) arr[y/2] =  1;
    if(y%3==0) arr[y/3] = 1;

    for(let i=y-1; i&gt;=x; i--){
        if(i-n&gt;0) arr[i-n] = Math.min(arr[i-n], arr[i]+1);
        if(i%2==0) arr[i/2] =  Math.min(arr[i/2], arr[i]+1);
        if(i%3==0) arr[i/3] = Math.min(arr[i/3], arr[i]+1);
    }
    return arr[x] == Infinity ? -1 : arr[x];
}</code></pre><br/>

<h2 id="리팩토링">리팩토링</h2>
<pre><code>function solution(x, y, n) {

    if(x==y) return 0;

    let arr = new Array(y+1).fill(Infinity);
    arr[y] = 0;

    for(let i=y; i&gt;=x; i--){
        if(i-n&gt;0) arr[i-n] = Math.min(arr[i-n], arr[i]+1);
        if(i%2==0) arr[i/2] =  Math.min(arr[i/2], arr[i]+1);
        if(i%3==0) arr[i/3] = Math.min(arr[i/3], arr[i]+1);
    }
    return arr[x] == Infinity ? -1 : arr[x];
}</code></pre><br/>

<h2 id="다른-사람-코드">다른 사람 코드</h2>
<pre><code>function solution(x, y, n) {
  if (x === y) return 0;
  const dp = {};
  dp[x] = 0;
  let data = [x];
  while (data.length) {
    const newData = [];
    for (const d of data) {
      for (const e of [d + n, d * 2, d * 3]) {
        if (e &gt; y || dp[e]) continue;
        if (e === y) return dp[d] + 1;
        dp[e] = dp[d] + 1;
        newData.push(e);
      }
    }
    data = newData;
  }
  return -1;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 뒤에 있는 큰 수 찾기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%92%A4%EC%97%90-%EC%9E%88%EB%8A%94-%ED%81%B0-%EC%88%98-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%92%A4%EC%97%90-%EC%9E%88%EB%8A%94-%ED%81%B0-%EC%88%98-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Mon, 19 Jun 2023 09:37:46 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/154539">https://school.programmers.co.kr/learn/courses/30/lessons/154539</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>정수로 이루어진 배열 numbers가 있습니다. 배열 의 각 원소들에 대해 자신보다 뒤에 있는 숫자 중에서 자신보다 크면서 가장 가까이 있는 수를 뒷 큰수라고 합니다.
정수 배열 numbers가 매개변수로 주어질 때, 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성해주세요. 단, 뒷 큰수가 존재하지 않는 원소는 -1을 담습니다.</p>
</blockquote>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>4 ≤ numbers의 길이 ≤ 1,000,000</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ numbers[i] ≤ 1,000,000</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/145c7eb5-5bae-4f8f-9192-e033a0566dcb/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>numbers의 배열길이만큼 -1로 채운 값을 생성한다.</li>
<li>numbers만큼 돌면서 stack에 데이터가 있고 stack 마지막 값을 index로 하는 number값과 현재 number값을 비교하여 현재 number값이 크면 stack 값을 빼서 해당 index값에 현재 number값을 넣어준다.</li>
<li>스택에 현재 위치에 들어갈 index번호를 넣어준다.</li>
<li>정답을 리턴한다.</li>
</ol>
<h2 id="다른-사람-코드">다른 사람 코드</h2>
<p>코드 출처 : 
<a href="https://velog.io/@sean2337/Programmers-%EB%92%A4%EC%97%90-%EC%9E%88%EB%8A%94-%ED%81%B0-%EC%88%98-%EC%B0%BE%EA%B8%B0-JavaScript">https://velog.io/@sean2337/Programmers-%EB%92%A4%EC%97%90-%EC%9E%88%EB%8A%94-%ED%81%B0-%EC%88%98-%EC%B0%BE%EA%B8%B0-JavaScript</a></p>
<pre><code>function solution(numbers) {
    var answer = new Array(numbers.length).fill(-1);
    var stack = [];

    for(let i=0; i&lt;numbers.length; i++){
        while(stack &amp;&amp; numbers[stack.at(-1)]&lt;numbers[i]){
           answer[stack.pop()] = numbers[i]; 
        }
        stack.push(i);
    }

    return answer;
}
</code></pre><p><em>스택에 대해 개념은 잘 알고 있다고 생각했는데 정작 문제에 적용해서 풀려고 하니 어떻게 접근해야 될 지 모르겠어서 다른 사람 코드를 보고 문제풀이를 리뷰했다. 문제를 푸는 구현 능력도 부족하다는 것을 느꼈다.</em></p>
<h2 id="til">TIL</h2>
<ul>
<li>Array.at(-1) : 배열 뒤에서 첫번째 값 반환 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]할인 행사]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%ED%95%A0%EC%9D%B8-%ED%96%89%EC%82%AC</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%ED%95%A0%EC%9D%B8-%ED%96%89%EC%82%AC</guid>
            <pubDate>Mon, 19 Jun 2023 03:32:15 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/131127">https://school.programmers.co.kr/learn/courses/30/lessons/131127</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>XYZ 마트는 일정한 금액을 지불하면 10일 동안 회원 자격을 부여합니다. XYZ 마트에서는 회원을 대상으로 매일 한 가지 제품을 할인하는 행사를 합니다. 할인하는 제품은 하루에 하나씩만 구매할 수 있습니다. 알뜰한 정현이는 자신이 원하는 제품과 수량이 할인하는 날짜와 10일 연속으로 일치할 경우에 맞춰서 회원가입을 하려 합니다.</p>
</blockquote>
<p>예를 들어, 정현이가 원하는 제품이 바나나 3개, 사과 2개, 쌀 2개, 돼지고기 2개, 냄비 1개이며, XYZ 마트에서 15일간 회원을 대상으로 할인하는 제품이 날짜 순서대로 치킨, 사과, 사과, 바나나, 쌀, 사과, 돼지고기, 바나나, 돼지고기, 쌀, 냄비, 바나나, 사과, 바나나인 경우에 대해 알아봅시다. 첫째 날부터 열흘 간에는 냄비가 할인하지 않기 때문에 첫째 날에는 회원가입을 하지 않습니다. 둘째 날부터 열흘 간에는 바나나를 원하는 만큼 할인구매할 수 없기 때문에 둘째 날에도 회원가입을 하지 않습니다. 셋째 날, 넷째 날, 다섯째 날부터 각각 열흘은 원하는 제품과 수량이 일치하기 때문에 셋 중 하루에 회원가입을 하려 합니다.</p>
<blockquote>
</blockquote>
<p>정현이가 원하는 제품을 나타내는 문자열 배열 want와 정현이가 원하는 제품의 수량을 나타내는 정수 배열 number, XYZ 마트에서 할인하는 제품을 나타내는 문자열 배열 discount가 주어졌을 때, 회원등록시 정현이가 원하는 제품을 모두 할인 받을 수 있는 회원등록 날짜의 총 일수를 return 하는 solution 함수를 완성하시오. 가능한 날이 없으면 0을 return 합니다.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>1 ≤ want의 길이 = number의 길이 ≤ 10</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ number의 원소 ≤ 10</li>
<li>number[i]는 want[i]의 수량을 의미하며, number의 원소의 합은 10입니다.<ul>
<li>10 ≤ discount의 길이 ≤ 100,000</li>
<li>want와 discount의 원소들은 알파벳 소문자로 이루어진 문자열입니다.</li>
</ul>
</li>
<li>1 ≤ want의 원소의 길이, discount의 원소의 길이 ≤ 12</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/42ca0645-5e51-4b17-8641-361fc95779f1/image.png" alt=""></p>
<h2 id="문제-풀이">문제 풀이</h2>
<ol>
<li>원하는 제품 수 만큼 반복문을 돌기 위해 총 갯수를 변수로 선언한다.</li>
<li>각 제품에 원하는 갯수를 map형식으로 넣어준다.</li>
<li>할인 배열을 원하는 제품 수 만큼 돌면서 각 할인물품의 갯수를 더해서 map 형식으로 리턴한다.</li>
<li>원하는 물품의 갯수와 할인하는 물품의 갯수가 동일하다면 1증가해준다.</li>
<li>반복문이 원하는 제품 수와 같다면 반복문을 중단한다.</li>
</ol>
<h2 id="코드">코드</h2>
<pre><code>function solution(want, number, discount) {
    let answer = 0;
    let total = number.reduce((acc, cur) =&gt; acc+cur, 0);
    let wantMap = {};
    want.map((v, i) =&gt; wantMap[v] = number[i])

   wantMap =  Object.fromEntries(Array.from(new Map(Object.entries(wantMap))).sort());

    for(let i=0; i&lt;discount.length; i++){
        let foodMap = {};

        for(let j=i; j&lt;total+i; j++) 
            foodMap[discount[j]] = (foodMap[discount[j]] || 0) + 1;

        foodMap = Object.fromEntries(Array.from(new Map(Object.entries(foodMap))).sort());
        if(JSON.stringify(foodMap) == JSON.stringify(wantMap)) answer++;
        if(i == discount.length - total) break;
    }

    return answer;
}</code></pre><h2 id="다른-사람-코드">다른 사람 코드</h2>
<pre><code>function solution(want, number, discount) {
    let count = 0;
    for (let i = 0; i &lt; discount.length - 9; i++) {
        const slice = discount.slice(i, i+10);

        let flag = true;
        for (let j = 0; j &lt; want.length; j++) {
            if (slice.filter(item =&gt; item === want[j]).length !== number[j]) {
                flag = false;
                break;
            }
        }
        if (flag) count += 1;
    }
    return count;
}</code></pre><p><em>filter를 쓰면 O(n)만큼의 시간복잡도가 걸리기 때문에 시간이 더 걸릴 거라고 생각했는데 주어진 배열의 크기가 10이하이기 때문에 filter를 써도 시간이 많이 걸리지 않는 거 같다. 길이값에 따라 적당하게 map과 배열을 쓰는 게 중요할 거 같다.</em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]테이블 해시 함수]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%B8%94-%ED%95%B4%EC%8B%9C-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%B8%94-%ED%95%B4%EC%8B%9C-%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 15 Jun 2023 07:04:50 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/147354">https://school.programmers.co.kr/learn/courses/30/lessons/147354</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>완호가 관리하는 어떤 데이터베이스의 한 테이블은 모두 정수 타입인 컬럼들로 이루어져 있습니다. 테이블은 2차원 행렬로 표현할 수 있으며 열은 컬럼을 나타내고, 행은 튜플을 나타냅니다.
첫 번째 컬럼은 기본키로서 모든 튜플에 대해 그 값이 중복되지 않도록 보장됩니다. 완호는 이 테이블에 대한 해시 함수를 다음과 같이 정의하였습니다.</p>
</blockquote>
<ol>
<li>해시 함수는 col, row_begin, row_end을 입력으로 받습니다.</li>
<li>테이블의 튜플을 col번째 컬럼의 값을 기준으로 오름차순 정렬을 하되, 만약 그 값이 동일하면 기본키인 첫 번째 컬럼의 값을 기준으로 내림차순 정렬합니다.</li>
<li>정렬된 데이터에서 S_i를 i 번째 행의 튜플에 대해 각 컬럼의 값을 i 로 나눈 나머지들의 합으로 정의합니다.</li>
<li>row_begin ≤ i ≤ row_end 인 모든 S_i를 누적하여 bitwise XOR 한 값을 해시 값으로서 반환합니다.<blockquote>
</blockquote>
테이블의 데이터 data와 해시 함수에 대한 입력 col, row_begin, row_end이 주어졌을 때 테이블의 해시 값을 return 하도록 solution 함수를 완성해주세요.</li>
</ol>
<h2 id="제한-사항">제한 사항</h2>
<blockquote>
<ul>
<li>1 ≤ data의 길이 ≤ 2,500</li>
</ul>
</blockquote>
<ul>
<li>1 ≤ data의 원소의 길이 ≤ 500</li>
<li>1 ≤ data[i][j] ≤ 1,000,000<ul>
<li>data[i][j]는 i + 1 번째 튜플의 j + 1 번째 컬럼의 값을 의미합니다.</li>
</ul>
</li>
<li>1 ≤ col ≤ data의 원소의 길이</li>
<li>1 ≤ row_begin ≤ row_end ≤ data의 길이</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p> <img src="https://velog.velcdn.com/images/lee-goeun/post/016a5c1a-baac-4bd3-9140-5763d14c279a/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>정렬한 다음 주어진 구간만큼의 배열을 계산하여 XOR을 계산한 값을 정답으로 리턴한다.</li>
</ol>
<ul>
<li>문제에 나온 순서대로 계산해주면 된다.</li>
</ul>
<br/>

<h2 id="코드">코드</h2>
<pre><code>function solution(data, col, row_begin, row_end) {
    var answer = 0;

    data.sort((a,b) =&gt; {
        if(a[col-1] == b[col-1]) return b[0] - a[0];
        else return a[col-1] - b[col-1];
    })

    let arr = [];
    data.map((v,i) =&gt; {
        let sum = 0;
        if(i+1 &gt;= row_begin &amp;&amp; i+1 &lt;= row_end){
            v.map(e =&gt; {
                sum += e%(i+1);
            })

            answer = answer ^ sum;
        }
    })

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

<h2 id="리팩토링">리팩토링</h2>
<pre><code>function solution(data, col, row_begin, row_end) {
    var answer = 0;
    data.sort((a,b) =&gt; a[col-1] - b[col-1] || b[0]-a[0]).map((v,i) =&gt; {
        if(i+1 &gt;= row_begin &amp;&amp; i+1 &lt;= row_end)  
            answer ^= v.reduce((acc, cur) =&gt; acc + cur%(i+1),0);
    })
    return answer;
}</code></pre><br/>

<h2 id="다른-사람-코드">다른 사람 코드</h2>
<pre><code>function sort(a, b, col) {
    return a[col - 1] - b[col - 1] || b[0] - a[0];
}

function solution(data, col, row_begin, row_end) {
    data.sort((a, b) =&gt; sort(a, b, col));
    return data
        .map((row, i) =&gt; row.reduce((acc, col) =&gt; acc + (col % (i + 1)), 0))
        .slice(row_begin - 1, row_end)
        .reduce((acc, val) =&gt; acc ^ val, 0);
}</code></pre><h2 id="til">TIL</h2>
<ul>
<li>sort((a,b) =&gt; a[0] - b[0] || b[0] - a[0]) : 앞 조건의 값이 동일하다면 뒷 조건으로 정렬</li>
<li>XOR : ^으로 계산 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]시소 짝꿍]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%8B%9C%EC%86%8C-%EC%A7%9D%EA%BF%8D</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%8B%9C%EC%86%8C-%EC%A7%9D%EA%BF%8D</guid>
            <pubDate>Thu, 15 Jun 2023 05:44:15 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/152996">https://school.programmers.co.kr/learn/courses/30/lessons/152996</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>어느 공원 놀이터에는 시소가 하나 설치되어 있습니다. 이 시소는 중심으로부터 2(m), 3(m), 4(m) 거리의 지점에 좌석이 하나씩 있습니다.
이 시소를 두 명이 마주 보고 탄다고 할 때, 시소가 평형인 상태에서 각각에 의해 시소에 걸리는 토크의 크기가 서로 상쇄되어 완전한 균형을 이룰 수 있다면 그 두 사람을 시소 짝꿍이라고 합니다. 즉, 탑승한 사람의 무게와 시소 축과 좌석 간의 거리의 곱이 양쪽 다 같다면 시소 짝꿍이라고 할 수 있습니다.
사람들의 몸무게 목록 weights이 주어질 때, 시소 짝꿍이 몇 쌍 존재하는지 구하여 return 하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="제한-사항">제한 사항</h2>
<blockquote>
<ul>
<li>2 ≤ weights의 길이 ≤ 100,000</li>
</ul>
</blockquote>
<ul>
<li>100 ≤ weights[i] ≤ 1,000<ul>
<li>몸무게 단위는 N(뉴턴)으로 주어집니다.</li>
<li>몸무게는 모두 정수입니다.</li>
</ul>
</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/15925a71-0bc5-4d9c-9747-63434551dcf8/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>비례되는 수를 구해 그 수가 obj에 들어있으면 value값을 찾아 정답에 더해주고 정답을 리턴한다.</li>
</ol>
<h2 id="코드">코드</h2>
<pre><code>function solution(weights) {
    let answer = 0;
    let obj = {};
    weights.sort((a,b) =&gt; a-b).map(v =&gt; {
        let cals = [v,v*2/3, v*2/4, v*3/4].filter(v =&gt; v == parseInt(v));
        cals.map(cal =&gt; {
            if(obj[cal]) answer += obj[cal];
        })
        obj[v] = (obj[v] || 0) + 1;
    })
    return answer;
}</code></pre><h2 id="til">TIL</h2>
<ul>
<li>object의 시간복잡도 :  O(1)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]미로 탈출]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%AF%B8%EB%A1%9C-%ED%83%88%EC%B6%9C</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%AF%B8%EB%A1%9C-%ED%83%88%EC%B6%9C</guid>
            <pubDate>Tue, 13 Jun 2023 09:10:49 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/159993">https://school.programmers.co.kr/learn/courses/30/lessons/159993</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>1 x 1 크기의 칸들로 이루어진 직사각형 격자 형태의 미로에서 탈출하려고 합니다. 각 칸은 통로 또는 벽으로 구성되어 있으며, 벽으로 된 칸은 지나갈 수 없고 통로로 된 칸으로만 이동할 수 있습니다. 통로들 중 한 칸에는 미로를 빠져나가는 문이 있는데, 이 문은 레버를 당겨서만 열 수 있습니다. 레버 또한 통로들 중 한 칸에 있습니다. 따라서, 출발 지점에서 먼저 레버가 있는 칸으로 이동하여 레버를 당긴 후 미로를 빠져나가는 문이 있는 칸으로 이동하면 됩니다. 이때 아직 레버를 당기지 않았더라도 출구가 있는 칸을 지나갈 수 있습니다. 미로에서 한 칸을 이동하는데 1초가 걸린다고 할 때, 최대한 빠르게 미로를 빠져나가는데 걸리는 시간을 구하려 합니다.</p>
</blockquote>
<p>미로를 나타낸 문자열 배열 maps가 매개변수로 주어질 때, 미로를 탈출하는데 필요한 최소 시간을 return 하는 solution 함수를 완성해주세요. 만약, 탈출할 수 없다면 -1을 return 해주세요.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>5 ≤ maps의 길이 ≤ 100</li>
</ul>
</blockquote>
<ul>
<li><p>5 ≤ maps[i]의 길이 ≤ 100</p>
</li>
<li><p>maps[i]는 다음 5개의 문자들로만 이루어져 있습니다.</p>
<ul>
<li>S : 시작 지점</li>
<li>E : 출구</li>
<li>L : 레버</li>
<li>O : 통로</li>
<li>X : 벽</li>
<li>시작 지점과 출구, 레버는 항상 다른 곳에 존재하며 한 개씩만 존재합니다.</li>
<li>출구는 레버가 당겨지지 않아도 지나갈 수 있으며, 모든 통로, 출구, 레버, 시작점은 여러 번 지나갈 수 있습니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/7c15e852-49af-4591-82b8-63edf9469cca/image.png" alt=""></p>
</li>
</ul>
<h2 id="풀이">풀이</h2>
<ol>
<li><p>레버를 돌려야 문이 열리기 때문에 레버까지 가는 데 걸리는 최소시간과 레버에서 출구까지 가는 데 걸리는 최소시간을 더해서 정답을 도출해야 한다.</p>
</li>
<li><p>중복체크를 위한 맵과 시간을 체크하기 위한 방문배열을 생성해 레버까지 가는 bfs와 출구까지 가는 bfs를 돌린다.</p>
</li>
<li><p>레버까지 도달했을 때 그 값이 0이라면 레버까지 도달하지 못한 것이기 때문에 -1을 리턴하고 0이 아니면 정답에 해당 시간을 더한다.</p>
</li>
<li><p>출구까지 도달했을 때 값이 0이면 출구까지 도달하지 못한 것이기 때문에 -1을 리턴하고 0이 아니면 정답에 해당 시간을 더해서 정답을 리턴한다.</p>
<h2 id="코드">코드</h2>
<pre><code>function solution(maps) {
 let answer = 0;
 let dupMap = maps.map(v =&gt; v.split(&quot;&quot;));
 let lMap = maps.map(v =&gt; v.split(&quot;&quot;));
 const visited = Array.from(Array(maps.length), () =&gt; Array(maps[0].length).fill(0));
 const lVisited = Array.from(Array(maps.length), () =&gt; Array(maps[0].length).fill(0));
 for(let i=0; i&lt;maps.length; i++){
     for(let j=0; j&lt;maps[0].length; j++){
         if(maps[i][j] == &#39;S&#39;)  bfs(i, j, dupMap, visited);
         if(maps[i][j] == &#39;L&#39;) bfs(i ,j, lMap, lVisited);
     }
 }

 for(let i=0; i&lt;maps.length; i++){
     for(let j=0; j&lt;maps[0].length; j++){
          if(maps[i][j] == &#39;L&#39;) {
             if(visited[i][j] == 0) return -1;
             answer += visited[i][j];
         }
         if(maps[i][j] == &#39;E&#39;){
             if(lVisited[i][j] == 0) return -1;
             answer += lVisited[i][j];
         } 
     }
 }
 return answer;
}


</code></pre></li>
</ol>
<p> const bfs = (sx,sy, maps, visited) =&gt; {
    let dx = [-1,1,0,0];
    let dy = [0,0,-1,1];</p>
<pre><code>const q = [[sx, sy]];

while(q.length){
const [x,y] = q.shift();
    for(let i=0; i&lt;4; i++){
        const nowX = x + dx[i];
        const nowY = y + dy[i];

        if(nowX &lt; 0 || nowY &lt; 0 || nowX &gt;= maps.length || nowY &gt;= maps[0].length) continue;
        if(maps[nowX][nowY] != &#39;X&#39;){
            q.push([nowX, nowY]);
            maps[nowX][nowY] = &#39;X&#39;;
            visited[nowX][nowY] = visited[x][y] + 1;
        }
    }
}</code></pre><p>}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]숫자 카드 나누기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%88%AB%EC%9E%90-%EC%B9%B4%EB%93%9C-%EB%82%98%EB%88%84%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%88%AB%EC%9E%90-%EC%B9%B4%EB%93%9C-%EB%82%98%EB%88%84%EA%B8%B0</guid>
            <pubDate>Fri, 09 Jun 2023 01:35:09 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/135807">https://school.programmers.co.kr/learn/courses/30/lessons/135807</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>철수와 영희는 선생님으로부터 숫자가 하나씩 적힌 카드들을 절반씩 나눠서 가진 후, 다음 두 조건 중 하나를 만족하는 가장 큰 양의 정수 a의 값을 구하려고 합니다.</p>
</blockquote>
<ol>
<li>철수가 가진 카드들에 적힌 모든 숫자를 나눌 수 있고 영희가 가진 카드들에 적힌 모든 숫자들 중 하나도 나눌 수 없는 양의 정수 a</li>
<li>영희가 가진 카드들에 적힌 모든 숫자를 나눌 수 있고, 철수가 가진 카드들에 적힌 모든 숫자들 중 하나도 나눌 수 없는 양의 정수 a<blockquote>
</blockquote>
예를 들어, 카드들에 10, 5, 20, 17이 적혀 있는 경우에 대해 생각해 봅시다. 만약, 철수가 [10, 17]이 적힌 카드를 갖고, 영희가 [5, 20]이 적힌 카드를 갖는다면 두 조건 중 하나를 만족하는 양의 정수 a는 존재하지 않습니다. 하지만, 철수가 [10, 20]이 적힌 카드를 갖고, 영희가 [5, 17]이 적힌 카드를 갖는다면, 철수가 가진 카드들의 숫자는 모두 10으로 나눌 수 있고, 영희가 가진 카드들의 숫자는 모두 10으로 나눌 수 없습니다. 따라서 철수와 영희는 각각 [10, 20]이 적힌 카드, [5, 17]이 적힌 카드로 나눠 가졌다면 조건에 해당하는 양의 정수 a는 10이 됩니다.<blockquote>
</blockquote>
철수가 가진 카드에 적힌 숫자들을 나타내는 정수 배열 arrayA와 영희가 가진 카드에 적힌 숫자들을 나타내는 정수 배열 arrayB가 주어졌을 때, 주어진 조건을 만족하는 가장 큰 양의 정수 a를 return하도록 solution 함수를 완성해 주세요. 만약, 조건을 만족하는 a가 없다면, 0을 return 해 주세요.</li>
</ol>
<h2 id="제한사항">제한사항</h2>
<blockquote>
</blockquote>
<ul>
<li>1 ≤ arrayA의 길이 = arrayB의 길이 ≤ 500,000</li>
<li>1 ≤ arrayA의 원소, arrayB의 원소 ≤ 100,000,000</li>
<li>arrayA와 arrayB에는 중복된 원소가 있을 수 있습니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/70b8f42e-4dcd-4b10-a5c1-3fd4c23f2e26/image.png" alt=""></p>
<br/>

<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>철수,영희가 가진 카드들에 적힌 모든 숫자를 나눌수 있는 양의 정수를 구하기 위하여 배열의 최대공약수를 구한다.</li>
<li>최대공약수의 약수를 구하여 약수 중 큰 수부터 차례대로 상대의 숫자를 나눌 수 없는 지 확인한다.
2-1. 나눌 수 없다면 그 수를 최대공약수로 설정하고 반복문을 빠져나온다.
2-2. 나눌 수 있다면 다음 수를 확인하여 최대공약수를 변경해준다.</li>
<li>철수, 영희의 최대공약수가 모두 1이라면 본인이 가진 최대공약수는 상대의 카드를 나눌 수 있다는 뜻이기 때문에 조건에 만족하는 것이 없다. 그러므로 1을 리턴한다.</li>
<li>철수의 최대공약수, 영희의 최대공약수 중 최댓값을 정답으로 리턴한다.</li>
</ol>
<br/>

<h2 id="코드">코드</h2>
<pre><code>function solution(arrayA, arrayB) {
    var answer = 0;
    arrayA.sort((a,b) =&gt; a-b);
    arrayB.sort((a,b) =&gt; a-b);

    //최대공약수
    let gcdA = arrayA[0];
    let gcdB = arrayB[0];
    for(let i in arrayA) gcdA = gcd(gcdA, arrayA[i]);
    for(let i in arrayB) gcdB = gcd(gcdB, arrayB[i]);

    //약수구하기
    let arrA = arr(gcdA);
    let arrB = arr(gcdB);

    for(let v of arrA){
        gcdA = v;
        var rest;
        for(let b of arrayB){
            rest = b%v;
            if(rest == 0) break;
        }

        if(rest != 0) break;
    }

   for(let v of arrB){
        gcdB = v;
        var rest;
        for(let a of arrayA){
            rest = a%v;
            if(rest == 0) break;
        }
       if(rest != 0) break;
    }

    if(gcdA == 1 &amp;&amp; gcdB == 1) return 0;
    return Math.max(gcdA, gcdB);

}
let arr = (num) =&gt; {
    let result = [];
    let idx = 1;
    while(idx &lt;= Math.sqrt(num)){
        if(num % idx == 0){
            result.push(idx);
            if(num / idx != idx) result.push(num / idx);
        }
        idx++;
    }
    result.sort((a,b) =&gt; b-a);
    return result;
}
let gcd = (num1, num2) =&gt; {
    while(num2 &gt; 0){
        let r = num1 % num2;
        num1 = num2;
        num2 = r;
    }
    return num1;
}</code></pre><p><img src="https://velog.velcdn.com/images/lee-goeun/post/8df049a6-1388-4068-9efd-e1118aadad57/image.png" alt=""></p>
<br/>

<h2 id="리팩토링">리팩토링</h2>
<pre><code>function solution(arrayA, arrayB) {
    return Math.max(getAnswer(arrayA, arrayB), getAnswer(arrayB, arrayA));
}

let getAnswer = (arr1, arr2) =&gt; {
    let gcd = (a, b) =&gt; (a%b == 0 ? b : gcd(b, a%b));
    let ele = arr1[0]; 
    for(let v of arr1) ele = gcd(ele, v); // 최대공약수
    let gcdArr = arr(ele); // 공약수
    for(let v of gcdArr) if(arr2.every(b =&gt; b%v != 0)) return v;
    return 0;
}

let arr = (num) =&gt; {
    let result = [];
    for(let i=1; i&lt;=Math.sqrt(num); i++){
        if(num%i==0){
            result.push(i);
            if(num/i!=i) result.push(num/i);
        }
    }
    return result.sort((a,b) =&gt; b-a);
}</code></pre><p><img src="https://velog.velcdn.com/images/lee-goeun/post/8ddb8b93-138f-4d50-9b44-5285065c4ccd/image.png" alt=""></p>
<p><em>every 사용해서 리팩토링하니 시간이 많이 단축되었는데 시간복잡도 확인해보니까 O(n)이다. every때문에 시간이 줄어든 거 같진 않은데 어디서 시간이 줄었는 지 모르겠다.</em>
<br/></p>
<h2 id="다른-사람-코드">다른 사람 코드</h2>
<pre><code>function solution(arrayA, arrayB) {
    const aResult = getAnswer(arrayA, arrayB)
    const bResult = getAnswer(arrayB, arrayA)

    return aResult &gt; bResult ? aResult : bResult
}

function getAnswer (A, B) {
    A.sort((a, b) =&gt; a - b)
    for (let i = A[0]; i &gt; 1; i--) {
        if (A.every(a =&gt; a % i === 0) &amp;&amp; !B.some(b =&gt; b % i === 0)) return i
    }
    return 0
}</code></pre><h2 id="til">TIL</h2>
<ul>
<li>array.every(조건) : 배열이 조건에 모두 부합해야 true 반환 <ul>
<li>시간복잡도 : O(n)<br/></li>
</ul>
</li>
<li>array.some(조건) : 배열이 조건에 하나라도 부합하면 true 반환<ul>
<li>시간복잡도 : O(n)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]마법의 엘리베이터]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%A7%88%EB%B2%95%EC%9D%98-%EC%97%98%EB%A6%AC%EB%B2%A0%EC%9D%B4%ED%84%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%A7%88%EB%B2%95%EC%9D%98-%EC%97%98%EB%A6%AC%EB%B2%A0%EC%9D%B4%ED%84%B0</guid>
            <pubDate>Thu, 08 Jun 2023 05:20:34 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/148653">https://school.programmers.co.kr/learn/courses/30/lessons/148653</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>마법의 세계에 사는 민수는 아주 높은 탑에 살고 있습니다. 탑이 너무 높아서 걸어 다니기 힘든 민수는 마법의 엘리베이터를 만들었습니다. 마법의 엘리베이터의 버튼은 특별합니다. 마법의 엘리베이터에는 -1, +1, -10, +10, -100, +100 등과 같이 절댓값이 10c (c ≥ 0 인 정수) 형태인 정수들이 적힌 버튼이 있습니다. 마법의 엘리베이터의 버튼을 누르면 현재 층 수에 버튼에 적혀 있는 값을 더한 층으로 이동하게 됩니다. 단, 엘리베이터가 위치해 있는 층과 버튼의 값을 더한 결과가 0보다 작으면 엘리베이터는 움직이지 않습니다. 민수의 세계에서는 0층이 가장 아래층이며 엘리베이터는 현재 민수가 있는 층에 있습니다.</p>
</blockquote>
<p>마법의 엘리베이터를 움직이기 위해서 버튼 한 번당 마법의 돌 한 개를 사용하게 됩니다.예를 들어, 16층에 있는 민수가 0층으로 가려면 -1이 적힌 버튼을 6번, -10이 적힌 버튼을 1번 눌러 마법의 돌 7개를 소모하여 0층으로 갈 수 있습니다. 하지만, +1이 적힌 버튼을 4번, -10이 적힌 버튼 2번을 누르면 마법의 돌 6개를 소모하여 0층으로 갈 수 있습니다.</p>
<blockquote>
</blockquote>
<p>마법의 돌을 아끼기 위해 민수는 항상 최소한의 버튼을 눌러서 이동하려고 합니다. 민수가 어떤 층에서 엘리베이터를 타고 0층으로 내려가는데 필요한 마법의 돌의 최소 개수를 알고 싶습니다. 민수와 마법의 엘리베이터가 있는 층을 나타내는 정수 storey 가 주어졌을 때, 0층으로 가기 위해 필요한 마법의 돌의 최소값을 return 하도록 solution 함수를 완성하세요.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
</blockquote>
<ul>
<li>1 ≤ storey ≤ 100,000,000</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/f008b985-8258-4682-8e54-4c349b6fc937/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li><p>Storey 값이 0이 될때까지 반복문을 돈다. </p>
</li>
<li><p>Storey의 첫번째 자리 수가 5보다 크면 올림, 5보다 작으면 내림, 5면 둘째자리를 확인하여 둘째자리가 5보다 크면 내림, 작으면 올림하여 storey값에서 빼준다. </p>
</li>
<li><p>반올림한 값의 첫째자리의 절댓값을 정답에 더해 정답을 리턴한다. </p>
<br/>
## 코드
```
function solution(storey) {
 var answer = 0;

<p> while(storey != 0){</p>
<pre><code> let abs = Math.abs(storey)+&quot;&quot;;
 let sqrt = abs[0] &gt; 5 ? 10**(abs.length) : 
                 abs[0] &lt; 5 ? 10**(abs.length-1) : 
                     abs[1] &lt; 5 || abs.length == 1 ? 10**(abs.length-1) : 10**(abs.length);
 answer += Math.abs(Math.round(storey/sqrt));
 storey -= Math.round(storey/sqrt) * sqrt;</code></pre><p> }</p>
<p> return answer;</p>
</li>
</ol>
<p>}</p>
<pre><code>&lt;br/&gt;

## 리팩토링</code></pre><p>function solution(storey) {
    var answer = 0;</p>
<pre><code>while(storey != 0){
    let abs = Math.abs(storey)+&quot;&quot;;
    let len = abs.length;
    let sqrt = abs[0] &gt; 5 ? 10**len : abs[0] &lt; 5 ? 10**(len-1) : abs[1] &lt; 5 || len == 1 ? 10**(len-1) : 10**len;
    let rnd = Math.round(storey/sqrt)
    answer += Math.abs(rnd);
    storey -= rnd * sqrt;
}

return answer;</code></pre><p>}</p>
<pre><code>&lt;br/&gt;

## 다른 사람 코드</code></pre><p>function solution(storey) {
    if (storey &lt; 5) return storey;
    const r = storey % 10;
    const m = (storey - r) / 10;
    return Math.min(r + solution(m), 10 - r + solution(m + 1));
}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]퍼즐 조각 채우기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%ED%8D%BC%EC%A6%90-%EC%A1%B0%EA%B0%81-%EC%B1%84%EC%9A%B0%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%ED%8D%BC%EC%A6%90-%EC%A1%B0%EA%B0%81-%EC%B1%84%EC%9A%B0%EA%B8%B0</guid>
            <pubDate>Sun, 21 May 2023 14:32:05 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/84021">https://school.programmers.co.kr/learn/courses/30/lessons/84021</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>테이블 위에 놓인 퍼즐 조각을 게임 보드의 빈 공간에 적절히 올려놓으려 합니다. 게임 보드와 테이블은 모두 각 칸이 1x1 크기인 정사각 격자 모양입니다. 이때, 다음 규칙에 따라 테이블 위에 놓인 퍼즐 조각을 게임 보드의 빈칸에 채우면 됩니다.</p>
</blockquote>
<ul>
<li>조각은 한 번에 하나씩 채워 넣습니다.</li>
<li>조각을 회전시킬 수 있습니다.</li>
<li>조각을 뒤집을 수는 없습니다.</li>
<li>게임 보드에 새로 채워 넣은 퍼즐 조각과 인접한 칸이 비어있으면 안 됩니다.
다음은 퍼즐 조각을 채우는 예시입니다.<blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/lee-goeun/post/8034502b-82a3-40cc-9fef-db71283f47a5/image.png" alt=""><blockquote>
</blockquote>
위 그림에서 왼쪽은 현재 게임 보드의 상태를, 오른쪽은 테이블 위에 놓인 퍼즐 조각들을 나타냅니다. 테이블 위에 놓인 퍼즐 조각들 또한 마찬가지로 [상,하,좌,우]로 인접해 붙어있는 경우는 없으며, 흰 칸은 퍼즐이 놓이지 않은 빈 공간을 나타냅니다. 모든 퍼즐 조각은 격자 칸에 딱 맞게 놓여있으며, 격자 칸을 벗어나거나, 걸쳐 있는 등 잘못 놓인 경우는 없습니다.<blockquote>
</blockquote>
이때, 아래 그림과 같이 3,4,5번 조각을 격자 칸에 놓으면 규칙에 어긋나므로 불가능한 경우입니다.<blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/lee-goeun/post/e498628c-8b57-4b11-8ee6-d8da2eb6978d/image.png" alt=""><blockquote>
</blockquote>
</li>
<li>3번 조각을 놓고 4번 조각을 놓기 전에 위쪽으로 인접한 칸에 빈칸이 생깁니다.</li>
<li>5번 조각의 양 옆으로 인접한 칸에 빈칸이 생깁니다.
다음은 규칙에 맞게 최대한 많은 조각을 게임 보드에 채워 넣은 모습입니다.<blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/lee-goeun/post/b1e44494-87b6-43be-ac6d-93425dbe0ed3/image.png" alt=""><blockquote>
</blockquote>
최대한 많은 조각을 채워 넣으면 총 14칸을 채울 수 있습니다.<blockquote>
</blockquote>
현재 게임 보드의 상태 game_board, 테이블 위에 놓인 퍼즐 조각의 상태 table이 매개변수로 주어집니다. 규칙에 맞게 최대한 많은 퍼즐 조각을 채워 넣을 경우, 총 몇 칸을 채울 수 있는지 return 하도록 solution 함수를 완성해주세요.</li>
</ul>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>3 ≤ game_board의 행 길이 ≤ 50</li>
</ul>
</blockquote>
<ul>
<li>game_board의 각 열 길이 = game_board의 행 길이<ul>
<li>즉, 게임 보드는 정사각 격자 모양입니다.</li>
<li>game_board의 모든 원소는 0 또는 1입니다.</li>
<li>0은 빈칸, 1은 이미 채워진 칸을 나타냅니다.</li>
<li>퍼즐 조각이 놓일 빈칸은 1 x 1 크기 정사각형이 최소 1개에서 최대 6개까지 연결된 형태로만 주어집니다.</li>
</ul>
</li>
<li>table의 행 길이 = game_board의 행 길이</li>
<li>table의 각 열 길이 = table의 행 길이<ul>
<li>즉, 테이블은 game_board와 같은 크기의 정사각 격자 모양입니다.</li>
<li>table의 모든 원소는 0 또는 1입니다.</li>
<li>0은 빈칸, 1은 조각이 놓인 칸을 나타냅니다.</li>
<li>퍼즐 조각은 1 x 1 크기 정사각형이 최소 1개에서 최대 6개까지 연결된 형태로만 주어집니다.</li>
</ul>
</li>
<li>game_board에는 반드시 하나 이상의 빈칸이 있습니다.</li>
<li>table에는 반드시 하나 이상의 블록이 놓여 있습니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/a7ff9f6d-db45-422d-bb21-5443e186fcf2/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>퍼즐을 비교하기 위해 퍼즐을 첫번째 칸으로 이동하는 함수를 작성한다.</li>
<li>퍼즐을 회전하였을 때 일치하는 지 확인하기 위한 블럭 회전하는 함수를 작성한다.</li>
<li>배열을 돌며 연결되어 있는 블럭을 찾는 bfs함수를 작성한다.</li>
<li>game_board배열을 돌면서 빈 공간이 있는 영역을 blanks함수에 넣는다.</li>
<li>table 배열을 돌면서 블럭이 있는 영역을 blocks 배열에 넣는다.</li>
<li>블럭 배열을 돌면서 블럭 배열을 동서남북으로 4번 돌렸을 때 빈칸배열의 값과 동일한 게 있다면 빈칸 배열에서 제외시키고 정답을 길이만큼 더해준다.</li>
<li>정답을 리턴한다.</li>
</ol>
<p><em>일단 빈공간과 블럭의 위치를 배열에 담아야겠다는 것은 알았는데 이를 어떻게 회전해서 일치시키게 만드는 부분을 구현하는 것에 어려움이 있었다. 다음번에 혼자 힘으로 다시 풀어봐야겠다.</em></p>
<h2 id="참고-코드">참고 코드</h2>
<p>참고 : <a href="https://velog.io/@nd098pkc/%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%8D%BC%EC%A6%90-%EC%A1%B0%EA%B0%81-%EC%B1%84%EC%9A%B0%EA%B8%B0">https://velog.io/@nd098pkc/%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%8D%BC%EC%A6%90-%EC%A1%B0%EA%B0%81-%EC%B1%84%EC%9A%B0%EA%B8%B0</a></p>
<pre><code>function solution(game_board, table) {
    let blanks = [];
    let blocks = [];
    for(let i=0; i&lt;game_board.length; i++){
        for(let j=0; j&lt;game_board.length; j++){
            if(game_board[i][j] == 0){
                game_board[i][j] = 1;
                blanks.push(bfs([[i,j]], game_board, 1));
            }
        }
    }
    for(let i=0; i&lt;table.length; i++){
        for(let j=0; j&lt;table.length; j++){
            if(table[i][j] == 1){
                table[i][j] = 0;
                blocks.push(bfs([[i,j]], table, 0));
            }
        }
    }

    let answer = 0;
    blocks.forEach((val) =&gt; {
        for(let i=0; i&lt;blanks.length; i++){
            let match = false;
            for(let j=0;j&lt;4;j++){
                val = rotate(val);
                if(JSON.stringify(val) == JSON.stringify(blanks[i])){
                    blanks.splice(i,1);
                    answer += val.length;
                    match = true;
                    break;
                }
            }
            if(match) break;
        }
    })
    return answer;

}
function moveBlock(block){
    let minX = Math.min(...block.map(v =&gt; v[0]));
    let minY = Math.min(...block.map(v =&gt; v[1]));

    return block.map(v =&gt; [v[0]- minX, v[1]- minY]).sort();
}
function rotate(block){
    let max = Math.max(...block.map(v =&gt; Math.max(v[0], v[1])));
    let rotateBlock = block.map(v =&gt; [max-v[1],v[0]]);

    return moveBlock(rotateBlock);
}

function bfs(start, table, k){
    const dx = [0,0,1,-1];
    const dy = [1,-1,0,0];

    let needVisit = start;
    let block = []
    while(needVisit.length &gt; 0){
        let [cx, cy] = needVisit.shift();
        block.push([cx, cy]);

        for(let i=0; i&lt;4; i++){
            let nx = cx + dx[i];
            let ny = cy + dy[i];

            if(nx&lt;0 || ny&lt;0 || nx&gt;=table.length || ny &gt;= table.length) continue;
            else if(table[nx][ny] == k) continue;
            else{
                needVisit.push([nx, ny]);
                table[nx][ny] = k;
            }
        }
    }
    return moveBlock(block);
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]단어 변환]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%8B%A8%EC%96%B4-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EB%8B%A8%EC%96%B4-%EB%B3%80%ED%99%98</guid>
            <pubDate>Sat, 20 May 2023 15:31:06 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/43163">https://school.programmers.co.kr/learn/courses/30/lessons/43163</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.</p>
</blockquote>
<ol>
<li>한 번에 한 개의 알파벳만 바꿀 수 있습니다.</li>
<li>words에 있는 단어로만 변환할 수 있습니다.
예를 들어 begin이 &quot;hit&quot;, target가 &quot;cog&quot;, words가 [&quot;hot&quot;,&quot;dot&quot;,&quot;dog&quot;,&quot;lot&quot;,&quot;log&quot;,&quot;cog&quot;]라면 &quot;hit&quot; -&gt; &quot;hot&quot; -&gt; &quot;dot&quot; -&gt; &quot;dog&quot; -&gt; &quot;cog&quot;와 같이 4단계를 거쳐 변환할 수 있습니다.<blockquote>
</blockquote>
두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.</li>
</ol>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>각 단어는 알파벳 소문자로만 이루어져 있습니다.</li>
</ul>
</blockquote>
<ul>
<li>각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.</li>
<li>words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.</li>
<li>begin과 target은 같지 않습니다.</li>
<li>변환할 수 없는 경우에는 0를 return 합니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/ddcbcb5c-502d-4bc5-b16b-17b018efe700/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>시작 단어를 방문변수에 넣어주고 값을 0으로 처리한다.</li>
<li>큐 변수를 만들어 변화가 가능한 값들을 넣어준다.</li>
<li>큐에 값이 있다면 값을 하나씩 빼어 타겟과 일치한지 확인한다. 일치한다면 멈춘다.</li>
<li>일치하지 않다면 words를 돌면서 한 글자만 다른 지 이 값이 방문하지 않는 값인지 확인하여 방문하지 않는 값이라면 현재 키의 값에서 1만큼 더한 값을 넣어준다. 그리고 그 단어를 큐에 넣어준다.</li>
<li>연결되어 있는 지 확인하기 위한 함수는 두 단어를 인자값으로 받아 비교할 단어의 길이값만큼 돌려 각 단어가 같지 않으면 1씩 더하여 길이값이 1인 값만 true로 반환한다.</li>
</ol>
<p><em>이 문제 역시 BFS라는 것은 알았지만 여전히 어떻게 풀어야 하는 지 모르겠는 상황이었다. 다른 사람의 코드를 참고하였고 코드를 보고 문제풀이 과정을 확인하였다.</em></p>
<h2 id="코드">코드</h2>
<pre><code>function solution(begin, target, words) {
    const visited = {[begin] : 0};
    const queue = [begin];
    while(queue.length){
        const cur = queue.shift();
        if(cur == target) break;

        for(const word of words){
            if(isConnected(word, cur) &amp;&amp; !visited[word]){
                visited[word] = visited[cur] + 1;
                queue.push(word);
            }
        }
    }

    return visited[target] ? visited[target] : 0;
}

const isConnected = (str1, str2) =&gt; {
    let count = 0;
    const len = str1.length;
    for(let i=0; i&lt;len; i++){
        if(str1[i] !== str2[i]) count++;
    }
    return count == 1 ? true : false;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스]아이템 줍기]]></title>
            <link>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%95%84%EC%9D%B4%ED%85%9C-%EC%A4%8D%EA%B8%B0</link>
            <guid>https://velog.io/@lee-goeun/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4%EC%95%84%EC%9D%B4%ED%85%9C-%EC%A4%8D%EA%B8%B0</guid>
            <pubDate>Sat, 20 May 2023 14:06:56 GMT</pubDate>
            <description><![CDATA[<p>문제출처
<a href="https://school.programmers.co.kr/learn/courses/30/lessons/87694">https://school.programmers.co.kr/learn/courses/30/lessons/87694</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>다음과 같은 다각형 모양 지형에서 캐릭터가 아이템을 줍기 위해 이동하려 합니다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/54a3bdc2-ef48-4d9a-8c3a-e05505e37f3f/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>지형은 각 변이 x축, y축과 평행한 직사각형이 겹쳐진 형태로 표현하며, 캐릭터는 이 다각형의 둘레(굵은 선)를 따라서 이동합니다.</p>
<blockquote>
</blockquote>
<p>만약 직사각형을 겹친 후 다음과 같이 중앙에 빈 공간이 생기는 경우, 다각형의 가장 바깥쪽 테두리가 캐릭터의 이동 경로가 됩니다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/6c3093f5-679f-4476-83db-4848f9ea68eb/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>단, 서로 다른 두 직사각형의 x축 좌표 또는 y축 좌표가 같은 경우는 없습니다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/9ae5ca4d-4eaa-4d3a-ae08-b7d1ba222470/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>즉, 위 그림처럼 서로 다른 두 직사각형이 꼭짓점에서 만나거나, 변이 겹치는 경우 등은 없습니다.</p>
<blockquote>
</blockquote>
<p>다음 그림과 같이 지형이 2개 이상으로 분리된 경우도 없습니다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/6117ae13-9652-4cba-86b6-52e7b605bac1/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>한 직사각형이 다른 직사각형 안에 완전히 포함되는 경우 또한 없습니다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/566f5fed-07e6-41db-a659-196b00c043f0/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>지형을 나타내는 직사각형이 담긴 2차원 배열 rectangle, 초기 캐릭터의 위치 characterX, characterY, 아이템의 위치 itemX, itemY가 solution 함수의 매개변수로 주어질 때, 캐릭터가 아이템을 줍기 위해 이동해야 하는 가장 짧은 거리를 return 하도록 solution 함수를 완성해주세요.</p>
<h2 id="제한사항">제한사항</h2>
<blockquote>
<ul>
<li>rectangle의 세로(행) 길이는 1 이상 4 이하입니다.</li>
</ul>
</blockquote>
<ul>
<li>rectangle의 원소는 각 직사각형의 [좌측 하단 x, 좌측 하단 y, 우측 상단 x, 우측 상단 y] 좌표 형태입니다.<ul>
<li>직사각형을 나타내는 모든 좌표값은 1 이상 50 이하인 자연수입니다.</li>
<li>서로 다른 두 직사각형의 x축 좌표, 혹은 y축 좌표가 같은 경우는 없습니다.</li>
<li>문제에 주어진 조건에 맞는 직사각형만 입력으로 주어집니다.</li>
</ul>
</li>
<li>charcterX, charcterY는 1 이상 50 이하인 자연수입니다.<ul>
<li>지형을 나타내는 다각형 테두리 위의 한 점이 주어집니다.</li>
</ul>
</li>
<li>itemX, itemY는 1 이상 50 이하인 자연수입니다.<ul>
<li>지형을 나타내는 다각형 테두리 위의 한 점이 주어집니다.</li>
</ul>
</li>
<li>캐릭터와 아이템의 처음 위치가 같은 경우는 없습니다.</li>
</ul>
<h2 id="입출력-예">입출력 예</h2>
<p><img src="https://velog.velcdn.com/images/lee-goeun/post/64fbdb1a-8d93-4bd2-945e-ec9157a48c77/image.png" alt=""></p>
<h2 id="문제풀이">문제풀이</h2>
<ol>
<li>컴퓨터가 지나가는 길을 인식하기 위해 현재 값보다 두배 늘려준다.</li>
<li>큐에 현재위치와 길이값을 넣어주고 지나간 길은 100을 더해 더이상 지나가지 않게 한다.</li>
<li>큐에 값이 있다면 하나씩 빼서 그 값이 원하는 위치와 동일하다면 길이값의 반을 답으로 리턴한다.</li>
<li>같지 않다면 동서남북을 거치면서 그 위치값이 0보다 크거나 같고 100보다 작거나 같고 그 값이 지나가지 않은 길이라면 큐에 위치값을 넣어주고 현재 위치에 100을 더해줌으로써 갔던 길을 표시해준다.</li>
</ol>
<p><em>BFS로 풀어야 겠다는 건 알았는데 어떻게 구현해야 할 지 모르겠어서 다른 사람 풀이를 봤다ㅠㅠ 간단한 BFS는 구현이 가능한데 조금 난이도가 올라가면 구현에 어려움이 있는 거 같다ㅠㅠ 다른 사람의 문제풀이를 보면서 어떻게 구현해야 하는 지 더 공부해야겠다😥😥ㅠㅠ</em></p>
<h2 id="참고-코드">참고 코드</h2>
<p>참고 : <a href="https://velog.io/@tnehd1998/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%95%84%EC%9D%B4%ED%85%9C-%EC%A4%8D%EA%B8%B0-JavaScript">https://velog.io/@tnehd1998/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%95%84%EC%9D%B4%ED%85%9C-%EC%A4%8D%EA%B8%B0-JavaScript</a></p>
<pre><code>function solution(rectangle, characterX, characterY, itemX, itemY) {
    let map = Array.from(Array(103).fill(0), ()=&gt; Array(103).fill(0));
    let doubleRectangle = rectangle.map(cur =&gt; cur.map(point =&gt; point*2))

    doubleRectangle.forEach(([x1,y1,x2,y2]) =&gt; {
        for(let i=y1; i&lt;=y2; i++){
            for(let j=x1; j&lt;=x2; j++){
                if(j ==x1 || j == x2 || i == y1 || i == y2){
                    if(map[j][i] == 1) continue;
                    else map[j][i] += 1;
                }else{
                    map[j][i] += 2;
                }
            }
        }
    })

    characterX *=2;
    characterY *=2;
    itemX *= 2;
    itemY *= 2;

    const directionX = [1, -1, 0, 0];
    const directionY = [0, 0, 1, -1];

    const queue = [[characterX, characterY, 0]];
    map[characterX][characterY] += 100;

    while(queue.length){
        const [currentX, currentY, count] = queue.shift();

        if(currentX == itemX &amp;&amp; currentY == itemY){
            return count/2;
        }

        for(let i=0; i&lt;4; i++){
            const [nX, nY] = [currentX + directionX[i], currentY + directionY[i]];
            if(nX &gt;= 0 &amp;&amp; nX &lt; 101 &amp;&amp; nY &gt;=0 &amp;&amp; nY &lt; 101){
                if(map[nX][nY] == 1){
                    map[nX][nY] += 100;
                    queue.push([nX, nY, count+1]);
                }
            }
        }
    }
} </code></pre>]]></description>
        </item>
    </channel>
</rss>