<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Checking.log</title>
        <link>https://velog.io/</link>
        <description>(ง ᐖ)ว </description>
        <lastBuildDate>Sat, 01 Apr 2023 08:58:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Checking.log</title>
            <url>https://images.velog.io/images/checking_pks/profile/dca2f591-8195-41ce-9b3d-16838320965f/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Checking.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/checking_pks" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[👨‍💻 나의 첫 인턴 회고록]]></title>
            <link>https://velog.io/@checking_pks/%EB%82%98%EC%9D%98-%EC%B2%AB-%EC%9D%B8%ED%84%B4-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@checking_pks/%EB%82%98%EC%9D%98-%EC%B2%AB-%EC%9D%B8%ED%84%B4-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sat, 01 Apr 2023 08:58:17 GMT</pubDate>
            <description><![CDATA[<h1 id="처음-시작하는-인턴십">처음 시작하는 인턴십</h1>
<p>대학교 3학년에 조교를 했던 교수님의 제안으로 그 해 겨울 방학 기간에 인턴을 시작하게 됐었다. 2022년 12월 19일부터 2023년 03월 29일까지 총 100일 정도의 인턴 생활을 했었다.</p>
<p>한창 졸업 후 대학원을 갈지, 회사를 다닐지 엄청 고민하던 때라 나에게는 회사 생활을 체험해 볼 수 있는 너무 좋은 기회가 되었다. 대학원 생활은 학부 연구생을 통하여 체험을 해봤었다. 인턴까지 해보고 이후에 내 진로의 확답을 주고 싶었다.</p>
<p>인턴을 하며 생각보다 많은 일들을 할 수 있었다. 내가 맡은 일은 Unity로 Hololens와 Nreal 기기에서 작동하는 재활 치료 프로그램에 합류하여 함께 콘텐츠 개발하는 일이었다.</p>
<p>Unity는 몇 년간 수도 없이 봐와서 익숙했지만 VR 기기는 처음이었다.
아니 학부 연구생을 하며 옆에서 제작하는 것을 봤어도 직접 만드는 것은 처음이었다.</p>
<hr>
<h1 id="처음-접하는-문제들">처음 접하는 문제들</h1>
<p>개발을 하며 나에게는 매번 처음 하게 되는 일들 천지였다.
맨 처음 맡은 일은 현재 Hololens로 돌아가는 프로그램을 Nreal로 돌리는 일이었다. Hololens도 처음인데 Nreal은 또 뭔지... 그 SDK가 있다는데 또 뭘 어떻게 써야 할지...</p>
<p>Nreal에서 로그인을 위해서 UUID를 가져오는 방식을 찾아보는 것도 맡았었는데 하다가 결국 실패했었다.</p>
<p>나는 처음 해보는 일을 접하고 개발하는 건 많이 해봐서 그냥 두 가지 생각을 갖고 임한다.</p>
<h2 id="-내가-발생하는-오류는-이미-누군가는-접했을-것이다">• 내가 발생하는 오류는 이미 누군가는 접했을 것이다.</h2>
<p>내가 신대륙을 개척해나가는 일이 아닌 이상 누군가는 이미 밝은 발자국이 있을 것이다.</p>
<p>오류들을 구글링해 보면 대게 이미 그 오류를 접한 사람들이 있었다. 기존 프로젝트에 작성된 코드는 사수님께 물어보면 알 수 있었던 내용이었다.</p>
<p>나에게는 새로운 문제들이더라도 누군가에게는 익숙한 문제이며 어떤 사람들은 이미 그 지도를 그려놨을지도 모른다.</p>
<h2 id="-방법의-정답은-없다-그저-최선책과-차선책들이-존재할-뿐이다">• 방법의 정답은 없다. 그저 최선책과 차선책들이 존재할 뿐이다.</h2>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/2fc39945-dbfa-45b5-9f79-588e7255f1b4/image.jpg" alt=""> 게임 개발에 관한 비하인드 스토리를 본 적이 있다.
폴아웃 3에서 탈것을 만들 수 없어 기차를 머리에 씌워서 문제를 해결했다는 이야기다. <a href="https://bbs.ruliweb.com/etcs/board/300780/read/47458727">(출처)</a></p>
<p>게임 개발에 있어서 어떻게 가든 목적지에만 잘 도착한다면 문제가 없다고 생각한다. 효율적인 방법으로 갈 줄 안다면 그것이야말로 게임 개발에서는 기술이고 테크닉이지 않을까...</p>
<p>어떤 문제를 접했을 때 여러 방안을 제시하고 그중 장단점으로 최선책과 차선책으로 나눠 테스트를 해보며 최선책이 실력이나 현 상황이나 어떤 문제로 불가능하다면 다른 차선책으로 구현하는 방식으로 해결했다.</p>
<hr>
<h1 id="배우고-성장한-점">배우고 성장한 점</h1>
<h2 id="-기술적인-측면에서-배운-점">• 기술적인 측면에서 배운 점</h2>
<p>나는 인턴십을 하면서 100일이라는 시간 동안 코드 스타일이 또 한 번 대격변이 일어났다.</p>
<h3 id="1-sdk를-사용하니-편했다">1. SDK를 사용하니 편했다.</h3>
<p>Unity에서 Hololens2 콘텐츠를 만들려면 MRTK라는 SDK를 사용한다.
Nreal 기기를 만들려면 MRTK에 NRSDK까지 추가하여 사용한다.
기존 나는 기본 Unity만 사용하다가 SDK를 사용하며 처음 접하는 새로운 기술들을 접하게 됐다.</p>
<p>SDK가 그저 누군가 이미 잘 만들어놓은 여러 코드와 리소스, 오브젝트, 프리팹 등이었고, 내가 원하는 기능들을 덧붙여서 만드는 기술이 필요했다.</p>
<p>마이크로소프트에서 작성해놓은 위키도 보며, 갑자기 나타난 버그들도 구글링해 보며, 사수님께 조언도 구하며 일들을 해결해나갔다.</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/d02d351d-cfbc-43fa-9a3f-c570eedb3a89/image.png" alt=""> SDK를 사용하면서 이 짤 이 생각났다. 우리가 개발을 하며 지금 해야 하는 일은 바퀴 하나부터 만드는 일이 아니고 이미 만들어진 서비스를 갖고 개선해 더 멋진 작품을 만드는 일이라는 것이다. 내가 무얼 만들 때 이미 만들어진 기술이 있는지 찾아보고 응용하는 능력을 키워야 할 것 같다.</p>
<h3 id="2-잘-작성된-다른-사람-코드를-모방하게-되었다">2. 잘 작성된 다른 사람 코드를 모방하게 되었다.</h3>
<p>첫날에는 이미 작성된 프로젝트의 코드를 사수님께서 하나하나 설명해 주셨다. 코드를 보며 감탄을 금치 못했다. 싱글톤이나 프로젝트를 분리하고 상속하며 열거형을 사용하고 등등 그냥 학교에서 배워서 알고 있는 내용을 응용하여 적용시킨 것이었다.</p>
<p>&quot;내가 아는 식재료들로 이런 요리까지 가능하다고?&quot; 하는 듯한 느낌이었다.</p>
<p>배울 게 있다면 내 것으로 흡수해야지! 그렇게 나는 그 코드 스타일에서 좋았다고 생각되는 점들을 모방하게 되었다.</p>
<p>그렇게 그 이후 첫 게임잼에 가서 다른 초보 개발자들에게 그런 코드 스타일을 보여줬다. 그분들도 내 첫날과 같은 반응을 하길래 엄청 웃겼었다.</p>
<h3 id="3-빌드가-시간은-오래걸려도-투자해야-한다">3. 빌드가 시간은 오래걸려도 투자해야 한다.</h3>
<p>노트북과 Hololens를 연동시켜 Unity에서 실행했을 때는 렉 안 걸렸는데 Hololens에 빌드 해서 했을 때는 렉 걸리고...
Nreal은 노트북과 연결해서 실행하는 방법이 없다 보니 계속 빌드 하면서 실행해 봤고, 빌드 할 때마다 새로운 문제점들이 수도 없이 터져 나오고 끝없는 수정을 했었다.</p>
<p>과장님께서는 실제 실행할 환경에서 테스트를 해보는 것을 강조하셨다.</p>
<p>실제 환경은 얼마나 열악한지 좋은 컴퓨터로 작업하는 나는 몰랐다.
다 될 줄 알았지...</p>
<h3 id="4-렉과-최적화는-개발자만의-몫은-아니구나">4. 렉과 최적화는 개발자만의 몫은 아니구나...</h3>
<p>콘텐츠를 추가하고, 새로운 코드들과 오브젝트를 추가하다 보니 렉이 걸렸다.
나는 비효율적인 내 코드 때문인가? 싶어서 한참을 고민하고 어떻게 리팩토링을 해야 할지 생각했다.</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/abecab06-c5fc-47ee-90e3-e94b041ada7f/image.png" alt=""> 계속 찾아보니 렉이 걸리는 이유가 간단한 3D 오브젝트였는데 삼각형 개수가 많아서 Unity에서 화면에 비치는 Triangle 수를 보니 million을 넘어가서 렉 걸리는 거였다...</p>
<p>렉이 그냥 Update 문에 비효율적인 코드 때려 박아서 걸리는 줄 알았는데 디자인도 매우 큰 부분을 차지한다는 것을 보고 최적화의 무겁던 무게를 약간 내려놓았다.</p>
<h2 id="-동료와의-협업에서-배운-점">• 동료와의 협업에서 배운 점</h2>
<p>누구든 배울점이 있었고 나에게 흡수하기 위해 노력했다.</p>
<h3 id="1-많이-물어보자">1. 많이 물어보자...</h3>
<p>인턴십을 하면서 모르는 거 투성이였다. Unity를 빼고 다 모르는 것들이었다.
MR 기기도 처음이었고, SDK도 처음이었고, 회사 생활도 처음이었다.</p>
<p>모르는 게 많은 게... 아니 전부 모르는 게 당연한 거였다.</p>
<p>인턴십을 하면서 많은 일들을 물어봤고, 혼자 끙끙대며 해결해 보겠다고 붙잡아보기도 했다. 어느 날은 하루 종일 해결 못해 하루를 통째로 버리기도 했고, 계속 물어보느라 대화하다 하루가 끝난 날도 있었다.</p>
<p>이러면서 느낀 점은 물어보는 게 그래도 어떤 일을 해결하는 데 가장 빠른 일이라는 것이다. 질문이라는 것은 너 나 할 것 없이 모두가 했고, 협업에서의 질문은 모르는 것을 물어보는 부분보다 내 생각을 확인하고 이해하며 같은 방향으로 향하도록 하는 부분이 크다는 것을 느꼈다.</p>
<h3 id="2-문서가-있으니-편했다">2. 문서가 있으니 편했다.</h3>
<p>학교에서 프로젝트를 만들 때면 정형적인 문서가 많지 않다.
있더라도 관리가 안 되고 있거나, 틀린 정보들도 수두룩했다.</p>
<p>회사에서는 누군가 관리하고 편집하고 내용 수정되면 추가하여 공유하고 모르는 점들은 질문하며 생각을 공유할 수 있었다.</p>
<p>회사에서 쓰는 문서들의 용도나 방식을 배울 수 있어서 좋았다. 일단 뭐라도 확인하며 이게 맞는지 볼 수 있는 자료가 있어 개발하며 길을 헤매지 않았던 것 같다.</p>
<p>여러 문서들을 배우고 이번 졸업 작품에 적용해 볼까 한다. 이번에 졸업 작품에서 WBS를 작성할까 한다.</p>
<p>다시 한번 문서의 중요성을 느꼈다.</p>
<h3 id="3-매일매일-뭐-했는지-기록했다">3. 매일매일 뭐 했는지 기록했다.</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/ce3c8e0b-40b5-452c-a54c-883e694d0e79/image.png" alt=""> 인턴을 하면서 매일매일 오전에는 뭐 했고, 오후에는 뭐 했고, 이슈 사항은 뭐가 있는지 기록했다. 이렇게 기록하고 주간 보고를 위하여 한 주를 돌아보면 한 주 만에 수많은 일들을 해왔다는 것을 알 수 있었다.</p>
<p>예전 개발했던 것들을 보며 &quot;아 맞다! 이렇게 했었지!&quot;라며 참고하기도 했고 해결한 일들을 보며 다음엔 뭘 해야 할지 방향을 잡기도 했다. 버그를 고쳤던 기록을 보며 똑같은 실수를 더 빠르게 해결했다.</p>
<p>최근부턴가 기록의 중요성을 느꼈다. 내 친구는 블로그를 관리하고, 게임잼에서 만난 어느 개발자분은 Unity에서 범주로 사용하는 기술들로 라이브러리를 만들고 있었다.</p>
<p>누군가가 그랬다. 기록이 없으면 안한 것과 다름없다고...</p>
<h3 id="4-배울-점은-업무와-관련된-것-외에-많다">4. 배울 점은 업무와 관련된 것 외에 많다.</h3>
<p>사수님께서 게임계의 해커톤인 게임잼을 알려주셨고 새로운 도전을 했었다. 덕분에 새로운 인맥을 얻었고 나의 실력을 볼 수 있었다.</p>
<p>대리님께서 좋은 회사의 조건들을 알려주셨다. 나중에 회사를 선택할 때 어떤 것들은 보면 좋을지, 뭘 주의해야 하는지...</p>
<p>과장님께서 책임감과 배려에 대하여 보여주셨다. 사소한 일에도 오해할 것 같아 배려해 주고 설명해 주시거나 자신의 일, 누군가 해야 하는 일까지도 책임감을 갖고 하시는 모습이 멋있었다.</p>
<p>이외에도 다른 사람들과의 협업에서는 혼자는 느끼지 못할 수많은 것들을 배울 수 있었다.</p>
<hr>
<h1 id="개선할-점과-앞으로의-계획">개선할 점과 앞으로의 계획</h1>
<p>기록의 중요성, 협업의 장점, 커뮤니케이션의 효과 등
이번 100일간의 경험을 통하여 많은 것을 느꼈다.</p>
<p>글 쓰는 게 귀찮아서 중요하다는 것은 알고 있으나 실천을 안 하고 있었다. 귀찮아서... 방치해놨던 이 블로그에 다시 글을 열심히 끄적여보려 한다. 기록이 없으면 안한 것과 다름없으니 예전에 했던 일들도 차차 정리해 볼까 한다. 내가 들려주고 싶은 이야기는 수없이 많으니까!</p>
<p>혼자서만 개발하다가 같이 고민하고 의견을 나눌 수 있다는 것의 큰 이점을 이번 기회에 배울 수 있었다. 지금 계속 만들고 있는 졸업 작품에 어떻게 적용할 수 있을지 고민하는 계기가 되었다. 함께 프로젝트를 만들 때 우리에게 있어서 서로 대화하며 의견을 공유할 수 있는 시간이 많이 필요한 것 같다. 그래서 이번에 2주간 계속 붙어서 집중해서 졸업 작품 개발을 해볼까 한다.</p>
<hr>
<h1 id="끝으로">끝으로</h1>
<p>나는 어떤 새로운 시도를 할 때마다 많은 고민을 한다. 수많은 사람들에게 조언을 구하고 생각해 본다.</p>
<p>그러면서 하나 배운 점이 있다. 어느 누구에게 물어보든 &quot;해보는 게 좋을 것 같다.&quot;라는 답변이 올 것 같으면 무조건 하는 게 맞는 것 같다.</p>
<p>그게 나에게 많이 껄끄럽거나 귀찮거나 힘들거나 스트레스를 많이 받을 수 있는 상황이라도...</p>
<p>이번 인턴도 그랬다. 새로운 시도는 언제나 많은 스트레스를 불러온다. 하나 그만큼 더 많은 것을 얻을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Red Brick - 몹 충돌처리]]></title>
            <link>https://velog.io/@checking_pks/Red-Brick-%EB%AA%B9-%EC%B6%A9%EB%8F%8C%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@checking_pks/Red-Brick-%EB%AA%B9-%EC%B6%A9%EB%8F%8C%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Fri, 31 Mar 2023 09:19:38 GMT</pubDate>
            <description><![CDATA[<p>플레이어와 몹이 충돌됐을 경우, 플레이어의 체력이 1 감소하는 로직을 만들어야 한다.
게임에서 최대 체력은 3으로 설정했다.
몹이 충돌했을 시, 체력이 1씩 감소하는 로직으로 제작한다.</p>
<h1 id="몹-충돌처리">몹 충돌처리</h1>
<h2 id="체력바-ui-제작">체력바 UI 제작</h2>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/53c8fb96-2949-42aa-9577-9a738ba92371/image.png" alt="">임의로 체력바를 만들어줬다.
Background UI에 hp icon이 총 3개 들어간다.</p>
<h2 id="기초-오브젝트-호출">기초 오브젝트 호출</h2>
<pre><code class="language-js">const player = getObject(&quot;player&quot;)  // Player Object
const ghosts = []                   // Monster Ghost Objects
const health = []                     // 체력 UI

// 1~3까지 순회하며 오브젝트를 찾아 배열에 추가해준다.
for (let i=1; i&lt;=3; i++)  health.push(getObject(&quot;hp&quot; + i))
for (let i=1; i&lt;=10; i++) ghosts.push(getObject(&quot;ghost&quot; + i))</code></pre>
<p>각각 오브젝트가 따로 작동해야하기 때문에
이름을 달리하여 반복문으로 가져와준다.</p>
<p><strong>충돌 감지도 각각 오브젝트마다 따로 설정해야한다.
한꺼번에 불러오니 충돌 발생 시 모든 오브젝트에 한꺼번에 이벤트가 실행됐었다...</strong></p>
<h2 id="기초-값-설정">기초 값 설정</h2>
<pre><code class="language-js">// Variables
let hp = 3</code></pre>
<p>현재 체력을 저장할 변수를 하나 설정해준다.
저 값으로 UI도 컨트롤할 것이다.</p>
<h2 id="로직-코드">로직 코드</h2>
<pre><code class="language-js">ghosts.forEach((ghost) =&gt; { // 배열 순회하며 실행
    ghost.onCollide(player, function() {  // 충돌 처리
        ghost.kill()        // 충돌된 유령 삭제
        health[--hp].hide() // 체력 1깎고 UI 숨기기
    })
})</code></pre>
<p>충돌 처리 함수이다.
모든 오브젝트에 스크립트로 누구와 충돌됐을 시 어떤 코드가 실행될지 정의해 줘야 한다.</p>
<h2 id="결과">결과!</h2>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/d6c86380-3041-49ec-8b7a-1de8013b985c/image.gif" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RedBrick - 몹 따라오기]]></title>
            <link>https://velog.io/@checking_pks/RedBrick-%EB%AA%B9-%EB%94%B0%EB%9D%BC%EC%98%A4%EA%B8%B0</link>
            <guid>https://velog.io/@checking_pks/RedBrick-%EB%AA%B9-%EB%94%B0%EB%9D%BC%EC%98%A4%EA%B8%B0</guid>
            <pubDate>Sat, 25 Mar 2023 06:36:50 GMT</pubDate>
            <description><![CDATA[<p>내가 만들려는 게임에서는 유령 몹이 플레이어를 따라와야 하고, 플레이어를 계속 바라봐야 한다.</p>
<p>Unity에서는 transform.Lerp와 LookAt으로 이미 만들어져 있는 함수로 쉽게 구현이 가능하지만, RedBrick에서는 없기 때문에 만들어보자.</p>
<h1 id="몹-따라오기">몹 따라오기</h1>
<h2 id="기초-몹-호출">기초 몹 호출</h2>
<p>몹을 따라오는 함수를 사용하려면 일단 몹을 불러와야 한다.</p>
<p>몬스터는 여러 마리 존재하기 때문에 배열로 호출하여 불러왔다.
따라갈 플레이어도 불러와준다.</p>
<pre><code class="language-js">const player = getObject(&quot;player&quot;)          // Player Object
const ghosts = getObjectsByName(&quot;ghost&quot;)    // Monster Ghost Objects</code></pre>
<p><code>getObject(string)</code>는 Title 기준으로 하나의 객체만 불러오고,
<code>getObjectsByName(string)</code>은 Title 기준으로 동일한 친구들을 모두 불러온다.</p>
<h2 id="코드-ver-10">코드 Ver 1.0</h2>
<pre><code class="language-js">const speed = 10.0;

setInterval(() =&gt; 
{
    for (var i=0; i&lt;ghosts.length; i++)
    {
        ghosts[i].moveX(player.getPosition().x - ghosts[i].getPosition().x, speed)
        ghosts[i].moveY(player.getPosition().y - ghosts[i].getPosition().y + 1, speed)
        ghosts[i].moveZ(player.getPosition().z - ghosts[i].getPosition().z, speed)
    }
})</code></pre>
<p>움직이는 함수는 <code>moveX(dx, speed)</code>, <code>moveY(dy, speed)</code>, <code>moveZ(dz, speed)</code>를 사용하였다.
자신 위치를 기준으로 얼만큼(<code>dx</code>, <code>dy</code>, <code>dz</code>)을 몇의 속도(<code>speed</code>)로 움직인다.</p>
<p><code>goTo</code>는 한번에 그 위치로 이동하는 함수여서 따로 또 Lerp값을 구해줘야해서 자신 기준으로 움직이는 함수를 사용하였다.</p>
<p>자신의 위치를 기준으로 플레이어의 방향으로 크기만큼 시간에 걸쳐 이동하게 된다.</p>
<h3 id="문제점">문제점</h3>
<p>이러면 몹들이 잘 따라오긴 하는데 문제점이 하나 생겼다.
<img src="https://velog.velcdn.com/images/checking_pks/post/e4a14e3b-53bf-4663-9f46-868f4c3a5c2a/image.png" alt=""> x, y, z 모두 동일한 속도로 이동하면 <strong>(a)</strong>와 같이 x 거리와 y 거리가 같다면 문제가 없지만
<strong>(b)</strong>와 같이 거리가 다르다면 x축을 먼저 모두 이동해버리고, y축을 이동하여 부자연스러운 느낌이 발생했다.</p>
<h2 id="코드-ver-20">코드 Ver 2.0</h2>
<pre><code class="language-js">function monsterFollow(monster)
{
  let _disX = player.getPosition().x - monster.getPosition().x
  let _disY = player.getPosition().y - monster.getPosition().y
  let _disZ = player.getPosition().z - monster.getPosition().z

  let _dis = abs(sqrt(_disX * _disX + _disY * _disY + _disZ * _disZ))

  monster.moveX(_disX     , abs(_disX) / _dis * monsterMoveSpeed)
  monster.moveY(_disY + 1 , abs(_disY) / _dis * monsterMoveSpeed) // +1 해줘야 몸을 타겟으로 따라감
  monster.moveZ(_disZ     , abs(_disZ) / _dis * monsterMoveSpeed)
}</code></pre>
<p>사용이 쉽도록 함수로 묶어줬고, 속도에 플레이어까지 길이 비율을 곱했다.
길이가 짧으면 천천히가고, 길면 더 빨리 가도록 코드를 수정하여 해결하였다.</p>
<h2 id="결과">결과!</h2>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/7a0fc567-ffac-4733-8fe9-f454bb5c9c2b/image.gif" alt="">
몹 따라오기 완성!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[레드브릭 인디 챌린져스 선정!]]></title>
            <link>https://velog.io/@checking_pks/%EB%A0%88%EB%93%9C%EB%B8%8C%EB%A6%AD-%EC%9D%B8%EB%94%94-%EC%B1%8C%EB%A6%B0%EC%A0%B8%EC%8A%A4-%EC%84%A0%EC%A0%95</link>
            <guid>https://velog.io/@checking_pks/%EB%A0%88%EB%93%9C%EB%B8%8C%EB%A6%AD-%EC%9D%B8%EB%94%94-%EC%B1%8C%EB%A6%B0%EC%A0%B8%EC%8A%A4-%EC%84%A0%EC%A0%95</guid>
            <pubDate>Sat, 25 Mar 2023 05:58:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/checking_pks/post/67264a2d-c84f-48f3-9556-2c262cf6df85/image.jpg" alt="인디챌린저스"></p>
<p><strong>레드브릭에서 주최하는 공모전에 신청해서 참가 선정이 되었다!</strong></p>
<p>이번 공모전의 주제는 하이퍼 캐주얼 게임이었다.
하이퍼 캐주얼이면... 조작감은 쉬워야 되고 뭔가 직관적이어야 된다고 생각했다.</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/90208608-567c-456a-b78d-2c760fd91bfd/image.jpeg" alt="">그래서 어릴 때 재미있게 했던 <strong>&quot;Tilt to live&quot;</strong>라는 모바일 게임을 <strong>레드브릭 툴</strong>을 사용하여 만들어보려 했다.</p>
<p>빨간 점들이 따라와서 캐릭터를 잡고, 캐릭터는 움직이면서 아이템을 먹는다.
아이템마다 효과가 있고, 그 효과들로 빨간 점을 잡을 수 있게 된다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/fa051bfc-d64b-4fba-8f7f-150e48b438f5/image.bmp" alt="">2D의 모바일 게임을 3D의 레드브릭에서 구현하고, 빨간 점들은 유령으로 디자인을 바꿔 귀신 놀이동산으로 재탄생 시켰다.</p>
<p>유령을 피해서 제한 시간동안 살아남는 게임!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[OpenCV] SURF 알고리즘 코드 작성!]]></title>
            <link>https://velog.io/@checking_pks/OpenCV-SURF-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1</link>
            <guid>https://velog.io/@checking_pks/OpenCV-SURF-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1</guid>
            <pubDate>Sat, 11 Feb 2023 08:35:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>✅ 환경 세팅은 이전 글들을 확인해주세요!</p>
</blockquote>
<h1 id="surf-알고리즘-코드">SURF 알고리즘 코드</h1>
<p>SURF 알고리즘은 크게 2가지의 과정으로 진행된다.</p>
<ol>
<li>각 이미지에서 키포인트를 검출한다!</li>
<li>키포인트로 두 이미지를 매칭한다!</li>
</ol>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/82614f05-bdbd-448c-a84c-840bf042d26a/image.png" alt="TestImage">테스트 이미지는 같은 물체가 있는 각도가 다른 두 사진으로 진행하였다.</p>
<h2 id="전체-코드">전체 코드</h2>
<pre><code class="language-python">import cv2

# 이미지 불러오기 (확장자까지 적기!)
photo01 = cv2.imread(&quot;image01.jpg&quot;)
photo02 = cv2.imread(&quot;image02.jpg&quot;)

# 이미지가 너무 커서 사이즈 조절
photo01 = cv2.resize(photo01, (346, 462), cv2.INTER_LINEAR)
photo02 = cv2.resize(photo02, (346, 462), cv2.INTER_LINEAR)

# SURF 알고리즘 객체 생성 (500은 Threshold_임계값)
feature = cv2.xfeatures2d.SURF_create(500)

# 각 이미지에서 키포인트 추출
keyPoint01, descriptors01 = feature.detectAndCompute(photo01, None)
keyPoint02, descriptors02 = feature.detectAndCompute(photo02, None)

# Brute-force 방식으로 매칭
matcher = cv2.BFMatcher(cv2.NORM_L1, True)
matches = matcher.match(descriptors01, descriptors02)

# 키포인트 및 매칭 결과를 이미지에 그리기
keyPointImage01 = cv2.drawKeypoints(photo01, keyPoint01, None, None, cv2.DRAW_MATCHES_FLAGS_DEFAULT)
keyPointImage02 = cv2.drawKeypoints(photo02, keyPoint02, None, None, cv2.DRAW_MATCHES_FLAGS_DEFAULT)
matchImage = cv2.drawMatches(photo01, keyPoint01, photo02, keyPoint02, matches, None)

# 이미지 출력
cv2.imshow(&quot;keyPoint Image 01&quot;, keyPointImage01)
cv2.imshow(&quot;keyPoint Image 02&quot;, keyPointImage02)
cv2.imshow(&quot;match Image&quot;, matchImage)
cv2.waitKey(0)</code></pre>
<p>일단 전체 코드를 확인하고 하나하나 분석을 해보자.</p>
<h2 id="이미지-전처리-과정">이미지 전처리 과정</h2>
<pre><code class="language-python"># 이미지 불러오기 (확장자까지 적기!)
photo01 = cv2.imread(&quot;image01.jpg&quot;)
photo02 = cv2.imread(&quot;image02.jpg&quot;)

# 이미지가 너무 커서 사이즈 조절
photo01 = cv2.resize(photo01, (512, 512), cv2.INTER_LINEAR)
photo02 = cv2.resize(photo02, (512, 512), cv2.INTER_LINEAR)</code></pre>
<p>이미지는 불러오자마자 쓸 수 있는 상태가 되면 더 없이 좋겠지만 아닐 가능성이 높다.
이미지가 너무 커서 불러와 한 번 조절하는 과정을 진행하였다.</p>
<p><em>※ 참조 : 두 이미지의 크기가 달라도 상관없다.</em></p>
<h2 id="키포인트-추출">키포인트 추출</h2>
<pre><code class="language-python"># SURF 알고리즘 객체 생성 (500은 Threshold_임계값)
feature = cv2.xfeatures2d.SURF_create(500)

# 각 이미지에서 키포인트 추출
keyPoint01, descriptors01 = feature.detectAndCompute(photo01, None)
keyPoint02, descriptors02 = feature.detectAndCompute(photo02, None)</code></pre>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/bc2bde2f-c098-433c-ba82-1d3564f94c7f/image.jpg" alt="Threshold"> 왼쪽부터 임계값이 <strong>0</strong>일때, <strong>500</strong>일때, <strong>1000</strong>일때 이다.</p>
<p>SURF 알고리즘 객체를 생성할 때 값 안에 넣는 임계값에 따라 검출되는 키포인트 개수가 달라진다.
임계값이 <strong>높을수록</strong>! 키포인트 값이 <strong>높아야 하므로</strong>! 더 <strong>적은 키포인트가 검출</strong>된다.</p>
<ul>
<li>임계값은 500정도가 적당한 개수의 키포인트가 검출된다.</li>
</ul>
<p>이후 각 이미지에서 키포인트를 검출해주고 저장한다.</p>
<h2 id="키포인트-매칭">키포인트 매칭</h2>
<pre><code class="language-python"># Brute-force 방식으로 매칭
matcher = cv2.BFMatcher(cv2.NORM_L1, True)
matches = matcher.match(descriptors01, descriptors02)</code></pre>
<p>키포인트를 매칭할때는 Brute-force 방식으로 매칭한다.
각각 하나씩 대칭해보면서 가장 적절한 키포인트와 매칭하는 방식이다.</p>
<blockquote>
<p><code>matcher.match()</code>함수는 첫번째 키포인트들을 두번째 키포인트에 매칭하는 방식이다.
그래서 두 순서가 바뀐다면 값이 다르게 나올 수 있다!</p>
</blockquote>
<h2 id="키포인트-및-매칭-결과-그리기">키포인트 및 매칭 결과 그리기</h2>
<pre><code class="language-python"># 키포인트 및 매칭 결과를 이미지에 그리기
keyPointImage01 = cv2.drawKeypoints(photo01, keyPoint01, None, None, cv2.DRAW_MATCHES_FLAGS_DEFAULT)
keyPointImage02 = cv2.drawKeypoints(photo02, keyPoint02, None, None, cv2.DRAW_MATCHES_FLAGS_DEFAULT)
matchImage = cv2.drawMatches(photo01, keyPoint01, photo02, keyPoint02, matches, None)

# 이미지 출력
cv2.imshow(&quot;keyPoint Image 01&quot;, keyPointImage01)
cv2.imshow(&quot;keyPoint Image 02&quot;, keyPointImage02)
cv2.imshow(&quot;match Image&quot;, matchImage)
cv2.waitKey(0)</code></pre>
<p>이미지에 keyPoint를 그릴 때 <code>cv2.drawKeypoints()</code>를 사용
매칭된 결과를 그릴 때 <code>cv2.drawMatches()</code>를 사용</p>
<h3 id="keypoint-그리기">keyPoint 그리기</h3>
<p><code>cv2.drawKeypoints(image: Mat, keypoints: Any, outImage: Any, color: ... = ..., flags: int = ...)</code>
drawKeypoints 함수의 형태이다.</p>
<ul>
<li>image : keyPoint를 그릴 원본 이미지</li>
<li>keypoints : 검출한 키포인트 값</li>
<li>outImage : 저장할 변수 (안할거면 None)</li>
<li>color : 키포인트 색깔 (랜덤이면 None)</li>
<li>flags : 값을 표현하는 방식에 대한 태그</li>
</ul>
<h4 id="color">color</h4>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/aee1e3e3-6e78-46ed-817b-e326bb5f0732/image.jpg" alt="Color">좌측의 경우 랜덤 <code>None</code>, 우측의 경우 Cyan <code>(255, 255, 0)</code></p>
<p><code>color</code>의 경우 <code>(blue, green, red)</code>의 형태로 0~255를 넣으면 대응하는 색으로 키포인트가 표시된다. <code>None</code>으로 할 경우 각 키포인트마다 랜덤한 색이 부여된다.</p>
<h4 id="flags">flags</h4>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/367114c9-4fd5-4bc7-9f98-bf8a41c06fe6/image.jpg" alt="flags">
좌측의 경우 키포인트 위치만 출력 <code>cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS</code> 
우측의 경우 키포인트 크기와 방향까지 출력 <code>cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS</code></p>
<p>flags에 <code>cv2.DRAW_MATCHES_FLAGS_DEFAULT</code>나 <code>cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS</code>를 넣으면 위치 값만 보여주는 작은 점들로 그려진다.
<code>cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS</code>를 넣으면 위치 뿐만 아니라 크기 및 방향까지 보여준다.</p>
<h3 id="matching-결과-그리기">Matching 결과 그리기</h3>
<p><code>cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchColor=..., singlePointColor=..., matchesMask=..., flags: int = ...)</code>
drawMatches 함수의 형태이다.</p>
<ul>
<li>img1 : 매칭에 사용한 이미지 원본 1</li>
<li>keypoints1 : img1의 키포인트</li>
<li>img2 : 매칭에 사용한 이미지 원본 2</li>
<li>keypoints2 : img2의 키포인트</li>
<li>matches1to2 : 매칭 결과값</li>
<li>outImg : 저장할 변수 (안할거면 None)</li>
<li>matchColor : 매칭된 선 색깔 (랜덤이면 None)</li>
<li>singlePointColor : 매칭되지 않은 키포인트 색깔 (랜덤이면 None)</li>
<li>matchesMask : 매칭을 시도할 부분의 마스크 (값 없으면 모든 키포인트를 매칭)</li>
<li>flags : 값을 표현하는 방식에 대한 태그</li>
</ul>
<h4 id="matchcolor-singlepointcolor">matchColor, singlePointColor</h4>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/f5ba5123-9dfd-4cba-80bf-548f1d1569aa/image.png" alt="color change">
matchColor를 Cyan <code>(255, 255, 0)</code>, singlePointColor를 Red <code>(0, 0, 255)</code>로 설정</p>
<p>매칭이 된 키포인트와 선은 matchColor가 되며, 매칭이 되지 않은 키포인트는 singlePointColor가 된다.
각각 None일 경우 랜덤한 색깔로 설정된다.</p>
<h4 id="flags-1">flags</h4>
<p>flags는 총 3가지가 있다.
<code>DEFAULT</code>, <code>NOT_DRAW_SINGLE_POINTS</code>, <code>DRAW_RICH_KEYPOINTS</code></p>
<ul>
<li><p><code>DEFAULT</code>
<img src="https://velog.velcdn.com/images/checking_pks/post/4633ee74-1ff2-4702-9648-8f20ac28de4d/image.png" alt="default">키포인트는 위치 값만, 모든 키포인트를 표현하는 방식</p>
</li>
<li><p><code>NOT_DRAW_SINGLE_POINTS</code>
<img src="https://velog.velcdn.com/images/checking_pks/post/62800796-ecbe-404e-b07e-ba087b09327e/image.png" alt="notSingle">매칭된 키포인트들만 표현하는 방식</p>
</li>
<li><p><code>DRAW_RICH_KEYPOINTS</code>
<img src="https://velog.velcdn.com/images/checking_pks/post/277487b5-f744-4028-b5a4-1d1c5c7f6cd3/image.png" alt="rich keypoints">키포인트가 위치 뿐만 아니라 크기와 방향까지 표현하는 방식</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[OpenCV] SURF 알고리즘 환경 세팅]]></title>
            <link>https://velog.io/@checking_pks/OpenCV-SURF-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@checking_pks/OpenCV-SURF-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Sat, 11 Feb 2023 01:06:00 GMT</pubDate>
            <description><![CDATA[<h1 id="surf-알고리즘-환경-세팅">SURF 알고리즘 환경 세팅</h1>
<p>SURF 알고리즘을 사용하려면 OpenCV 모듈을 사용해야 한다.
그리고 SURF 알고리즘이 특허가 걸려서 사용하기 위해서는 <strong>OpenCV 이전 버전</strong>을 사용해야 한다.
본 글에서는 OpenCV 및 SURF 알고리즘을 하기 위한 세팅 방법을 알아보자.</p>
<hr>
<h2 id="환경-세팅-방법">환경 세팅 방법</h2>
<p>OpenCV는 Python, C++, C# 등 많은 언어로 모듈을 지원하고 있다.
그 중 환경 설정이 비교적 쉬운 Python으로 OpenCV 환경을 설정하는 방법을 알아보자.</p>
<h3 id="anaconda-설치">Anaconda 설치</h3>
<p>Anaconda Website
<a href="https://www.anaconda.com/">Anaconda | The World&#39;s Most Popular Data Science Platform</a>
<img src="https://velog.velcdn.com/images/checking_pks/post/745f2518-22ac-4553-a5f8-6930d57793f4/image.jpg" alt="Anaconda">아나콘다 웹 사이트로 들어가서 Download 버튼을 눌러 설치하면 된다.</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/dc2a31cb-68f8-4032-a78f-921c430e7e97/image.jpg" alt="Anaconda01">실행하면 이런 창이 뜰 것이다. 
<strong>Click (<em>Next &gt;</em>)</strong>
<img src="https://velog.velcdn.com/images/checking_pks/post/e87bc8f2-a3ae-4f2b-9d00-41c9cecb5a71/image.jpg" alt="Anaconda02"><strong>Click (<em>I Agree</em>)</strong>
<img src="https://velog.velcdn.com/images/checking_pks/post/dd545fca-ba8f-42ea-b922-482afa2ba1e3/image.jpg" alt="Anaconda03"><strong>Check (<em>Just Me (recommended)</em>)</strong>
<strong>Click (<em>Next &gt;</em>)</strong>
<img src="https://velog.velcdn.com/images/checking_pks/post/feacf53e-3e24-4bcf-882e-fe8de29464a5/image.jpg" alt="Anaconda04">
<strong>Click (<em>Next &gt;</em>)</strong></p>
<blockquote>
<p>만약 에러 창이 뜬다면!
<strong>1. Directory &#39;<em>경로</em>&#39; is not empty, please choose a different location.</strong></p>
<ul>
<li>아나콘다 설치는 빈 폴더에만 가능하다. 저 폴더에 뭔가 들어가 있다는 문제이니 폴더를 비우거나 새로운 폴더를 만들어서 경로를 변경해주면 해결 가능하다.</li>
</ul>
<p><strong>2. Error. Path <em>경로</em> is not writable. Please check permissions or try respawning the installer with elevated privileges.</strong></p>
<ul>
<li>경로에 파일 생성 권한이 없어서 설치를 못하는 문제다. 경로의 권한이 있는 곳에 폴더를 만들어 경로를 변경하고 설치하면 해결 가능하다.</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/33bfe36c-4126-4ef4-84f3-4b1a5ce0d91b/image.jpg" alt="Anaconda05">고급 옵션들이나 OpenCV에서는 그냥 설치를 진행해보자.
<strong>Click (<em>Install</em>)</strong></p>
<p>이후에는 자동으로 설치가 진행된다.</p>
<h3 id="가상환경-생성">가상환경 생성</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/e23b110e-3535-45fe-a258-64f3612fcfad/image.png" alt="Anaconda Navigator01">설치가 완료되면 Anaconda Navigator를 실행시켜준다.
<img src="https://velog.velcdn.com/images/checking_pks/post/534a623f-28e3-4be4-a3a1-c1526dde997a/image.png" alt="Anaconda navigator02">가상환경을 만들기 위해서는 옆의 Environments를 클릭
<img src="https://velog.velcdn.com/images/checking_pks/post/a2129e02-275b-4058-bd46-542cbfc4f50e/image.png" alt="">이런 창이 뜰 텐데 가상환경 별로 설치된 모듈을 볼 수 있는 창이다.
우리는 새로운 가상환경을 만들어야 하니 아래 Create를 클릭</p>
<blockquote>
<p>가상환경을 만드는 이유!</p>
<ul>
<li>하나의 컴퓨터에서 Python으로 머신러닝도 하고, OpenCV도 하고, 크롤링도 하고... 등등 여러 가지 작업을 할 수 있으므로 버전 관리와 모듈 관리를 위해서 가상환경을 만들어서 관리하는 것이 좋다.</li>
</ul>
</blockquote>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/104a4970-11d6-4409-9da9-d1a7d72186d9/image.png" alt="Anaconda navigator03">Name : 가상환경의 이름
Packages : 프로그래밍 언어의 버전</p>
<p>이름은 자신이 알 수 있는 형태로 지어놓으면 되고, (ex. &quot;OpenCV&quot;나 &quot;SURF&quot; 등)
버전은 SURF 알고리즘을 사용하기 위해 <strong>Python 3.7.15</strong>로 설정하여 생성한다.</p>
<h3 id="opencv-모듈-설치">OpenCV 모듈 설치</h3>
<p>SURF 알고리즘이 특허가 걸려서 사용하기 위해서는 OpenCV 이전 버전을 사용해야 한다.</p>
<p>이전 버전 친구들 다운로드 링크</p>
<ul>
<li><a href="https://pypi.org/project/opencv-python/3.4.2.16/#files">OpenCV_Python_3.4.2.16</a></li>
<li><a href="https://pypi.org/project/opencv-contrib-python/3.4.2.16/#files">OpenCV_Contrib_Python_3.4.2.16</a></li>
</ul>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/dd01c310-4b81-4cdb-b41a-86759f6f8b10/image.png" alt="Module Download Page"> 두 링크 다 들어가면 이런 형식의 사이트가 나올 것이다. </p>
<p>우리가 다운받아야 될 친구는 </p>
<ul>
<li><strong>opencv_python-3.4.2.16-cp37-cp37m-win_amd64.whl</strong></li>
<li><strong>opencv_contrib_python-3.4.2.16-cp37-cp37m-win_amd64.whl</strong></li>
</ul>
<blockquote>
<p>위 파일 이름의 뜻은 이것이다. (다른 친구를 다운받지 않도록 조심)</p>
</blockquote>
<ul>
<li>둘 다 동일한 버전 (3.4.2.16)</li>
<li>아까 설치한 python 3.7.15 버전(cp37)</li>
<li>운영체제 윈도우 (win_amd64)</li>
</ul>
<p>다운을 받았다면 가상환경에 모듈을 설치해 보자.
다시 Anaconda Navigator를 켜주고, Environments를 들어가면 아까 만든 가상환경이 보일 것이다.</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/4de08448-9886-48f1-a09b-849434251f0b/image.png" alt="Anaconda navigator04">그 친구를 눌러주면 옆에 초록색 화살표가 생기는데 거기에 <strong>Open Terminal</strong>을 눌러준다.
<img src="https://velog.velcdn.com/images/checking_pks/post/5d2bd112-3e01-46d1-8463-d224b5b425a5/image.jpg" alt="cmd01">그러면 이런 cmd 창이 뜰 것이다. <code>(가상환경 이름) 경로&gt;</code>
우리는 다운로드한 whl 파일 두 개의 위치로 가서 설치를 해야 한다.
<code>cd 경로</code>를 입력한다. (ex. 다운로드 폴더에 있으면 <code>cd C:\Users\~\Downloads</code> 이런 느낌으로 하면 된다.)
<img src="https://velog.velcdn.com/images/checking_pks/post/901c1ad0-2063-46e2-bca2-d3040d2036dc/image.png" alt="cmd02">옆의 경로가 방금 입력한 경로로 변한 것을 볼 수 있다.</p>
<p>그럼 이제 다운받은 모듈들을 설치해 보자! (설치 순서도 동일하게 opencv_python을 먼저 설치해 준다.)</p>
<ul>
<li><code>pip install opencv_python-3.4.2.16-cp37-cp37m-win_amd64.whl</code></li>
<li><code>pip install opencv_contrib_python-3.4.2.16-cp37-cp37m-win_amd64.whl</code></li>
</ul>
<p>두 명령어를 복사하여 실행해주면 설치가 된다.</p>
<h3 id="vs-code에서-python-파일-생성">VS Code에서 Python 파일 생성</h3>
<p>많은 IDE가 있겠지만 우리는 <strong>Visual Studio Code</strong>를 사용해 보자.</p>
<p>Visual Studio Code Website
<a href="https://code.visualstudio.com/">Visual Studio Code - Code Editing. Redefined</a>
<img src="https://velog.velcdn.com/images/checking_pks/post/d6436b9e-c9c9-4b5e-afef-290544075df4/image.png" alt="VS Code Wepsite">위의 링크에서 VS Code 다운로드 및 설치</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/043d9009-e42b-4368-b2b7-1418e8bdb339/image.png" alt="VSCode01">VS Code를 실행시켜 옆의 네모 박스 쌓인 아이콘(Extensions)을 눌러 검색창에 
<strong>python</strong>과 <strong>Code Runner</strong>를 검색하여 <strong>Install</strong> 해주고 VS Code를 껐다가 다시 실행해준다.</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/45d4b07e-b0d0-4586-9505-2a42e06dcad0/image.png" alt="VSCode02">이후 <strong>File</strong>에서 <strong>New File</strong>로 Python 파일을 생성하거나 <strong>Open Folder</strong>로 폴더를 열 수 있다.</p>
<h4 id="1-new-file로-파일-생성">1. New File로 파일 생성</h4>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/e5e5033c-c4bc-4825-8e0a-d134c8a12fea/image.png" alt="VSCode03">
<code>File → New File... → Python File</code>
위 방식으로 누르면 <em>Untitled-1</em> 이름으로 파일이 생성될 것이다.
<img src="https://velog.velcdn.com/images/checking_pks/post/8bdcc0b2-6b48-4e7f-b549-0ec0d3582ddf/image.png" alt="Save"> <strong>이때 꼭 Ctrl+S(저장하기)를 눌러서 원하는 위치에 저장하고 코드를 작성하는 것을 추천한다.</strong>
<br> </p>
<h4 id="2-open-folder로-폴더-열기">2. Open Folder로 폴더 열기</h4>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/838ce8f9-b422-4c1f-8712-bb3240331534/image.png" alt="Open">
<code>File → Open Folder...</code>
위 방식으로 누르면 폴더를 선택할 수 있는 창이 뜬다. 이 때 파일을 관리할 폴더를 선택해준다.
<img src="https://velog.velcdn.com/images/checking_pks/post/80917f07-a554-4db0-ae14-5564efd2ffcd/image.png" alt="VSCode05"> 폴더를 선택해주면 좌측 종이가 겹쳐 그려진 아이콘(Explorer)을 클릭하면 옆 창에 선택한 폴더 안 파일들이 보인다. (현재는 빈 폴더이므로 아무것도 안보인다.)</p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/f7c17307-0aa8-47bc-87ac-354b97d52321/image.png" alt="Folder"> (현 사진에서는 Python이라는 이름의 폴더를 선택하였다.)
옆의 파일+ 아이콘을 눌러 파일을 추가하거나, 폴더+ 아이콘을 눌러 폴더를 추가하면 된다.
※ 파일 만들 때 ~.py 확장자까지 작성해야 파이썬 파일이 된다.</p>
<h3 id="opencv-코드-테스트">OpenCV 코드 테스트</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/117036a5-4693-4c16-a7a9-d26014061960/image.png" alt="version output test"></p>
<pre><code class="language-python">import cv2

# 버전을 출력하는 코드
print(cv2.__version__)</code></pre>
<p>위 코드를 작성하고 <code>Ctrl+F5</code>를 눌러 실행하면 아래와 같이 OpenCV 버전인 3.4.2가 출력되면 성공!
그리고 아래 빨간 박스를 보면 가상환경의 이름과 파이썬 버전이 보이는 것을 확인할 수 있다.</p>
<hr>
<p>이후 SURF 알고리즘 코드를 작성하는 것은 다음 글에서 알아보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[OpenCV] 이미지 처리 기본 코드]]></title>
            <link>https://velog.io/@checking_pks/OpenCV-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@checking_pks/OpenCV-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Mon, 24 Oct 2022 12:55:58 GMT</pubDate>
            <description><![CDATA[<h1 id="opencv-이미지-처리">OpenCV 이미지 처리</h1>
<h2 id="opencv-모듈-가져오기">OpenCV 모듈 가져오기</h2>
<pre><code class="language-python">import cv2

# 만약 ModuleNotFoundError가 날 경우, 하단 코드를 터미널에 입력
# pip install opencv-python</code></pre>
<hr>
<h2 id="이미지-불러오기">이미지 불러오기</h2>
<h3 id="기본-형태">기본 형태</h3>
<pre><code class="language-python">cv2.imread(filename, flags=&#39;IMREAD_COLOR&#39;) -&gt;    retval</code></pre>
<ul>
<li>filename : 불러올 파일 경로<ul>
<li>파일의 경로는 상대 경로와 절대 경로 둘 다 가능합니다.<ul>
<li>상대 경로 : 실행되는 코드 기준으로 경로가 지정됩니다.<ul>
<li>ex) filename = &#39;imagesFolder/flower.png&#39;</li>
</ul>
</li>
<li>절대 경로 : 컴퓨터의 기준으로 경로가 지정됩니다.<ul>
<li>ex) filename = &#39;C:/Users/Default/imagesFolder/flower.png&#39;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>flags : 이미지 불러오는 모드 (기본값 : ‘IMREAD_COLOR’)<ul>
<li>이미지 불러오는 모드는 <a href="https://docs.opencv.org/3.4/d8/d6a/group__imgcodecs__flags.html#gga61d9b0126a3e57d9277ac48327799c80af660544735200cbe942eea09232eb822">다양한 종류</a>가 있지만 크게 두 종류가 있습니다.<ul>
<li>IMREAD_COLOR : 컬러 색상으로 이미지를 불러옵니다.</li>
<li>IMREAD_GRAYSCALE : 회색조 색상으로 이미지를 불러옵니다.
<img src="https://velog.velcdn.com/images/checking_pks/post/4cba95a1-9d68-47a0-9d80-679e736101da/image.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>※ 이미지를 읽을 수 없는 경우(파일 누락, 부적절한 권한, 지원되지 않거나 잘못된 형식으로 인해) 함수는 빈 행렬(NULL)을 반환합니다.</p>
<h3 id="읽을-수-있는-파일-목록">읽을 수 있는 파일 목록</h3>
<ul>
<li>Windows 비트맵 - *.bmp, *.dib</li>
<li>JPEG 파일 - *.jpeg, *.jpg, *.jpe</li>
<li>JPEG 2000 파일 - *.jp2</li>
<li>휴대용 네트워크 그래픽 - *.png</li>
<li>WebP - *.webp</li>
<li>휴대용 이미지 형식 - *.pbm, *.pgm, *.ppm *.pxm, *.pnm</li>
<li>Sun 래스터 - *.sr, *.ras</li>
<li>TIFF 파일 - *.tiff, *.tif</li>
<li>OpenEXR 이미지 파일 - *.exr</li>
<li>Radiance HDR - *.hdr, *.pic</li>
<li>GDAL에서 지원하는 래스터 및 벡터 지리 공간 데이터</li>
</ul>
<h3 id="코드-사용-예시">코드 사용 예시</h3>
<pre><code class="language-python">import cv2 # OpenCV 모듈 불러오기

# 절대 경로로 바탕화면의 sky.jpg를 불러와 img 변수에 저장
img = cv2.imread(&#39;C:/Users/Default/Desktop/sky.jpg&#39;, cv2.IMREAD_COLOR)</code></pre>
<hr>
<h2 id="이미지-출력">이미지 출력</h2>
<h3 id="기본-형태-1">기본 형태</h3>
<pre><code class="language-python">cv2.imshow(winname, mat) -&gt;    None</code></pre>
<ul>
<li>winname : 열리는 창의 이름</li>
<li>mat : 출력할 이미지 Mat</li>
</ul>
<h3 id="코드-사용-예시-1">코드 사용 예시</h3>
<pre><code class="language-python">import cv2 # OpenCV 모듈 불러오기

# 절대 경로로 바탕화면의 sky.jpg를 불러와 img 변수에 저장
image1 = cv2.imread(&#39;C:/Users/Default/Desktop/sky.jpg&#39;, cv2.IMREAD_COLOR)

# &#39;this is sky&#39;라는 창에 image1을 출력합니다.
cv2.imshow(&#39;this is sky&#39;, image1)
cv2.waitKey() # waitKey는 창을 확인하기 위하여 추가합니다. (없을시 코드가 바로 종료됩니다.)</code></pre>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/0c560ad7-cebe-4b08-a262-1f7fc3f71977/image.png" alt=""></p>
<hr>
<h2 id="이미지-크기-변경">이미지 크기 변경</h2>
<h3 id="기본-형태-2">기본 형태</h3>
<pre><code class="language-python">cv.resize(src, dsize, fx = 0, fy = 0, interpolation = cv2.INTER_LINEAR) -&gt; dst</code></pre>
<ul>
<li>src : 크기를 변경할 이미지 Mat</li>
<li>dsize : 변경할 이미지 절대 크기 (가로, 세로)</li>
<li>fx : 가로 상대 크기 (기본 값 : 0)</li>
<li>fy : 세로 상대 크기 (기본 값 : 0)</li>
<li>interpolation : 보간법 (기본 값 : cv2.INTER_LINEAR)</li>
</ul>
<pre><code>| cv2.INTER_NEAREST | 최근접 이웃 보간 |
| --- | --- |
| cv2.INTER_LINEAR | 쌍선형 보간법 |
| cv2.INTER_LINEAR_EXACT | 비트 쌍 선형 보간법 |
| cv2.INTER_CUBIC | 바이큐빅 보간법 |
| cv2.INTER_AREA | 영역 보간법 |
| cv2.INTER_LANCZOS4 | Lanczos 보간법 |</code></pre><p>※ dsize, fx, fy가 모두 0일 시 오류가 발생합니다.</p>
<p>※ 상대 크기로 변경하려면 절대 크기가 (0, 0) 이어야 합니다.</p>
<p>→ 상대 크기로 이미지 변경 후 절대 크기로 변경하는 순서이기 때문</p>
<h3 id="코드-사용-예시-2">코드 사용 예시</h3>
<pre><code class="language-python">import cv2 # OpenCV 모듈 불러오기

# 절대 경로로 바탕화면의 sky.jpg를 불러와 img 변수에 저장
image1 = cv2.imread(&#39;C:/Users/Default/Desktop/sky.jpg&#39;, cv2.IMREAD_COLOR)

# image1의 크기를 512, 512로 변경하고 nowImage에 저장
nowImage = cv2.resize(image1, (512, 512), 0, 0, cv2.INTER_CUBIC)

# &#39;this is sky&#39;라는 창에 image1을 출력합니다.
cv2.imshow(&#39;this is sky&#39;, nowImage)
cv2.waitKey() # waitKey는 창을 확인하기 위하여 추가합니다. (없을시 코드가 바로 종료됩니다.)</code></pre>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/1df7ba62-5119-48a3-8891-c69ef9b3bfdb/image.png" alt=""></p>
<hr>
<h2 id="이미지-저장">이미지 저장</h2>
<h3 id="기본-형태-3">기본 형태</h3>
<pre><code class="language-python">cv2.imwrite(filename, img) -&gt; retval</code></pre>
<ul>
<li>filename : 저장할 파일 경로<ul>
<li>파일의 경로는 상대 경로와 절대 경로 둘 다 가능합니다.<ul>
<li>상대 경로 : 실행되는 코드 기준으로 경로가 지정됩니다.<ul>
<li>ex) filename = &#39;imagesFolder/flower.png&#39;</li>
</ul>
</li>
<li>절대 경로 : 컴퓨터의 기준으로 경로가 지정됩니다.<ul>
<li>ex) filename = &#39;C:/Users/Default/imagesFolder/flower.png&#39;</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>img : 저장할 이미지 Mat</li>
</ul>
<h3 id="코드-사용-예시-3">코드 사용 예시</h3>
<pre><code class="language-python">import cv2

image1 = cv2.imread(&#39;C:/Users/Default/Desktop/sky.jpg&#39;, cv2.IMREAD_GRAYSCALE)
cv2.imwrite(&#39;graySky.png&#39;, image1)</code></pre>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/3dcd2f87-4395-4725-9582-8d6cd9a06994/image.png" alt=""></p>
<h1 id="참조">참조</h1>
<ul>
<li><a href="https://076923.github.io/posts/Python-opencv-8/">https://076923.github.io/posts/Python-opencv-8/</a></li>
<li><a href="https://docs.opencv.org/3.4/">https://docs.opencv.org/3.4/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[OpenCV] SURF 알고리즘]]></title>
            <link>https://velog.io/@checking_pks/SURF-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@checking_pks/SURF-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Sun, 16 Oct 2022 17:31:49 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡 논문 작성하며 공부했던 내용을 정리해 보았다!</p>
</blockquote>
<h1 id="surf-알고리즘">SURF 알고리즘</h1>
<h2 id="surf-알고리즘이란">SURF 알고리즘이란?</h2>
<p>Speeded-Up Robust Features 알고리즘
특징점을 통하여 동일한 장면이나 물체를 찾는 알고리즘입니다.</p>
<p>기존 SIFT 알고리즘의 이미지 사이즈 변경시키며 특징점을 찾는 방식에서 박스 필터의 사이즈를 변경시키며 찾음으로써 시간을 단축시켜 더 빠른 성능의 알고리즘입니다.</p>
<h2 id="surf-알고리즘의-방식">SURF 알고리즘의 방식</h2>
<h3 id="1-sift-vs-surf">1. SIFT vs SURF</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/7ecdd4bb-ed0b-4db1-bb63-c59e0e9813c0/image.bmp" alt=""></p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/af5fa6d0-da6c-4868-806b-39a8ebea0725/image.bmp" alt=""></p>
<p><strong>SURF</strong>에서는 Gaussian filter 형태의 단순화한 <strong>Box filter를 사용</strong>하여 <strong>필터의 스케일을 키우면서 극점을 찾는다.</strong> 그래서 <strong>이미지 크기를 직접 줄이며 찾는 SIFT</strong>보다 <strong>필터의 사이즈를 늘리며 찾는 SURF</strong>가 <strong>3배 더 빠른 속도</strong>가 나온다.</p>
<h3 id="2-hessian-matrix">2. Hessian Matrix</h3>
<p>$$
H(x,y,\sigma)={D_{xx}(x,y,\sigma)<del>D_{xy}(x,y,\sigma) \brack D_{xy}(x,y,\sigma)</del>D_{yy}(x,y,\sigma)}
$$</p>
<p>$$
det(H_{approx})=D_{xx}D_{yy}-(0.9D_{xy})^2
$$</p>
<p>가우시안 필터를 대체한 Box filter에서 Hessian Determinant 추출한다.</p>
<p>$$
w={{\vert L_{xy}(1.2) \vert <em>F~ \vert D</em>{yy}(9) \vert <em>F} \over {\vert L</em>{yy}(1.2) \vert <em>F~ \vert D</em>{xy}(9) \vert _F}}=0.912... \simeq 0.9
$$</p>
<p>(0.9를 곱하는 이유는 Box filter가 9x9, σ=1.2인 가우시안 2차 미분 함수에 대한 근사이기 때문이다.)</p>
<h3 id="3-특징점-추출">3. 특징점 추출</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/f0dd01f2-7cd5-43b4-a26d-60f219496836/image.bmp" alt=""></p>
<ol>
<li>X 지점의 Hessian Determinant가 Threshold 보다 큰지 판별</li>
<li>크다면 인접 8개의 픽셀보다 큰지 판별</li>
<li>상하 박스 필터 사이즈의 3x3 범위와 비교하여 가장 클 경우 특징점으로 검출</li>
</ol>
<h3 id="4-방향-할당-orientation-assignment">4. 방향 할당 (Orientation Assignment)</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/9057dfa2-503c-4c5a-ab36-d429aa8ad8c2/image.bmp" alt=""></p>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/018bef14-4c15-428d-8614-dd28c509daa8/image.bmp" alt=""></p>
<p>반지름 6 scale 원 안에서 <strong>x및 y 방향으로 Haar-wavelet 응답(responses)의 합을 계산</strong>한 다음, 가장 큰 합을 가진 방향을 찾을 때까지 스캔 방향을 변경하고(+π/3, 60°) 다시 계산한다.</p>
<p><strong>이 방향이 특징점의 주 방향 성분[fig.5 right]</strong></p>
<h3 id="5-기술자-구성-요소-descriptor-components">5. 기술자 구성 요소 (Descriptor Components)</h3>
<p><img src="https://velog.velcdn.com/images/checking_pks/post/3789fa38-415b-4229-bf9a-3dd38108b4db/image.bmp" alt=""></p>
<ol>
<li>특징점을 중심으로 이전 과정을 통해 얻은 <strong>방향을 따라 20 Scale 크기의 정사각형 영역을 구성</strong>한다.</li>
<li>해당 영역은 균등하게 4x4 하위 영역으로 분할, 각 하위 영역에 대해 일정한 간격의 5x5 샘플 포인트에서 dx, dy 계산, 각 하위 영역은 각각의 기본 강도 구조인 V = (∑dx, ∑dy, ∑|dx|, ∑|dy|) 4x4x4 = 64 길이의 Descriptor 벡터 생성한다.</li>
</ol>
<h2 id="surf-알고리즘의-특징">SURF 알고리즘의 특징</h2>
<ol>
<li>물체의 기울기, 크기, 방향, 밝기 등의 차이에 영향이 적다.<ul>
<li>특이점을 찾고 그 특이점의 크기와 방향을 비교하다 보니 위의 변화에 비교적 적은 영향을 받는다.</li>
</ul>
</li>
<li>이미지의 크기가 다르더라도 매칭이 가능하다.<ul>
<li>박스 필터를 사용하여 특이점을 찾고 그 특이점을 통하여 매칭을 시도하다 보니 이미지의 크기가 달라도 문제가 되지 않는다.</li>
</ul>
</li>
</ol>
<h1 id="참조">참조</h1>
<ul>
<li><em>Bay, H., Tuytelaars, T., Van Gool, L. (2006). SURF: Speeded Up Robust Features. In: Leonardis, A., Bischof, H., Pinz, A. (eds) Computer Vision – ECCV 2006. ECCV 2006. Lecture Notes in Computer Science, vol 3951. Springer, Berlin, Heidelberg. DOI: <a href="https://doi.org/10.1016/j.cviu.2007.09.014">https://doi.org/10.1007/11744023_3</a></em></li>
<li><em>Y. Do, Y. Jeong. “Hardware Design of SURF-based Feature extraction and description
for Object Tracking” Journal of The Institute of Electronics Engineers of Korea, vol. 50, 5. DOI: <a href="https://doi.org/10.5573/ieek.2013.50.5.083">https://doi.org/10.5573/ieek.2013.50.5.083</a></em></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study : 2022 Summer - 07/04]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0704</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0704</guid>
            <pubDate>Mon, 04 Jul 2022 13:45:13 GMT</pubDate>
            <description><![CDATA[<h1 id="1주차-0704---class-2">1주차 (07/04) - Class 2</h1>
<h2 id="2751---수-정렬하기-2">2751 - 수 정렬하기 2</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;list&gt;

using namespace std;

int main() {
    int times;
    list &lt;int&gt; numList;
    cin &gt;&gt; times;

    for (int i=0; i&lt;times; i++) {
        int num;
        cin &gt;&gt; num;

        numList.push_back(num);
    }

    numList.sort();

    for (int n:numList)
        cout &lt;&lt; n &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
<h2 id="2869---달팽이는-올라가고-싶다">2869 - 달팽이는 올라가고 싶다</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int up, down, height;
    double days;
    cin &gt;&gt; up &gt;&gt; down &gt;&gt; height;

    days = double (height - down) / (up - down);

    cout &lt;&lt; int(days) + ((int(days) != days) ? 1 : 0);

    return 0;
}</code></pre>
<h2 id="7568---덩치">7568 - 덩치</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

int main() {
    int times;
    cin &gt;&gt; times;

    vector &lt;pair&lt;int, int&gt;&gt; infoList;
    vector &lt;int&gt; rank(times, 1);

    for (int i=0; i&lt;times; i++) {
        int weight, height;
        cin &gt;&gt; weight &gt;&gt; height;

        infoList.push_back({weight, height});
    }

    for (int i=0; i&lt;times; i++) 
        for (int j=0; j&lt;times; j++) 
            if (infoList[i].first &lt; infoList[j].first &amp;&amp; infoList[i].second &lt; infoList[j].second)
                rank[i]++;

    for (int r:rank)
        cout &lt;&lt; r &lt;&lt; &quot; &quot;;


    return 0;
}</code></pre>
<h2 id="10814---나이순-정렬">10814 - 나이순 정렬</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;list&gt;

using namespace std;

bool cmp(pair&lt;pair&lt;int, string&gt;, int&gt; user1, pair&lt;pair&lt;int, string&gt;, int&gt; user2) {
    if (user1.first.first != user2.first.first)
        return user1.first.first &lt; user2.first.first;

    return user1.second &lt; user2.second;
}

int main() {
    list &lt;pair&lt;pair&lt;int, string&gt;, int&gt;&gt; userList;
    int times;
    cin &gt;&gt; times;

    for (int i=0; i&lt;times; i++) {
        int age;
        string name;
        cin &gt;&gt; age &gt;&gt; name;

        userList.push_back({{age, name}, i});
    }

    userList.sort(cmp);

    for (pair&lt;pair&lt;int, string&gt;, int&gt; u:userList)
        cout &lt;&lt; u.first.first &lt;&lt; &quot; &quot; &lt;&lt; u.first.second &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
<h2 id="11650---좌표-정렬하기">11650 - 좌표 정렬하기</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;list&gt;

using namespace std;

bool cmp(pair&lt;int, int&gt; pos1, pair&lt;int, int&gt; pos2) {
    if (pos1.first != pos2.first)
        return pos1.first &lt; pos2.first;

    return pos1.second &lt; pos2.second;
}

int main() {
    list &lt;pair&lt;int, int&gt;&gt; posList;
    int times;
    cin &gt;&gt; times;

    for (int i=0; i&lt;times; i++) {
        int x, y;
        cin &gt;&gt; x &gt;&gt; y;

        posList.push_back({x, y});
    }

    posList.sort(cmp);

    for (pair&lt;int, int&gt; p:posList)
        cout &lt;&lt; p.first &lt;&lt; &quot; &quot; &lt;&lt; p.second &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study : 2022 Summer - 07/03]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0703</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0703</guid>
            <pubDate>Sun, 03 Jul 2022 19:29:47 GMT</pubDate>
            <description><![CDATA[<h1 id="1주차-0703---class-2">1주차 (07/03) - Class 2</h1>
<h2 id="10989---수-정렬하기-3">10989 - 수 정렬하기 3</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

int main() {
    cin.tie(NULL);
    ios_base::sync_with_stdio(false);

    int testCase;
    vector &lt;int&gt; numList(10001, 0);

    cin &gt;&gt; testCase;

    for (int i=0; i&lt;testCase; i++) {
        int num;
        cin &gt;&gt; num;

        numList[num]++;
    }

    for (int i=1; i&lt;=10000; i++)
        for (int j=0; j&lt;numList[i]; j++) 
            cout &lt;&lt; i &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
<h2 id="11050---이항-계수-1">11050 - 이항 계수 1</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

int main() {
    int n, r, result = 1;
    cin &gt;&gt; n &gt;&gt; r;

    for (int i = n; i &gt; 1; i--) {
        result *= i;

        if (i &lt;= r)
            result /= i;

        if (i &lt;= n - r)
            result /= i;
    }

    cout &lt;&lt; result;

    return 0;
}</code></pre>
<h2 id="1181---단어-정렬">1181 - 단어 정렬</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;list&gt;

using namespace std;

bool cmp(string first, string second) {
    if (first.length() != second.length())
        return first.length() &lt; second.length();

    return first &lt; second;
}

int main() {
    list &lt;string&gt; strList;
    int num;

    cin &gt;&gt; num;

    for (int i=0; i&lt;num; i++) {
        string str;
        cin &gt;&gt; str;

        strList.push_back(str);
    }

    strList.sort(cmp);
    strList.unique();

    for (string s:strList)
        cout &lt;&lt; s &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
<h2 id="1436---영화감독-숌">1436 - 영화감독 숌</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

int main() {
    int num, result = 665;
    cin &gt;&gt; num;

    while (num) {
        result++;

        if (to_string(result).find(&quot;666&quot;) != string::npos)
            num--;
    }

    cout &lt;&lt; result;

    return 0;
}</code></pre>
<h2 id="1978---소수-찾기">1978 - 소수 찾기</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;

using namespace std;

bool isPrime(int num) {
    if (num &lt;= 1)
        return false;

    for (int i=2; i&lt;=sqrt(num); i++)
        if (num % i == 0)
            return false;

    return true;
}

int main() {
    int times, result = 0;
    cin &gt;&gt; times;

    for (int i=0; i&lt;times; i++) {
        int num;
        cin &gt;&gt; num;

        if (isPrime(num))
            result++;
    }

    cout &lt;&lt; result;

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study : 2022 Summer - 07/01]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0701</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0701</guid>
            <pubDate>Fri, 01 Jul 2022 10:41:51 GMT</pubDate>
            <description><![CDATA[<h1 id="1주차-0701---class-2">1주차 (07/01) - Class 2</h1>
<h2 id="2798---블랙잭">2798 - 블랙잭</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

int main() {
    int cardNum, limitScore, maxScore = 0;
    vector&lt;int&gt; cardList;

    cin &gt;&gt; cardNum &gt;&gt; limitScore;

    for (int i=0; i&lt;cardNum; i++) {
        int card;
        cin &gt;&gt; card;

        cardList.push_back(card);
    }

    for (int i=0; i&lt;cardNum-2; i++) {
        for (int j=i+1; j&lt;cardNum-1; j++) {
            for (int k=j+1; k&lt;cardNum; k++) {
                int cardSum = cardList[i] + cardList[j] + cardList[k];

                if (cardSum &lt;= limitScore &amp;&amp; cardSum &gt; maxScore) 
                    maxScore = cardSum;
            }
        }
    }

    cout &lt;&lt; maxScore &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
<h2 id="15829---hashing">15829 - Hashing</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

int main() {
    int strLength;
    string inputStr;
    long long result = 0;
    long long primeNum = 1;

    cin &gt;&gt; strLength &gt;&gt; inputStr;

    for (int i = 0; i &lt; strLength; i++) {
        int alphabetNum = inputStr[i] - &#39;a&#39; + 1;

        result += alphabetNum * primeNum;
        result %= 1234567891;

        primeNum *= 31;
        primeNum %= 1234567891;
    }

    cout &lt;&lt; result &lt;&lt; &quot;\n&quot;;

    return 0;
}</code></pre>
<h2 id="1259---팰린드롬수">1259 - 팰린드롬수</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

int main() {
    while (true) {
        int num;
        string numToStr;
        bool isPalindrome = true;

        cin &gt;&gt; num;

        if (num == 0)
            break;

        numToStr = to_string(num);

        for (int i=0; i&lt;(numToStr.length() &gt;&gt; 1); i++) {
            int idxFront = i;
            int idxBack  = numToStr.length() - i - 1;

            if (numToStr[idxFront] != numToStr[idxBack]) {
                isPalindrome = false;
                break;
            }
        }

        cout &lt;&lt; ((isPalindrome) ? &quot;yes&quot; : &quot;no&quot;) &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}</code></pre>
<h2 id="2609---최대공약수와-최소공배수">2609 - 최대공약수와 최소공배수</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;numeric&gt;

using namespace std;

int main() {
    int num1, num2;

    cin &gt;&gt; num1 &gt;&gt; num2;

    cout &lt;&lt; gcd(num1, num2) &lt;&lt; &quot;\n&quot; &lt;&lt; lcm(num1, num2);

    return 0;
}</code></pre>
<hr>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int num1, num2;
    int gcd, lcm;

    cin &gt;&gt; num1 &gt;&gt; num2;

    if (num1 &lt; num2) 
        swap(num1, num2);

    for (int i = num1; i &gt;= 1; i--) {
        if (num1 % i == 0 &amp;&amp; num2 % i == 0) {
            gcd = i;
            break;
        }
    }

    lcm = num1 * num2 / gcd;

    cout &lt;&lt; gcd &lt;&lt; &quot;\n&quot; &lt;&lt; lcm;

    return 0;
}</code></pre>
<h2 id="2775---부녀회장이-될테야">2775 - 부녀회장이 될테야</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int testCase;

    cin &gt;&gt; testCase;

    for (int i=0; i&lt;testCase; i++) {
        int floor, roomNumber;
        long long result = 1;

        cin &gt;&gt; floor &gt;&gt; roomNumber;

        for (int i = floor + roomNumber; i &gt;= 2; i--) {
            result *= i;

            if (i &lt;= roomNumber - 1)
                result /= i;

            if (i &lt;= floor + 1)
                result /= i;
        }

        cout &lt;&lt; result &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study : 2022 Summer - 06/28]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0628</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-2022-Summer-0628</guid>
            <pubDate>Tue, 28 Jun 2022 13:53:29 GMT</pubDate>
            <description><![CDATA[<h1 id="1주차-0628---class-2">1주차 (06/28) - Class 2</h1>
<h2 id="1085---직사각형에서-탈출">1085 - 직사각형에서 탈출</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int x, y, w, h, result = 1000;
    cin &gt;&gt; x &gt;&gt; y &gt;&gt; w &gt;&gt; h;

      if (result &gt; x) result = x;
    if (result &gt; y) result = y;
    if (result &gt; w-x) result = w-x;
    if (result &gt; h-y) result = h-y;

    cout &lt;&lt; result;

    return 0;
}</code></pre>
<h2 id="4153---직각삼각형">4153 - 직각삼각형</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    while (true) {
        int side1, side2, hypotenuse;
        cin &gt;&gt; side1 &gt;&gt; side2 &gt;&gt; hypotenuse;

        if (side1 + side2 + hypotenuse == 0)
            break;

        if (hypotenuse &lt; side1) {
            int num = side1;
            side1 = hypotenuse;
            hypotenuse = num;
        }

        if (hypotenuse &lt; side2) {
            int num = side2;
            side2 = hypotenuse;
            hypotenuse = num;
        }

        cout &lt;&lt; ((side1 * side1 + side2 * side2 == hypotenuse * hypotenuse) ? &quot;right\n&quot; : &quot;wrong\n&quot;);
    }

    return 0;
}</code></pre>
<h2 id="10250---acm-호텔">10250 - ACM 호텔</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

int main() {
    int times;
    cin &gt;&gt; times;

    for (int i=0; i&lt;times; i++) {
        int h, w, n;
        cin &gt;&gt; h &gt;&gt; w &gt;&gt; n;

        string floor, room;

        room = to_string((n - 1) / h + 1);
        floor = to_string((n % h == 0) ? h : n % h) + ((room.length() != 2) ? &quot;0&quot; : &quot;&quot;);

        cout &lt;&lt; floor &lt;&lt; room &lt;&lt; &quot;\n&quot;;
    }

    return 0;
}</code></pre>
<h2 id="2231---분해합">2231 - 분해합</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int num, result = 0;
    cin &gt;&gt; num;

    for (int i=0; i&lt;num; i++) {
        int nowValue = i;

        for (int j=i; j&gt;0; j/=10) 
            nowValue += j % 10;

        if (nowValue == num) {
            result = i;
            break;
        }
    }

    cout &lt;&lt; result;

    return 0;
}</code></pre>
<h2 id="2292---벌집">2292 - 벌집</h2>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int num;
    cin &gt;&gt; num;

    for (int i=1, maxRoom=1; maxRoom &lt;= num; i++) 
        maxRoom += 6 * i;

    return 0;
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 16주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-16%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-16%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 02 Aug 2021 15:56:46 GMT</pubDate>
            <description><![CDATA[<h1 id="깊이너비-우선-탐색dfsbfs">깊이/너비 우선 탐색(DFS/BFS)</h1>
<h2 id="여행경로">여행경로</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;unordered_map&gt;
#include &lt;unordered_set&gt;

using namespace std;

vector&lt;string&gt; BFS(unordered_map&lt;string, unordered_multiset&lt;string&gt;&gt; ticket_field, string prev_airport, string now_airport) {
    if (prev_airport.size()) {
        ticket_field[prev_airport].erase(ticket_field[prev_airport].find(now_airport));
    }

    vector&lt;string&gt; optimal_route;

    for (string next_airport:ticket_field[now_airport]) {
        vector&lt;string&gt; route = BFS(ticket_field, now_airport, next_airport);

        if (optimal_route.size() &lt; route.size()) optimal_route = route;
        else if (optimal_route.size() == route.size()) {

            for (int i=0; i&lt;optimal_route.size(); i++) {
                if (optimal_route[i] != route[i]) {
                    if (optimal_route[i] &gt; route[i]) optimal_route = route;

                    break;
                }
            }
        }
    }

    optimal_route.insert(optimal_route.begin(), now_airport);

    return optimal_route;
}

vector&lt;string&gt; solution(vector&lt;vector&lt;string&gt;&gt; tickets) {
    unordered_map&lt;string, unordered_multiset&lt;string&gt;&gt; ticket_field;

    for (int i=0; i&lt;tickets.size(); i++) {
        ticket_field[tickets[i][0]].insert(tickets[i][1]);
    }

    return BFS(ticket_field, &quot;&quot;, &quot;ICN&quot;);
}</code></pre>
<blockquote>
<pre><code>정확성  테스트
  테스트 1 〉    통과 (297.06ms, 3.95MB)
  테스트 2 〉    통과 (0.02ms, 3.93MB)
  테스트 3 〉    통과 (0.02ms, 3.96MB)
  테스트 4 〉    통과 (0.02ms, 3.97MB)
</code></pre></blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h1 id="이분탐색">이분탐색</h1>
<h2 id="입국심사">입국심사</h2>
<h3 id="1차-시도-1">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

long long solution(int n, vector&lt;int&gt; times) {
    sort(times.begin(), times.end());

    long long left = 1, right = (long long)n * (long long)times.back(), mid = (left + right)&gt;&gt;1;

    while (left &lt; right) {
        long long check_people = 0;
        bool isMultiple = false;

        for (int t:times) {
            check_people += mid / t;

            if (mid % t == 0) isMultiple = true;

            if (check_people &gt; n) break;
        }

        if (check_people &gt; n) {
            right = mid;
        } else if (check_people &lt; n) {
            left = mid + 1;
        } else if (!isMultiple) {
            left--;
            right--;
        } else break;

        mid = (left + right)&gt;&gt;1;
    }

    return mid;
}</code></pre>
<blockquote>
<pre><code>정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.97MB)
  테스트 2 〉    통과 (0.02ms, 3.89MB)
  테스트 3 〉    통과 (343.67ms, 3.94MB)
  테스트 4 〉    통과 (338.15ms, 6.8MB)
  테스트 5 〉    통과 (200.64ms, 6.88MB)
  테스트 6 〉    통과 (30.10ms, 6.54MB)
  테스트 7 〉    통과 (518.44ms, 6.74MB)
  테스트 8 〉    통과 (2854.43ms, 6.86MB)
  테스트 9 〉    통과 (0.01ms, 3.95MB)
</code></pre></blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<p>```</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 15주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-15%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-15%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Thu, 29 Jul 2021 05:53:01 GMT</pubDate>
            <description><![CDATA[<h1 id="깊이너비-우선-탐색dfsbfs">깊이/너비 우선 탐색(DFS/BFS)</h1>
<h2 id="네트워크">네트워크</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(int n, vector&lt;vector&lt;int&gt;&gt; computers) {
    vector &lt;int&gt; networks;
    for (int i=0; i&lt;n; i++) networks.push_back(i);

    for (int i=0; i&lt;computers.size(); i++) {
        for (int j=i+1; j&lt;computers.size(); j++) {
            if (computers[i][j]) {
                int base_network = networks[i];
                int replace_network = networks[j];

                for (int k=0; k&lt;networks.size(); k++) {
                    if (networks[k] == replace_network) networks[k] = base_network;
                }
            }
        }
    }

    sort(networks.begin(), networks.end());
    auto iter = unique(networks.begin(), networks.end());
    networks.erase(iter, networks.end());

    return networks.size();
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.95MB)
  테스트 2 〉    통과 (0.01ms, 3.94MB)
  테스트 3 〉    통과 (0.01ms, 3.96MB)
  테스트 4 〉    통과 (0.02ms, 3.89MB)
  테스트 5 〉    통과 (0.01ms, 3.93MB)
  테스트 6 〉    통과 (0.04ms, 3.89MB)
  테스트 7 〉    통과 (0.01ms, 3.93MB)
  테스트 8 〉    통과 (0.02ms, 3.93MB)
  테스트 9 〉    통과 (0.02ms, 3.89MB)
  테스트 10 〉    통과 (0.02ms, 3.93MB)
  테스트 11 〉    통과 (0.06ms, 4.01MB)
  테스트 12 〉    통과 (0.05ms, 3.88MB)
  테스트 13 〉    통과 (0.03ms, 3.94MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h2 id="단어-변환">단어 변환</h2>
<h3 id="1차-시도-1">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;unordered_set&gt;

using namespace std;

int DFS(string begin, string target, vector&lt;string&gt; words, unordered_set&lt;string&gt; checked, int dipth) {
    if (words.size() &lt; dipth) return 0;

    checked.insert(begin);

    for (int i=0; i&lt;words.size(); i++) {
        if (checked.find(words[i]) != checked.end()) continue;

        int canReplace = 0;

        for (int j=0; j&lt;begin.length(); j++) {
            if (begin[j] != words[i][j]) canReplace++;

            if (canReplace &gt; 1) break;
        }

        if (canReplace == 1) {
            if (words[i] == target) return dipth;

            int s = DFS(words[i], target, words, checked, dipth + 1);
            if (s != 0) return s;
        }
    }

    return 0;
}

int solution(string begin, string target, vector&lt;string&gt; words) {
    return DFS(begin, target, words, {}, 1);
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.94MB)
  테스트 2 〉    통과 (0.01ms, 3.96MB)
  테스트 3 〉    통과 (0.03ms, 3.95MB)
  테스트 4 〉    통과 (0.01ms, 3.95MB)
  테스트 5 〉    통과 (0.01ms, 3.72MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<blockquote>
<pre><code class="language-markdown">테스트 1
  입력값 〉    &quot;hit&quot;, &quot;cog&quot;, [&quot;hot&quot;, &quot;dot&quot;, &quot;dog&quot;, &quot;lot&quot;, &quot;log&quot;, &quot;cog&quot;]
  기댓값 〉    4
  실행 결과 〉    실행한 결괏값 5이(가) 기댓값 4와(과) 다릅니다.
테스트 2
  입력값 〉    &quot;hit&quot;, &quot;cog&quot;, [&quot;hot&quot;, &quot;dot&quot;, &quot;dog&quot;, &quot;lot&quot;, &quot;log&quot;]
  기댓값 〉    0
  실행 결과 〉    테스트를 통과하였습니다.
테스트 3
  입력값 〉    &quot;hit&quot;, &quot;cog&quot;, [&quot;cog&quot;, &quot;log&quot;, &quot;lot&quot;, &quot;dog&quot;, &quot;hot&quot;]
  기댓값 〉    4
  실행 결과 〉    테스트를 통과하였습니다.
테스트 4
  입력값 〉    &quot;1234567000&quot;, &quot;1234567899&quot;, [&quot;1234567800&quot;, &quot;1234567890&quot;, &quot;1234567899&quot;]
  기댓값 〉    3
  실행 결과 〉    테스트를 통과하였습니다.
테스트 5
  입력값 〉    &quot;hit&quot;, &quot;hot&quot;, [&quot;hot&quot;, &quot;dot&quot;, &quot;dog&quot;, &quot;lot&quot;, &quot;log&quot;]
  기댓값 〉    1
  실행 결과 〉    테스트를 통과하였습니다.
테스트 6
  입력값 〉    &quot;hot&quot;, &quot;dog&quot;, [&quot;hot&quot;, &quot;dog&quot;]
  기댓값 〉    0
  실행 결과 〉    테스트를 통과하였습니다.
</code></pre>
</blockquote>
<p>테스트 결과 (<del>˘▾˘)</del>
  6개 중 5개 성공</p>
<blockquote>
</blockquote>
<h3 id="2차-시도">2차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;unordered_set&gt;

using namespace std;

int BFS(string begin, string target, vector&lt;string&gt; words, unordered_set&lt;string&gt; checked, int dipth) {
    if (words.size() &lt; dipth) return 0;

    int min = words.size()+1;

    checked.insert(begin);

    for (int i=0; i&lt;words.size(); i++) {
        if (checked.find(words[i]) != checked.end()) continue;

        int canReplace = 0;

        for (int j=0; j&lt;begin.length(); j++) {
            if (begin[j] != words[i][j]) canReplace++;

            if (canReplace &gt; 1) break;
        }

        if (canReplace == 1) {
            if (words[i] == target) return dipth;

            int value = BFS(words[i], target, words, checked, dipth + 1);

            if (value != 0 &amp;&amp; min &gt; value) min = value;
        }
    }

    return (min != words.size()+1) ? min : 0;
}

int solution(string begin, string target, vector&lt;string&gt; words) {
    return BFS(begin, target, words, {}, 1);
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.76MB)
  테스트 2 〉    통과 (0.02ms, 3.96MB)
  테스트 3 〉    통과 (0.04ms, 3.72MB)
  테스트 4 〉    통과 (0.01ms, 3.95MB)
  테스트 5 〉    통과 (0.01ms, 3.95MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<p>```</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 14주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-14%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-14%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 19 Jul 2021 02:41:51 GMT</pubDate>
            <description><![CDATA[<h1 id="동적계획법dynamic-programming">동적계획법(Dynamic Programming)</h1>
<h2 id="도둑질">도둑질</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(vector&lt;int&gt; money) {
    vector&lt;int&gt; money_reverse(money.rbegin(), money.rend());
    int forward = 0, reverse = 0;

    for (int i=0; i&lt;money.size()-1; i += 2) {
        int now_choice = money[i] - (money[(i-1+money.size())%money.size()] + money[(i+1)%money.size()]);
        int next_choice = money[i+1] - (money[i] + money[(i+2)%money.size()]);

        if (now_choice &gt; next_choice) {
            if (i==0) money.back() = 0;
            forward += money[i];
        } else {
            if (i==0) money.push_back(0);
            forward += money[i+1];
            i++;
        }
    } 

    for (int i=0; i&lt;money_reverse.size()-1; i += 2) {
        int now_choice = money_reverse[i] - (money_reverse[(i-1+money_reverse.size())%money_reverse.size()] + money_reverse[(i+1)%money_reverse.size()]);
        int next_choice = money_reverse[i+1] - (money_reverse[i] + money_reverse[(i+2)%money_reverse.size()]);

        if (now_choice &gt; next_choice) {
            if (i==0) money_reverse.back() = 0;
            reverse += money_reverse[i];
        } else {
            if (i==0) money_reverse.push_back(0);
            reverse += money_reverse[i+1];
            i++;
        }
    } 

    return (forward &gt; reverse) ? forward : reverse;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    실패 (0.02ms, 3.94MB)
  테스트 2 〉    실패 (0.04ms, 3.75MB)
  테스트 3 〉    실패 (0.02ms, 3.95MB)
  테스트 4 〉    실패 (0.01ms, 3.95MB)
  테스트 5 〉    실패 (0.01ms, 3.96MB)
  테스트 6 〉    실패 (0.03ms, 3.95MB)
  테스트 7 〉    실패 (0.02ms, 3.96MB)
  테스트 8 〉    실패 (0.01ms, 3.93MB)
  테스트 9 〉    실패 (0.06ms, 3.94MB)
  테스트 10 〉    실패 (0.01ms, 3.93MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    실패 (25.73ms, 40.6MB)
  테스트 2 〉    실패 (24.14ms, 38.2MB)
  테스트 3 〉    실패 (26.67ms, 39.6MB)
  테스트 4 〉    실패 (38.17ms, 40MB)
  테스트 5 〉    실패 (22.08ms, 33.6MB)
  테스트 6 〉    실패 (25.48ms, 38.5MB)
  테스트 7 〉    실패 (13.05ms, 22MB)
  테스트 8 〉    실패 (15.51ms, 24.5MB)
  테스트 9 〉    실패 (16.73ms, 28.2MB)
  테스트 10 〉    실패 (26.07ms, 38.8MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 0.0
  효율성: 0.0
  합계: 0.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<blockquote>
<pre><code class="language-markdown">테스트 1
  입력값 〉    [1, 2, 3, 1]
  기댓값 〉    4
  실행 결과 〉    테스트를 통과하였습니다.
테스트 2
  입력값 〉    [90, 0, 0, 95, 1, 1]
  기댓값 〉    185
  실행 결과 〉    테스트를 통과하였습니다.
테스트 3
  입력값 〉    [91, 90, 5, 7, 5, 7]
  기댓값 〉    104
  실행 결과 〉    테스트를 통과하였습니다.
테스트 4
  입력값 〉    [90, 0, 0, 95, 1, 1]
  기댓값 〉    185
  실행 결과 〉    테스트를 통과하였습니다.
테스트 5
  입력값 〉    [91, 90, 5, 7, 5, 7]
  기댓값 〉    104
  실행 결과 〉    테스트를 통과하였습니다.
테스트 6
  입력값 〉    [1, 2, 3]
  기댓값 〉    3
  실행 결과 〉    테스트를 통과하였습니다.
테스트 7
  입력값 〉    [11, 0, 2, 5, 100, 100, 85, 1]
  기댓값 〉    198
  실행 결과 〉    테스트를 통과하였습니다.
테스트 8
  입력값 〉    [0, 0, 0, 0, 100, 0, 0, 100, 0, 0, 1, 1]
  기댓값 〉    201
  실행 결과 〉    테스트를 통과하였습니다.
테스트 9
  입력값 〉    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  기댓값 〉    30
  실행 결과 〉    테스트를 통과하였습니다.
테스트 10
  입력값 〉    [1000, 0, 0, 0, 0, 1000, 0, 0, 0, 0, 0, 1000]
  기댓값 〉    2000
  실행 결과 〉    테스트를 통과하였습니다.
테스트 11
  입력값 〉    [1000, 1, 0, 1, 2, 1000, 0]
  기댓값 〉    2001
  실행 결과 〉    테스트를 통과하였습니다.
테스트 12
  입력값 〉    [1000, 0, 0, 1000, 0, 0, 1000, 0, 0, 1000]
  기댓값 〉    3000
  실행 결과 〉    테스트를 통과하였습니다.
테스트 13
  입력값 〉    [1, 1, 4, 1, 4]
  기댓값 〉    8
  실행 결과 〉    테스트를 통과하였습니다.
</code></pre>
</blockquote>
<p>테스트 결과 (<del>˘▾˘)</del>
  13개 중 13개 성공</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="2차-시도">2차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(vector&lt;int&gt; money) {
    vector &lt;int&gt; stolen_first_house = {money[0], money[0]};
    vector &lt;int&gt; stolen_second_house = {0, money[1]};

    for (int i=2; i&lt;money.size()-1; i++) {
        if (stolen_first_house[i-2] + money[i] &gt; stolen_first_house[i-1]) {
            stolen_first_house.push_back(stolen_first_house[i-2] + money[i]);
        } else {
            stolen_first_house.push_back(stolen_first_house[i-1]);
        }
    }

    for (int i=2; i&lt;money.size(); i++) {
        if (stolen_second_house[i-2] + money[i] &gt; stolen_second_house[i-1]) {
            stolen_second_house.push_back(stolen_second_house[i-2] + money[i]);
        } else {
            stolen_second_house.push_back(stolen_second_house[i-1]);
        }
    }

    return (stolen_first_house[money.size()-2] &gt; stolen_second_house[money.size()-1]) ? stolen_first_house[money.size()-2] : stolen_second_house[money.size()-1];
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.02ms, 3.95MB)
  테스트 2 〉    통과 (0.02ms, 3.89MB)
  테스트 3 〉    통과 (0.02ms, 3.96MB)
  테스트 4 〉    통과 (0.01ms, 3.95MB)
  테스트 5 〉    통과 (0.01ms, 3.96MB)
  테스트 6 〉    통과 (0.02ms, 3.96MB)
  테스트 7 〉    통과 (0.02ms, 3.89MB)
  테스트 8 〉    통과 (0.02ms, 3.96MB)
  테스트 9 〉    통과 (0.03ms, 3.9MB)
  테스트 10 〉    통과 (0.01ms, 3.95MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    통과 (16.82ms, 43MB)
  테스트 2 〉    통과 (15.77ms, 40.7MB)
  테스트 3 〉    통과 (16.89ms, 42.2MB)
  테스트 4 〉    통과 (17.35ms, 42.6MB)
  테스트 5 〉    통과 (14.33ms, 36.9MB)
  테스트 6 〉    통과 (15.50ms, 41.2MB)
  테스트 7 〉    통과 (9.06ms, 24.9MB)
  테스트 8 〉    통과 (9.04ms, 25.6MB)
  테스트 9 〉    통과 (12.94ms, 31.8MB)
  테스트 10 〉    통과 (16.32ms, 41.6MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 50.0
  효율성: 50.0
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h1 id="깊이너비-우선-탐색dfsbfs">깊이/너비 우선 탐색(DFS/BFS)</h1>
<h2 id="타겟-넘버">타겟 넘버</h2>
<h3 id="1차-시도-1">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int DFS(vector&lt;int&gt; numbers, int target, int now_number, int depth) {
    if (depth == numbers.size()) {
        return (now_number == target) ? true : false;
    }

    int plus = DFS(numbers, target, now_number + numbers[depth], depth + 1);
    int minus = DFS(numbers, target, now_number - numbers[depth], depth + 1);

    return plus + minus;
}

int solution(vector&lt;int&gt; numbers, int target) {
    return DFS(numbers, target, 0, 0);
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (65.63ms, 3.82MB)
  테스트 2 〉    통과 (69.89ms, 3.97MB)
  테스트 3 〉    통과 (0.08ms, 3.93MB)
  테스트 4 〉    통과 (0.31ms, 3.96MB)
  테스트 5 〉    통과 (2.23ms, 3.96MB)
  테스트 6 〉    통과 (0.16ms, 3.94MB)
  테스트 7 〉    통과 (0.08ms, 3.94MB)
  테스트 8 〉    통과 (0.64ms, 3.95MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<p>```</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 13주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-13%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-13%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 12 Jul 2021 18:57:43 GMT</pubDate>
            <description><![CDATA[<h1 id="동적계획법dynamic-programming">동적계획법(Dynamic Programming)</h1>
<h2 id="정수-삼각형">정수 삼각형</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(vector&lt;vector&lt;int&gt;&gt; triangle) {
    int answer = 0;

    for (int i=1; i&lt;triangle.size(); i++) {
        triangle[i][0] += triangle[i-1][0];

        for (int j=1; j&lt;triangle[i].size()-1; j++) {
            triangle[i][j] += (triangle[i-1][j-1] &gt; triangle[i-1][j]) ? triangle[i-1][j-1] : triangle[i-1][j];
        }

        triangle[i][triangle[i].size()-1] += triangle[i-1][triangle[i-1].size()-1];
    }

    for (int n:triangle[triangle.size()-1]) {
        if (answer &lt; n) answer = n;
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.97MB)
  테스트 2 〉    통과 (0.01ms, 3.97MB)
  테스트 3 〉    통과 (0.01ms, 3.97MB)
  테스트 4 〉    통과 (0.01ms, 3.95MB)
  테스트 5 〉    통과 (0.02ms, 3.97MB)
  테스트 6 〉    통과 (0.01ms, 3.92MB)
  테스트 7 〉    통과 (0.03ms, 3.96MB)
  테스트 8 〉    통과 (0.02ms, 3.96MB)
  테스트 9 〉    통과 (0.01ms, 3.91MB)
  테스트 10 〉    통과 (0.01ms, 3.94MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    통과 (0.28ms, 7.6MB)
  테스트 2 〉    통과 (0.23ms, 6.55MB)
  테스트 3 〉    통과 (0.31ms, 8.09MB)
  테스트 4 〉    통과 (0.31ms, 7.82MB)
  테스트 5 〉    통과 (0.28ms, 7.29MB)
  테스트 6 〉    통과 (0.30ms, 8.39MB)
  테스트 7 〉    통과 (0.33ms, 8.08MB)
  테스트 8 〉    통과 (0.24ms, 7.13MB)
  테스트 9 〉    통과 (0.28ms, 7.26MB)
  테스트 10 〉    통과 (0.32ms, 7.84MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 64.3
  효율성: 35.7
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h2 id="등굣길">등굣길</h2>
<h3 id="1차-시도-1">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(int m, int n, vector&lt;vector&lt;int&gt;&gt; puddles) {
    vector&lt;vector&lt;int&gt;&gt; field(m, vector&lt;int&gt; (n, 1));

    for (auto p:puddles) field[p[0]-1][p[1]-1] = 0;

    for (int i=1; i&lt;m; i++) {
        for (int j=1; j&lt;n; j++) {
            if (field[i][j] == 0) continue;
            field[i][j] = field[i-1][j] + field[i][j-1];
        }
    }

    return field[m-1][n-1];
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    실패 (0.01ms, 3.96MB)
  테스트 2 〉    통과 (0.01ms, 3.96MB)
  테스트 3 〉    통과 (0.01ms, 3.98MB)
  테스트 4 〉    통과 (0.01ms, 3.96MB)
  테스트 5 〉    통과 (0.01ms, 3.9MB)
  테스트 6 〉    통과 (0.01ms, 3.97MB)
  테스트 7 〉    통과 (0.01ms, 3.92MB)
  테스트 8 〉    통과 (0.01ms, 3.89MB)
  테스트 9 〉    실패 (0.01ms, 3.98MB)
  테스트 10 〉    실패 (0.01ms, 3.8MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    실패 (0.04ms, 3.96MB)
  테스트 2 〉    실패 (0.02ms, 3.95MB)
  테스트 3 〉    실패 (0.02ms, 3.92MB)
  테스트 4 〉    실패 (0.03ms, 3.96MB)
  테스트 5 〉    실패 (0.03ms, 3.98MB)
  테스트 6 〉    실패 (0.04ms, 3.96MB)
  테스트 7 〉    실패 (0.02ms, 3.92MB)
  테스트 8 〉    실패 (0.03ms, 3.97MB)
  테스트 9 〉    실패 (0.04ms, 3.96MB)
  테스트 10 〉    실패 (0.03ms, 3.96MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 35.0
  효율성: 0.0
  합계: 35.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="2차-시도">2차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(int m, int n, vector&lt;vector&lt;int&gt;&gt; puddles) {
    vector&lt;vector&lt;long long&gt;&gt; field(m, vector&lt;long long&gt; (n, 1));

    for (auto p:puddles) {
        field[p[0]-1][p[1]-1] = 0;

        if (p[0]-1 == 0) for (int i=p[1]; i&lt;n; i++) field[p[0]-1][i] = 0;
        if (p[1]-1 == 0) for (int i=p[0]; i&lt;m; i++) field[i][p[1]-1] = 0;
    }

    for (int i=1; i&lt;m; i++) {
        for (int j=1; j&lt;n; j++) {
            if (field[i][j] == 0) continue;
            field[i][j] = (field[i-1][j] + field[i][j-1]) % 1000000007;
        }
    }

    return field[m-1][n-1];
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.93MB)
  테스트 2 〉    통과 (0.01ms, 3.92MB)
  테스트 3 〉    통과 (0.01ms, 3.96MB)
  테스트 4 〉    통과 (0.01ms, 3.95MB)
  테스트 5 〉    통과 (0.01ms, 3.95MB)
  테스트 6 〉    통과 (0.01ms, 3.92MB)
  테스트 7 〉    통과 (0.01ms, 3.96MB)
  테스트 8 〉    통과 (0.01ms, 3.89MB)
  테스트 9 〉    통과 (0.01ms, 3.96MB)
  테스트 10 〉    통과 (0.01ms, 3.9MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    통과 (0.08ms, 3.96MB)
  테스트 2 〉    통과 (0.03ms, 3.79MB)
  테스트 3 〉    통과 (0.04ms, 3.72MB)
  테스트 4 〉    통과 (0.05ms, 3.96MB)
  테스트 5 〉    통과 (0.05ms, 3.73MB)
  테스트 6 〉    통과 (0.08ms, 3.96MB)
  테스트 7 〉    통과 (0.04ms, 3.91MB)
  테스트 8 〉    통과 (0.06ms, 3.94MB)
  테스트 9 〉    통과 (0.06ms, 3.97MB)
  테스트 10 〉    통과 (0.06ms, 3.97MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 50.0
  효율성: 50.0
  합계: 100.0 / 100.0</p>
<blockquote>
<p>```</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 12주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-12%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-12%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 12 Jul 2021 08:43:36 GMT</pubDate>
            <description><![CDATA[<h1 id="탐욕법greedy">탐욕법(Greedy)</h1>
<h2 id="단속카메라">단속카메라</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(vector&lt;vector&lt;int&gt;&gt; routes) {

    sort(routes.begin(), routes.end());

    vector&lt;vector&lt;int&gt;&gt; camera = {routes.front()};

    for (int i=1; i &lt; routes.size(); i++) {

        if (camera.back()[1] &lt; routes[i][0]) {
            camera.push_back(routes[i]);
            continue;
        }

        if (camera.back()[0] &lt; routes[i][0]) camera.back()[0] = routes[i][0];
        if (camera.back()[1] &gt; routes[i][1]) camera.back()[1] = routes[i][1];
    }

    return camera.size();
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.02ms, 3.94MB)
  테스트 2 〉    통과 (0.01ms, 3.99MB)
  테스트 3 〉    통과 (0.02ms, 3.77MB)
  테스트 4 〉    통과 (0.02ms, 3.95MB)
  테스트 5 〉    통과 (0.02ms, 3.9MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    통과 (0.26ms, 3.95MB)
  테스트 2 〉    통과 (0.14ms, 3.99MB)
  테스트 3 〉    통과 (0.60ms, 3.97MB)
  테스트 4 〉    통과 (0.03ms, 3.97MB)
  테스트 5 〉    통과 (0.63ms, 3.95MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 50.0
  효율성: 50.0
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h1 id="동적계획법dynamic-programming">동적계획법(Dynamic Programming)</h1>
<h2 id="n으로-표현">N으로 표현</h2>
<h3 id="1차-시도-1">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int recursive(int N, int now_number, int number, int times) {
    if (times &gt; 8 || now_number &lt;= 0) return 9;
    if (now_number == number) return times;

    string N_type = to_string(N);

    int now_times = 9;

    for (int i=0; i&lt;to_string(number).size(); i++) {
        int Plus = recursive(N, now_number + stoi(N_type), number, times + N_type.size());
        int Minus = recursive(N, now_number - stoi(N_type), number, times + N_type.size());
        int Multiplication = recursive(N, now_number * stoi(N_type), number, times + N_type.size());

        int Divide = 9;
        if (now_number % stoi(N_type) == 0) {
            Divide = recursive(N, now_number / stoi(N_type), number, times + N_type.size());
        }

        if (now_times &gt; Plus) now_times = Plus;
        if (now_times &gt; Minus) now_times = Minus;
        if (now_times &gt; Multiplication) now_times = Multiplication;
        if (now_times &gt; Divide) now_times = Divide;

        N_type += to_string(N);
    }

    return now_times;
}

int solution(int N, int number) {
    int answer = 9;
    string N_type = to_string(N);

    for (int i=0; i&lt;to_string(number).size(); i++) {
        int optimal = recursive(N, stoi(N_type), number, N_type.size());
        N_type += to_string(N);

        if (answer &gt; optimal) answer = optimal;
    }

    if (answer == 9) return -1;

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    실패 (16.18ms, 3.96MB)
  테스트 2 〉    통과 (8.42ms, 3.97MB)
  테스트 3 〉    통과 (14.51ms, 3.87MB)
  테스트 4 〉    통과 (45.78ms, 3.96MB)
  테스트 5 〉    통과 (26.11ms, 3.84MB)
  테스트 6 〉    통과 (15.81ms, 3.97MB)
  테스트 7 〉    통과 (15.18ms, 3.96MB)
  테스트 8 〉    실패 (34.93ms, 3.83MB)
  테스트 9 〉    통과 (0.02ms, 3.83MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 77.8
  합계: 77.8 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="2차-시도">2차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;unordered_set&gt;

using namespace std;

int solution(int N, int number) {
    if (N==number) return 1;

    vector&lt;unordered_set&lt;int&gt;&gt; result_list(8);

    result_list[0].insert(N);

    for (int i=1; i&lt;8; i++) {
        string repeat(i+1, &#39;0&#39; + N);
        result_list[i].insert(stoi(repeat));
        for (int j=0; j&lt;i; j++) {
            for (auto iter_01 = result_list[j].begin(); iter_01 != result_list[j].end(); iter_01++) {
                for (auto iter_02 = result_list[i-j-1].begin(); iter_02 != result_list[i-j-1].end(); iter_02++) {
                    result_list[i].insert(*iter_01 + *iter_02);
                    result_list[i].insert(*iter_01 - *iter_02);
                    result_list[i].insert(*iter_01 * *iter_02);
                    if (*iter_02 != 0) result_list[i].insert(*iter_01 / *iter_02);
                }
            }
        }

        if (result_list[i].find(number) != result_list[i].end()) return i+1;
    }

    return -1;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.26ms, 3.9MB)
  테스트 2 〉    통과 (0.01ms, 3.84MB)
  테스트 3 〉    통과 (0.02ms, 3.95MB)
  테스트 4 〉    통과 (4.11ms, 3.96MB)
  테스트 5 〉    통과 (3.12ms, 4.16MB)
  테스트 6 〉    통과 (0.06ms, 3.95MB)
  테스트 7 〉    통과 (0.08ms, 3.89MB)
  테스트 8 〉    통과 (4.11ms, 3.89MB)
  테스트 9 〉    통과 (0.01ms, 3.97MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<p>```</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 11주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-11%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-11%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 29 Jun 2021 10:10:45 GMT</pubDate>
            <description><![CDATA[<h1 id="탐욕법greedy">탐욕법(Greedy)</h1>
<h2 id="구명보트">구명보트</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(vector&lt;int&gt; people, int limit) {
    int answer = 0;

    sort(people.begin(), people.end());

    while (people.size()) {
        int most_heavy = *--upper_bound(people.begin(), people.end(), limit);
        people.erase(--upper_bound(people.begin(), people.end(), limit));

        if (people.size()) {
            auto second_most_heavy = --upper_bound(people.begin(), people.end(), limit - most_heavy);
            if (second_most_heavy != --people.begin()) people.erase(--upper_bound(people.begin(), people.end(), limit - most_heavy));
        }

        answer++;
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.46ms, 3.92MB)
  테스트 2 〉    통과 (0.27ms, 3.91MB)
  테스트 3 〉    통과 (0.34ms, 3.94MB)
  테스트 4 〉    통과 (0.29ms, 3.93MB)
  테스트 5 〉    통과 (0.16ms, 3.95MB)
  테스트 6 〉    통과 (0.09ms, 3.89MB)
  테스트 7 〉    통과 (0.13ms, 3.88MB)
  테스트 8 〉    통과 (0.02ms, 3.89MB)
  테스트 9 〉    통과 (0.03ms, 3.96MB)
  테스트 10 〉    통과 (0.30ms, 3.89MB)
  테스트 11 〉    통과 (0.29ms, 3.9MB)
  테스트 12 〉    통과 (0.25ms, 3.93MB)
  테스트 13 〉    통과 (0.29ms, 3.95MB)
  테스트 14 〉    통과 (0.31ms, 3.95MB)
  테스트 15 〉    통과 (0.03ms, 3.84MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    실패 (시간 초과)
  테스트 2 〉    통과 (4.91ms, 4.68MB)
  테스트 3 〉    실패 (시간 초과)
  테스트 4 〉    통과 (4.84ms, 4.82MB)
  테스트 5 〉    통과 (4.23ms, 4.56MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 75.0
  효율성: 15.0
  합계: 90.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="2차-시도">2차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;set&gt;

using namespace std;

int solution(vector&lt;int&gt; people, int limit) {
    int answer = 0;

    multiset &lt;int&gt; weight(people.begin(), people.end());
    weight.insert(-1);

    while (weight.size() &gt; 1) {
        auto most_heavy_iter = --weight.lower_bound(limit + 1);
        int most_heavy = *most_heavy_iter;
        weight.erase(most_heavy_iter);

        if (weight.size() &gt; 1) {
            auto second_most_heavy = --weight.lower_bound(limit - most_heavy + 1);
            if (*second_most_heavy != -1) weight.erase(second_most_heavy);
        }

        answer++;
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.94ms, 3.86MB)
  테스트 2 〉    통과 (0.62ms, 3.87MB)
  테스트 3 〉    통과 (0.65ms, 3.89MB)
  테스트 4 〉    통과 (0.60ms, 3.96MB)
  테스트 5 〉    통과 (0.35ms, 3.95MB)
  테스트 6 〉    통과 (0.19ms, 3.91MB)
  테스트 7 〉    통과 (0.31ms, 3.91MB)
  테스트 8 〉    통과 (0.04ms, 3.95MB)
  테스트 9 〉    통과 (0.06ms, 3.71MB)
  테스트 10 〉    통과 (0.62ms, 3.89MB)
  테스트 11 〉    통과 (0.52ms, 3.98MB)
  테스트 12 〉    통과 (0.46ms, 3.97MB)
  테스트 13 〉    통과 (0.63ms, 3.93MB)
  테스트 14 〉    통과 (0.72ms, 3.94MB)
  테스트 15 〉    통과 (0.07ms, 3.93MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    실패 (시간 초과)
  테스트 2 〉    실패 (시간 초과)
  테스트 3 〉    실패 (시간 초과)
  테스트 4 〉    실패 (시간 초과)
  테스트 5 〉    실패 (시간 초과)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 75.0
  효율성: 0.0
  합계: 75.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="3차-시도">3차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(vector&lt;int&gt; people, int limit) {
    int answer = 0;

    sort(people.begin(), people.end(), greater&lt;&gt;());

    for (int left=0, right=people.size()-1; left&lt;=right; left++) {
        if (people[left] + people[right] &lt;= limit) {
            right--;
        }

        answer++;
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.17ms, 3.94MB)
  테스트 2 〉    통과 (0.11ms, 3.96MB)
  테스트 3 〉    통과 (0.13ms, 3.91MB)
  테스트 4 〉    통과 (0.12ms, 3.95MB)
  테스트 5 〉    통과 (0.08ms, 3.95MB)
  테스트 6 〉    통과 (0.04ms, 3.92MB)
  테스트 7 〉    통과 (0.06ms, 3.89MB)
  테스트 8 〉    통과 (0.01ms, 3.96MB)
  테스트 9 〉    통과 (0.02ms, 3.93MB)
  테스트 10 〉    통과 (0.11ms, 3.97MB)
  테스트 11 〉    통과 (0.11ms, 3.83MB)
  테스트 12 〉    통과 (0.10ms, 3.97MB)
  테스트 13 〉    통과 (0.11ms, 3.94MB)
  테스트 14 〉    통과 (0.12ms, 3.94MB)
  테스트 15 〉    통과 (0.02ms, 3.84MB)
</code></pre>
</blockquote>
<p>효율성  테스트
  테스트 1 〉    통과 (1.67ms, 4.66MB)
  테스트 2 〉    통과 (1.43ms, 4.63MB)
  테스트 3 〉    통과 (1.42ms, 4.76MB)
  테스트 4 〉    통과 (1.21ms, 4.79MB)
  테스트 5 〉    통과 (1.21ms, 4.6MB)</p>
<blockquote>
</blockquote>
<p>채점 결과
  정확성: 75.0
  효율성: 25.0
  합계: 100.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h2 id="섬-연결하기">섬 연결하기</h2>
<h3 id="1차-시도-1">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(int n, vector&lt;vector&lt;int&gt;&gt; costs) {
    int answer = -1;

    vector&lt;vector&lt;int&gt;&gt; field(n, vector&lt;int&gt; (n, -1));
    vector&lt;int&gt; road;

    for (auto a:costs) {
        field[a[0]][a[1]] = a[2];
        field[a[1]][a[0]] = a[2];
    }

    for (int i=0; i&lt;n; i++) road.push_back(i);

    do{
        int score = 0;
        bool isRoad = true;

        for (int i=0; i&lt;n-1; i++) {
            if (field[road[i]][road[i+1]] == -1) {
                isRoad = false;
                break;
            }

            score += field[road[i]][road[i+1]];
        }

        if (isRoad &amp;&amp; (answer == -1 || answer &gt; score)) {
            answer = score;
        }
    } while (next_permutation(road.begin(), road.end()));

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.9MB)
  테스트 2 〉    통과 (0.01ms, 3.72MB)
  테스트 3 〉    실패 (1.99ms, 3.89MB)
  테스트 4 〉    실패 (시간 초과)
  테스트 5 〉    실패 (0.27ms, 3.77MB)
  테스트 6 〉    실패 (시간 초과)
  테스트 7 〉    실패 (시간 초과)
  테스트 8 〉    실패 (0.02ms, 3.96MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 25.0
  합계: 25.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="2차-시도-1">2차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(int n, vector&lt;vector&lt;int&gt;&gt; costs) {
    int answer = 0;

    sort(costs.begin(), costs.end(), [] (vector&lt;int&gt; a, vector&lt;int&gt; b) {return a[2] &lt; b[2];});
    vector&lt;vector&lt;int&gt;&gt; choose_node = {costs[0]};
    vector &lt;int&gt; parent;

    for (int i=0; i&lt;n; i++) parent.push_back(i);
    parent[choose_node[0][1]] = parent[choose_node[0][0]];

    for (int i=1; i&lt;costs.size(); i++) {
        if (choose_node.size() == n - 1) break;
        if (parent[costs[i][0]] == parent[costs[i][1]]) continue;

        choose_node.push_back(costs[i]);
        parent[choose_node.back()[1]] = parent[choose_node.back()[0]];
    }

    for (vector&lt;int&gt; a:choose_node) {
        answer += a[2];
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.95MB)
  테스트 2 〉    통과 (0.01ms, 3.96MB)
  테스트 3 〉    실패 (0.02ms, 3.94MB)
  테스트 4 〉    실패 (0.02ms, 3.97MB)
  테스트 5 〉    실패 (0.02ms, 3.98MB)
  테스트 6 〉    통과 (0.04ms, 3.72MB)
  테스트 7 〉    실패 (0.04ms, 3.77MB)
  테스트 8 〉    통과 (0.01ms, 3.96MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 50.0
  합계: 50.0 / 100.0</p>
<blockquote>
<pre><code></code></pre></blockquote>
<h3 id="3차-시도-1">3차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;

using namespace std;

int solution(int n, vector&lt;vector&lt;int&gt;&gt; costs) {
    int answer = 0;

    sort(costs.begin(), costs.end(), [] (vector&lt;int&gt; a, vector&lt;int&gt; b) {return a[2] &lt; b[2];});
    vector&lt;vector&lt;int&gt;&gt; choose_node = {costs[0]};
    vector &lt;int&gt; group;

    for (int i=0; i&lt;n; i++) group.push_back(i);

    group[choose_node[0][1]] = group[choose_node[0][0]];

    for (int i=1; i&lt;costs.size(); i++) {
        if (choose_node.size() == n - 1) break;
        if (group[costs[i][0]] == group[costs[i][1]]) continue;

        choose_node.push_back(costs[i]);
        for (int i=0, change_group = group[choose_node.back()[1]]; i&lt;group.size(); i++) {
            if (group[i] == change_group) group[i] = group[choose_node.back()[0]];
        }
    }

    for (vector&lt;int&gt; a:choose_node) {
        answer += a[2];
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.98MB)
  테스트 2 〉    통과 (0.01ms, 3.95MB)
  테스트 3 〉    통과 (0.02ms, 3.95MB)
  테스트 4 〉    통과 (0.02ms, 3.97MB)
  테스트 5 〉    통과 (0.02ms, 3.77MB)
  테스트 6 〉    통과 (0.06ms, 3.96MB)
  테스트 7 〉    통과 (0.05ms, 3.89MB)
  테스트 8 〉    통과 (0.01ms, 4MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<blockquote>
<p>```</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 10주차 +α]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-10%EC%A3%BC%EC%B0%A8-miar7ak5</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-10%EC%A3%BC%EC%B0%A8-miar7ak5</guid>
            <pubDate>Tue, 29 Jun 2021 03:42:08 GMT</pubDate>
            <description><![CDATA[<h1 id="level-2">Level 2</h1>
<h2 id="단체사진-찍기">단체사진 찍기</h2>
<h3 id="1차">1차</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;cmath&gt;

using namespace std;

bool CanPosition(string pos, vector&lt;string&gt; data) {
    for (int i=0; i&lt;data.size(); i++) {
        int diff = abs(int(pos.find(data[i][0]) - pos.find(data[i][2]))) - 1;
        int condition = data[i][4] - &#39;0&#39;;

        switch(data[i][3]) {
            case &#39;=&#39;:
                if (diff != condition) {
                    return false;
                }
                break;
            case &#39;&gt;&#39;:
                if (diff &lt;= condition) {
                    return false;
                }
                break;
            case &#39;&lt;&#39;:
                if (diff &gt;= condition) {
                    return false;
                }
                break;
        }
    }

    return true;
}

int solution(int n, vector&lt;string&gt; data) {
    int answer = 0;
    string pos = &quot;ACFJMNRT&quot;;

    do {
        if (CanPosition(pos, data)) {
            answer++;
        }
    } while (next_permutation(pos.begin(), pos.end()));

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (2704.51ms, 4.04MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Coding Test Study - 10주차]]></title>
            <link>https://velog.io/@checking_pks/Coding-Test-Study-10%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@checking_pks/Coding-Test-Study-10%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 22 Jun 2021 08:05:50 GMT</pubDate>
            <description><![CDATA[<h1 id="탐욕법-greedy">탐욕법 (Greedy)</h1>
<h2 id="체육복">체육복</h2>
<h3 id="1차-시도">1차 시도</h3>
<pre><code class="language-cpp">#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(int n, vector&lt;int&gt; lost, vector&lt;int&gt; reserve) {
    int answer = 0;
    vector &lt;int&gt; have_clothes(n, 1);

    for (int n:lost) have_clothes[n]--;
    for (int n:reserve) have_clothes[n]++;

    for (int i=0; i&lt;have_clothes.size(); i++) {
        if (have_clothes[i] == 0) {
            if (i &gt; 0 &amp;&amp; have_clothes[i-1] == 2) {
                have_clothes[i-1]--;
                have_clothes[i]++;
            } else if (i &lt; have_clothes.size()-1 &amp;&amp; have_clothes[i+1] == 2) {
                have_clothes[i+1]--;
                have_clothes[i]++;
            }
        }

        if (have_clothes[i] &gt;= 1) answer++;
    }

    return answer;
}</code></pre>
<blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    실패 (0.01ms, 3.85MB)
  테스트 2 〉    실패 (0.01ms, 3.97MB)
  테스트 3 〉    통과 (0.01ms, 3.95MB)
  테스트 4 〉    통과 (0.01ms, 3.96MB)
  테스트 5 〉    실패 (0.01ms, 3.95MB)
  테스트 6 〉    통과 (0.01ms, 3.91MB)
  테스트 7 〉    통과 (0.01ms, 3.97MB)
  테스트 8 〉    통과 (0.01ms, 3.96MB)
  테스트 9 〉    실패 (0.01ms, 3.72MB)
  테스트 10 〉    통과 (0.01ms, 3.96MB)
  테스트 11 〉    실패 (0.01ms, 3.89MB)
  테스트 12 〉    통과 (0.01ms, 3.91MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 58.3
  합계: 58.3 / 100.0</p>
<pre><code>
### 2차 시도
```cpp
#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int solution(int n, vector&lt;int&gt; lost, vector&lt;int&gt; reserve) {
    int answer = 0;
    vector &lt;int&gt; have_clothes(n, 1);

    for (int n:lost) have_clothes[n-1]--;
    for (int n:reserve) have_clothes[n-1]++;

    for (int i=0; i&lt;have_clothes.size(); i++) {
        if (have_clothes[i] == 0) {
            if (i &gt; 0 &amp;&amp; have_clothes[i-1] == 2) {
                have_clothes[i-1]--;
                have_clothes[i]++;
            } else if (i &lt; have_clothes.size()-1 &amp;&amp; have_clothes[i+1] == 2) {
                have_clothes[i+1]--;
                have_clothes[i]++;
            }
        }

        if (have_clothes[i] &gt;= 1) answer++;
    }

    return answer;
}</code></pre><blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.97MB)
  테스트 2 〉    통과 (0.01ms, 3.97MB)
  테스트 3 〉    통과 (0.01ms, 3.78MB)
  테스트 4 〉    통과 (0.01ms, 3.93MB)
  테스트 5 〉    통과 (0.01ms, 3.97MB)
  테스트 6 〉    통과 (0.01ms, 3.82MB)
  테스트 7 〉    통과 (0.01ms, 3.8MB)
  테스트 8 〉    통과 (0.01ms, 3.97MB)
  테스트 9 〉    통과 (0.01ms, 3.91MB)
  테스트 10 〉    통과 (0.01ms, 3.97MB)
  테스트 11 〉    통과 (0.01ms, 3.99MB)
  테스트 12 〉    통과 (0.01ms, 3.92MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0</p>
<pre><code>
## 조이스틱
### 1차 시도
```cpp
#include &lt;string&gt;
#include &lt;vector&gt;

using namespace std;

int optimal_distance(string name, int * pos) {
    int left_move = 0, right_move = 0;

    for (int i=0; i&lt;name.length(); i++) {
        if ((name[*pos] != &#39;A&#39;) || (left_move != 0 &amp;&amp; right_move != 0)) break;

        if (left_move == 0 &amp;&amp; name[(*pos - i + name.length()) %  name.length()] != &#39;A&#39;) left_move = i;
        if (right_move == 0 &amp;&amp; name[(*pos + i) %  name.length()] != &#39;A&#39;) right_move = i;
    }

    *pos = (*pos + ((left_move &lt; right_move) ? name.length()-left_move : right_move)) % name.length();

    return (left_move &lt; right_move) ? left_move : right_move;
}

int solution(string name) {
    int answer = 0;
    int pos = 0;

    vector &lt;int&gt; alphabet_code = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};

    for (string c(name.length(), &#39;A&#39;); c != name; name[pos] = &#39;A&#39;) {
        answer += optimal_distance(name, &amp;pos) + alphabet_code[name[pos] - &#39;A&#39;];
    }

    return answer;
}</code></pre><blockquote>
<pre><code class="language-markdown">정확성  테스트
  테스트 1 〉    통과 (0.01ms, 3.93MB)
  테스트 2 〉    통과 (0.01ms, 3.95MB)
  테스트 3 〉    통과 (0.01ms, 3.95MB)
  테스트 4 〉    통과 (0.01ms, 3.89MB)
  테스트 5 〉    통과 (0.01ms, 3.95MB)
  테스트 6 〉    통과 (0.01ms, 3.95MB)
  테스트 7 〉    통과 (0.01ms, 3.97MB)
  테스트 8 〉    통과 (0.01ms, 3.93MB)
  테스트 9 〉    통과 (0.01ms, 3.89MB)
  테스트 10 〉    통과 (0.01ms, 3.96MB)
  테스트 11 〉    통과 (0.01ms, 3.95MB)
</code></pre>
</blockquote>
<p>채점 결과
  정확성: 100.0
  합계: 100.0 / 100.0
```</p>
]]></description>
        </item>
    </channel>
</rss>