<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>rayleigh.log</title>
        <link>https://velog.io/</link>
        <description>단단한 아이스크림</description>
        <lastBuildDate>Wed, 12 Feb 2025 06:19:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>rayleigh.log</title>
            <url>https://velog.velcdn.com/images/rayleigh_/profile/9980fedd-b8b4-4c51-97a1-d7c898947287/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. rayleigh.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/rayleigh_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Flutter Bug] Could not cast value of type 'NSNull' (0x1f04621d0) to 'webview_flutter_wkwebview.AuthenticationChallengeResponse']]></title>
            <link>https://velog.io/@rayleigh_/Flutter-Bug-Could-not-cast-value-of-type-NSNull-0x1f04621d0-to-webviewflutterwkwebview.AuthenticationChallengeResponse</link>
            <guid>https://velog.io/@rayleigh_/Flutter-Bug-Could-not-cast-value-of-type-NSNull-0x1f04621d0-to-webviewflutterwkwebview.AuthenticationChallengeResponse</guid>
            <pubDate>Wed, 12 Feb 2025 06:19:40 GMT</pubDate>
            <description><![CDATA[<h1 id="🐛-상황">🐛 상황</h1>
<p>운영중인 플러터 앱에 구글 애드몹 광고를 적용하기 위해 <a href="https://pub.dev/packages/google_mobile_ads"><code>google_mobile_ads: ^5.3.1</code></a>를 설치했다.</p>
<p>광고는 성공적으로 적용했지만 기존 webview를 열면 아래와 같은 오류가 발생하면 앱이 죽는 현상이 발생했다.</p>
<pre><code class="language-shell">Could not cast value of type &#39;NSNull&#39; (0x1f04621d0) to &#39;webview_flutter_wkwebview.AuthenticationChallengeResponse&#39;</code></pre>
<h1 id="🕵️-원인">🕵️ 원인</h1>
<p>일단 <code>google_mobile_ads</code>를 설치하고 난 후부터 오류가 발생했으니 해당 패키지를 살표 보기로함.</p>
<p><a href="https://pub.dev/packages/google_mobile_ads">여기서</a> 보니까 이 패키지는 아래와 같은 의존 패키지가 있음.</p>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/c842cf7e-e2af-4e2b-8c65-fb696eb5413d/image.png" alt=""></p>
<p>그리고 오류 내용을 살펴보면 <code>webview_flutter_wkwebview</code>와 관련 있음.</p>
<p>이후 사례를 찾아보려 구글링 시작. <code>webview_flutter_wkwebview</code> 관련해서 <strong>패키지 버전 의존성 문제</strong>가 자주 발생하는 것을 인식.</p>
<h1 id="🚀-해결">🚀 해결</h1>
<p><a href="https://github.com/flutter/flutter/issues/162437#issuecomment-2626546934">https://github.com/flutter/flutter/issues/162437#issuecomment-2626546934</a></p>
<p>위 깃헙 이슈의 토론에서 적합하다고 생각한 방법 선택.</p>
<p><code>google_mobile_ads: ^5.3.1</code>을 설치하면서 패키지 의존성에 따라 <code>webview_flutter_wkwebview: ^3.18.0</code>로 업그레이드 되었음.</p>
<p>이를 아래와 같이 <code>3.17.0</code> 버전으로 다운그레이드 설정하여 해결 완료. 🎉</p>
<pre><code class="language-yaml"># pubspec.yaml
dependency_overrides:
  webview_flutter_wkwebview: 3.17.0</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[앱 분석] 인프런 앱 분석하기!]]></title>
            <link>https://velog.io/@rayleigh_/%EC%95%B1-%EB%B6%84%EC%84%9D-%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%95%B1-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@rayleigh_/%EC%95%B1-%EB%B6%84%EC%84%9D-%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%95%B1-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 26 Jan 2025 06:31:00 GMT</pubDate>
            <description><![CDATA[<h1 id="🙋-인프런은-어떤-앱일까">🙋 인프런은 어떤 앱일까?</h1>
<p><strong><a href="https://www.inflearn.com/">인프런(inflearn)</a></strong>은 2017년 부터 운영중인 온라인 교육 전문 플랫폼이다. 주로 프로그래밍, 개발, 인공지능, 데이터, 디자인과 같은 <strong>IT분야 교육</strong>을 핵심으로 성장했다. 이외에도 업무 스킬, 영어 등 다양한 분야의 교육을 확장해 나가고 있다.</p>
<p>현재 (주)인프랩에서 운영중이다. <a href="https://doc.clickup.com/d/3gfz7-5843/log/3gfz7-75205/%EC%9D%B8%ED%94%84%EB%9E%A9-%EC%8B%A4-log">인프랩 실Log</a>에서 인프런의 성장(발전) 기록을 볼 수 있다.</p>
<p>과거에 인프런 모바일 앱을 서비스 했으나 제대로 되지 않아 웹 위주로 사용 되었다. 그래서 중간에 앱 서비스가 중단 되었다가 2024년 6월에 <a href="https://apps.apple.com/kr/app/%EC%9D%B8%ED%94%84%EB%9F%B0-%EB%9D%BC%EC%9D%B4%ED%94%84%ED%83%80%EC%9E%84-%EC%BB%A4%EB%A6%AC%EC%96%B4-%ED%94%8C%EB%9E%AB%ED%8F%BC/id6502435542">새로운 모바일 앱</a>을 출시 하였다.</p>
<h2 id="주요-경쟁사">주요 경쟁사</h2>
<ul>
<li>유데미</li>
<li>패스트캠퍼스</li>
<li>프로그래머스</li>
<li>구름에듀</li>
<li>등등</li>
</ul>
<h1 id="👨💻-ios-앱-분석">👨‍💻 iOS 앱 분석</h1>
<p>인프런 앱 같은 경우는 <strong>본인의 강의를 수강하는 목적</strong>만 가지고 있다. 그래서 인프런의 다른 서비스(강의 구매 및 검색)는 웹 서비스로 이용해야 한다. 그래서 비교적 앱이 간단하다. (나의 강의를 볼 수 있는 기능만 있음)</p>
<h2 id="학습중---1">학습중 - 1</h2>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/26dfbceb-dc9d-47ac-b6de-989c12fc6a26/image.png" alt=""></p>
<h2 id="학습중---2">학습중 - 2</h2>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/5a00c4bb-9cea-437b-8b4c-093ddf35de67/image.png" alt=""></p>
<h2 id="설정">설정</h2>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/51b1f99f-4d0d-4071-bc94-a46729fcfd7c/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[앱 분석] SOOP 홈 화면 분석하기!]]></title>
            <link>https://velog.io/@rayleigh_/%EC%95%B1-%EB%B6%84%EC%84%9D-SOOP-%ED%99%88-%ED%99%94%EB%A9%B4-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@rayleigh_/%EC%95%B1-%EB%B6%84%EC%84%9D-SOOP-%ED%99%88-%ED%99%94%EB%A9%B4-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 24 Jan 2025 01:39:21 GMT</pubDate>
            <description><![CDATA[<h1 id="🙋-soop은-어떤-앱일까">🙋 SOOP은 어떤 앱일까?</h1>
<p>숲(구 아프리카TV)은 스트리머와 유저가 함께 실시간 소통을 통해 함께 콘텐츠를 만들어가는 Live Streaming 서비스 플랫폼이다.</p>
<h3 id="주요-경쟁사">주요 경쟁사</h3>
<ul>
<li>네이버 치지직</li>
<li>유튜브 라이브</li>
<li>트위치 (한국 서비스 철수)<h1 id="👨💻-ios-앱-분석">👨‍💻 iOS 앱 분석</h1>
이번에는 숲의 홈 화면만 분석해 본다.<h3 id="홈---추천1">홈 - 추천1</h3>
앱을 실행하면 가장 처음에 보이는 화면으로 실시간 인기 방송을 상단에 보여준다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/d5073ddb-8ba5-466c-b8e7-70b8aa64744d/image.png" alt=""></p>
<h3 id="홈---추천2">홈 - 추천2</h3>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/03919c44-900a-4fa2-ab2d-36fde57f21b5/image.png" alt=""></p>
<h3 id="홈---이슈">홈 - 이슈</h3>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/f4b62a44-1137-4559-b02d-92227e50e165/image.png" alt=""></p>
<h3 id="홈---라이브">홈 - 라이브</h3>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/a26627bf-f7e3-4e56-8953-edd680fa7c42/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CPU 아키텍처의 종류와 각 특징]]></title>
            <link>https://velog.io/@rayleigh_/CPU-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98%EC%9D%98-%EC%A2%85%EB%A5%98%EC%99%80-%EA%B0%81-%ED%8A%B9%EC%A7%95</link>
            <guid>https://velog.io/@rayleigh_/CPU-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98%EC%9D%98-%EC%A2%85%EB%A5%98%EC%99%80-%EA%B0%81-%ED%8A%B9%EC%A7%95</guid>
            <pubDate>Wed, 15 Jan 2025 06:25:29 GMT</pubDate>
            <description><![CDATA[<h1 id="cpu-다-똑같은거-아니야">CPU 다 똑같은거 아니야?</h1>
<p>정보화 시대가 되면서 CPU(중앙처리장치)는 한 번쯤 들어본 익숙한 단어가 되었다. CPU는 컴퓨터에서 두뇌의 역할(연산, 제어)을 담당한다.</p>
<h3 id="cpu에서-아키텍처란">CPU에서 아키텍처란</h3>
<p>CPU 아키텍처는 명령어 집합(ISA), 데이터 유형, 레지스터, 메모리 계층 및 실행 모델을 포함한 CPU의 기본 설계 및 구성을 말한다. 앞으로 x86, x64 그리고 ARM64이라는 아키텍처를 살펴볼 것이다.</p>
<h1 id="x86">x86</h1>
<p>x86 아키텍처는 흔히 32비트 체제의 CPU를 일컫는다. 조금 더 정확하게 하면 x86-IA32(Intel Architecture-32)이며 인텔에 의해 고안된 아키텍처이다. 64비트 CPU가 대중화되기 전에는 대부분 컴퓨터에서 이 32비트 CPU를 사용했다.</p>
<h3 id="이름이-x86인-이유">이름이 x86인 이유</h3>
<p>“왜 x86이라 하지? 32비트니까 x32라 하면 좋지 않을까?” 이런 생각이 들기도 할 것이다. </p>
<p>인텔이 과거에 출시한 32비트 CPU의 이름이 386, 486 등이었다. 즉 ‘~86’으로 끝나는 이름이었고 여기서 공통되는 ‘86’만 뽑아 x86이라 부르게 되었다. </p>
<blockquote>
<p>x86-IA16(16비트)가 먼저 출시되었지만 대중에게 거의 보급되지 못하고 IA-32가 출시되었다. 그래서 현재에 x86이라 하면 대게 32비트 아키텍처를 의미한다.</p>
</blockquote>
<h1 id="x64amd64">x64(amd64)</h1>
<p>x86 즉 32비트에서 더 발전되어 64비트 체제의 CPU이다. 64비트가 되어 바뀌는 것은 CPU가 <strong>한 번에 처리할 수 있는 데이터의 크기(레지스터 크기)</strong>이다.</p>
<ul>
<li>32-bit: 32비트로 데이터를 처리할 수 있으며 최대 4GB RAM을 사용할 수 있다.</li>
<li>64-bit: 64비트로 데이터를 처리할 수 있으며 최대 18EB(1.8e+10GB) RAM을 사용할 수 있다.</li>
</ul>
<p>64비트 도입 초기에는 AMD가 intel 보다 도입하여 amd64라고 불리었다. 추후 intel도 64비트를 도입 함에 따라 x64라고 통칭하게 되었다.</p>
<blockquote>
<p>x64 == amd64  // true</p>
</blockquote>
<h2 id="arm64">ARM64</h2>
<p>ARM64는 ARM이라는 회사에서 개발한 64비트 CPU 아키텍처이다. x64와 같은 64비트 아키텍처이지만 x64와 다른 목적을 가지고 탄생한 아키텍처이다. x64는 주로 일반적인 데스크탑 및 노트북에 사용되지만, ARM64는 주로 모바일 기기나 임베디드 컴퓨터와 같은 <strong>저전력</strong> 컴퓨팅 환경에 사용된다.</p>
<p>즉, intel과 amd와는 목표가 달랐고 근본적으로 다른 CPU 아키텍처이기 때문에 x64와 ARM64는 서로 호환되지 않는다.</p>
<blockquote>
<p>근본적으로 다른 이유 중 하나는 x64와 ARM64는 서로 다른 ISA(명령어 집합)를 사용하기 때문이다.</p>
</blockquote>
<blockquote>
<p>ISA(Instruction Set Architecture)란 하드웨어와 소프트웨어 사이의 인터페이스 역할을 하는 설계도(blueprint)이다. 쉽게 말하면 소프트웨어가 CPU를 제어하는 방법을 설명하는 모델이다.</p>
</blockquote>
<blockquote>
<p>흔히 들어본 애플의 A 시리즈, M 시리즈, 퀄컴의 스냅드래곤, 삼성의 엑시노스 모두 arm 아키텍처를 따른다.</p>
</blockquote>
<h1 id="정리">정리</h1>
<table>
<thead>
<tr>
<th>아키텍처</th>
<th>정의</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td>x86</td>
<td>32bit intel architecture</td>
<td>과거 인텔의 32bit cpu이다.</td>
</tr>
<tr>
<td>x64</td>
<td>64bit architecture(intel, amd)</td>
<td>64bit로 데이터를 처리하면서 더 많은 메모리 주소 공간을 제공하여 성능이 향상되었다.</td>
</tr>
<tr>
<td>ARM64</td>
<td>64bit architecture</td>
<td>저전력이 요구되는 모바일 및 임베디드 시스템에 적합하다.</td>
</tr>
</tbody></table>
<p><em>출처 : <a href="https://m.blog.naver.com/cjs0308cjs/223242935705">https://m.blog.naver.com/cjs0308cjs/223242935705</a></em></p>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://m.blog.naver.com/cjs0308cjs/223242935705">[x86, x64(amd64), Arm64] 뜻, 구분방법, CPU 역사, 차이점 알아보기</a></li>
<li><a href="https://blog.naver.com/PostView.nhn?blogId=mumasa&amp;logNo=221049608979">x86과 x64의 뜻과 차이 - CPU, OS, S/W</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 35일차 TIL - 백준: 주사위 윷놀이 (17825) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-35%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-35%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Sun, 01 Dec 2024 13:12:42 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/17825">17825</a></td>
<td align="center">주사위 윷놀이</td>
<td align="center">시뮬레이션</td>
<td align="center">골드2</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>이 문제는 브루트포스, 시뮬레이션, 백트래킹 관련 문제이다. 즉, 탐색을 통해 모든 경우의 수를 탐색하게 된다.</p>
<p>중요한 것 중 하나가 탐색에 필요한 인접 행렬을 정의하는 것이다. 문제에서 주어진 그래프가 복잡하기 때문에 꼼꼼하게 정의해야 한다.</p>
<p>한 가지 특징이 있다면 중간에 파란색 화살표로 분기가 가능하다는 것이다. 부분은 두 개의 방향을 하나의 리스트로 묶되 1번 인덱스는 출발 시 노드로 정의했다.</p>
<p>DFS로 탐색했으며 말을 하나씩 이동시켜보며 모든 경우의 수를 탐색하여 점수의 최댓값을 구했다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let adj = [[1],[2],[3],[4],[5],[6,21],[7],[8],[9],[10],[11,27],[12],[13],[14],[15],[16,29],[17],[18],[19],[20],[32],[22],[23],[24],[25],[26],[20],[28],[24],[30],[31],[24],[32],[32],[32],[32],[32]]
let score = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18,  20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 13, 16, 19, 25, 30, 35, 22, 24, 28, 27, 26, 0]

func dfs(_ n: Int, _ sum: Int) {
    if n == 10 {
        ans = max(ans, sum)
        return
    }

    for j in 0..&lt;4 {
        let s = v[j]
        var c = adj[s].last!
        for _ in 1..&lt;list[n] {
            c = adj[c].first!
        }

        if c == 32 || !v.contains(c) {
            v[j] = c
            dfs(n+1, sum+score[c])
            v[j] = s
        }
    }
}

let list = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }
var v = [0, 0, 0, 0]
var ans = 0
dfs(0, 0)
print(ans)</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>풀이를 생각하기 어려운 문제였다. 꼭 다시 한 번 풀어보자.
<a href="https://youtu.be/UlHUK2STX40">참고 - [삼성기출 #33] 17825. 주사위 윷놀이 (백준, 파이썬)</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 34일차 TIL - 프로그래머스: 개인정보 수집 유효기간
(150370) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-34%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-34%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Sun, 01 Dec 2024 01:28:23 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/150370">150370</a></td>
<td align="center">개인정보 수집 유효기간</td>
<td align="center">시뮬레이션</td>
<td align="center">Lv.1</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>단순히 주어진 요구사항을 구현하는 문제이다.</p>
<p>효율적인 날짜 계산 방법만 떠올리면 어렵지 않게 해결할 수 있다.</p>
<p>이번에는 날짜를 모두 &#39;일&#39;로 변환하여 계산했다.</p>
<pre><code class="language-swift">년*12*28 + 월*28 + 일</code></pre>
<p>이렇게 변환하면 간단하게 대소 비교로 각 날짜를 비교할 수 있다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ today:String, _ terms:[String], _ privacies:[String]) -&gt; [Int] {
    func dateToInt(_ date: String) -&gt; Int {
        let temp = date.split(separator: &quot;.&quot;).map{ Int($0)! }
        return temp[0]*12*28 + temp[1]*28 + temp[2]
    }

    let todayDate = dateToInt(today)
    var termsDic: [String:Int] = [:]
    for term in terms {
        let input = term.split(separator: &quot; &quot;)
        termsDic[String(input[0])] = Int(input[1])! * 28
    }

    var result: [Int] = []
    for (i, privacie) in privacies.enumerated() {
        let input = privacie.split(separator: &quot; &quot;).map{ String($0) }
        let (collectionDate, type) = (dateToInt(input[0]), input[1])
        if collectionDate + termsDic[type]! &lt;= todayDate {
            result.append(i+1)
        }
    }
    return result
}</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<h3 id="개선-전-코드">개선 전 코드</h3>
<p>개선 전에는 아래와 같이 날짜 연, 월, 일을 따로 계산했다. 그러다 보니 계산이 복잡해지고 코드가 불필요하게 복잡해졌다.
알고리즘 문제에서 날짜 계산이 나오면 하나의 단위로 변환하는 것을 먼저 고려해 보자!</p>
<pre><code class="language-swift">import Foundation

func solution(_ today:String, _ terms:[String], _ privacies:[String]) -&gt; [Int] {
    func dateStringToIntArray(_ date: String) -&gt; [Int] {
        return date.split(separator: &quot;.&quot;).map{ Int($0)! }
    }

    let todays = dateStringToIntArray(today)
    var termss: [String:Int] = [:]
    for term in terms {
        let input = term.split(separator: &quot; &quot;)
        termss[String(input[0])] = Int(input[1])!
    }

    func calculateDate(_ date: [Int], _ add: Int) -&gt; [Int] {
        var newDate = Array(repeating: 0, count: 3)
        let addY = add/12
        let addM = add%12
        newDate[0] = date[0] + addY
        newDate[1] = date[1] + addM
        newDate[2] = date[2] - 1

        if newDate[1] &gt; 12 {
            newDate[0] = newDate[0] + 1
            newDate[1] -= 12
        }
        if newDate[2] &lt; 1 {
            newDate[1] = newDate[1] - 1
            if newDate[1] == 0 {
                newDate[1] = 12
            }
            newDate[2] = 28
        }
        return newDate
    }

    func isDateOver(_ today: [Int], _ past: [Int], _ type: String) -&gt; Bool {
        let date = calculateDate(past, termss[type]!)
        if date[0] &lt; today[0] { return true }
        else if date[0] == today[0] &amp;&amp; date[1] &lt; today[1] { return true }
        else if date[0] == today[0] &amp;&amp; date[1] == today[1] &amp;&amp; date[2] &lt; today[2] { return true }
        else { return false }
    }

    var result: [Int] = []
    for (i, privacie) in privacies.enumerated() {
        let input = privacie.split(separator: &quot; &quot;).map{ String($0) }
        let (past, type) = (dateStringToIntArray(input[0]), input[1])
        if isDateOver(todays, past, type) {
            result.append(i+1)
        }
    }
    return result
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 33일차 TIL - 프로그래머스: 신규 아이디 추천(72410) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-33%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-33%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Fri, 29 Nov 2024 06:28:38 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/72410">72410</a></td>
<td align="center">신규 아이디 추천</td>
<td align="center">시뮬레이션</td>
<td align="center">Lv.1</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>특별히 문제를 해결하는 알고리즘은 없다. 단순히 주어진 요구사항을 구현하는 문제이다.</p>
<p>1 ~ 7단계 요구사항을 하나씩 구현해 주면 된다.</p>
<p>이때 문자열 또는 배열을 활용해야기 때문에 각자 사용 언어의 문법이 중요하다.</p>
<p>Swift 경우에는 아래와 같은 문법을 숙지하고 있다면 쉽게 해결할 수 있을 것이다.</p>
<ul>
<li><a href="https://developer.apple.com/documentation/swift/string/lowercased()">lowercased()</a></li>
<li><a href="https://developer.apple.com/documentation/swift/character/isletter">isLetter</a></li>
<li><a href="https://developer.apple.com/documentation/swift/character/isnumber">isNumber</a></li>
<li><a href="https://developer.apple.com/documentation/swift/array/contains(_:)">contains(_:)</a></li>
<li><a href="https://developer.apple.com/documentation/foundation/nsstring/1412937-replacingoccurrences">replacingOccurrences(of:with:)</a></li>
<li><a href="https://developer.apple.com/documentation/swift/string/hasprefix(_:)">hasPrefix(_:)</a></li>
<li><a href="https://developer.apple.com/documentation/swift/string/hassuffix(_:)">hasSuffix(_:)</a></li>
<li><a href="https://developer.apple.com/documentation/swift/array/removelast()">removeLast()</a></li>
<li><a href="https://developer.apple.com/documentation/swift/array/joined(separator:)-7uber">joined(separator:)</a></li>
</ul>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ new_id:String) -&gt; String {
    var id = new_id
    var newId = &quot;&quot;

    // 1단계 : new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
    id = id.lowercased()

    // 2단계 : new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
    for i in id {
        if i.isLetter || i.isNumber || i == &quot;-&quot; || i == &quot;_&quot; || i == &quot;.&quot; {
            newId.append(i)
        }
    }

    // 3단계 : new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
    while newId.contains(&quot;..&quot;) {
        newId = newId.replacingOccurrences(of: &quot;..&quot;, with: &quot;.&quot;)
    }

    // 4단계 : new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
    while newId.hasPrefix(&quot;.&quot;) {
        newId.removeFirst()
    }

    while newId.hasSuffix(&quot;.&quot;) {
        newId.removeLast()
    }

    // 5단계 new_id가 빈 문자열이라면, new_id에 &quot;a&quot;를 대입합니다.
    if newId.count == 0 {
        newId = &quot;a&quot;
    }

    // 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
    if newId.count &gt;= 16 {
        newId = Array(newId.map{String($0)})[0..&lt;15].joined()
    }
    if newId.hasSuffix(&quot;.&quot;) {
        newId.removeLast()
    }

    // 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
    while newId.count &lt; 3 {
        newId.append(newId.last!)
    }

    return newId
}</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>처음 보면 문제의 긴 글에 당황할 수 있지만 차근차근 해결하면 충분히 해결할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 32일차 TIL - 백준: 가장 긴 바이토닉 부분 수열(11054) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-32%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-32%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Thu, 28 Nov 2024 04:09:20 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/11054">11054</a></td>
<td align="center">가장 긴 바이토닉 부분 수열</td>
<td align="center">DP</td>
<td align="center">골드4</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>이 문제는 <a href="https://www.acmicpc.net/problem/11053">가장 긴 증가하는 부분 수열</a> 문제의 활용이라 보면 된다. 이 문제를 안 풀어 봤다면 먼저 풀어보고 오는 것을 추천한다.</p>
<p>위 문제를 해결하고 왔다면 DP(다이나믹 프로그래밍)를 활용해 <strong>가장 긴 증가하는 부분 수열</strong> 찾을 수 있을 것이다.</p>
<p>이 문제의 핵심 해결 아이디어는 <strong>오름 차순으로 증가하는 부분</strong>과 <strong>내림차순으로 감소하는 부분</strong>을 따로 구해 합하는 것이다.</p>
<p>Int 배열 <code>upCache</code>, <code>downCache</code>를 정의한다.</p>
<p><code>upCache</code>에 <strong>가장 긴 증가하는 부분 수열</strong>의 DP 테이블을 저장한다.
그리고 <code>downCache</code>에 <strong>가장 긴 감소하는 부분 수열</strong>의 DP 테이블을 저장하면 되는데, 필자는 입력되는 배열 <code>A</code>를 reverse 해서 <strong>가장 긴 증가하는 부분 수열</strong>의 DP 테이블을 구하고 테이블을 reverse 했다.</p>
<p><code>upCache</code>와 <code>downCache</code>의 각 인덱스를 더하면 <strong>증가하는 바이토닉 부분 수열</strong>의 dp 테이블을 얻을 수 있다. 이 테이블에서 max 값이 답이 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!
var A = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }

func dp(array: [Int]) -&gt; [Int] {
    var cache = Array(repeating: 1, count: N)
    for i in 0..&lt;N {
        for j in 0..&lt;i {
            if array[i] &gt; array[j] {
                cache[i] = max(cache[i], cache[j] + 1)
            }
        }
    }
    return cache
}

var upCache = dp(array: A)
A.reverse()
var downCache = dp(array: A)
downCache.reverse()

var maxResult = 0
for i in 0..&lt;N {
    maxResult = max(maxResult, upCache[i] + downCache[i] - 1)
}
print(maxResult)</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">N = int(input())
A = list(map(int, input().split()))

def dp(array):
    cache = [1] * N
    for i in range(N):
        for j in range(i):
            if A[i] &gt; A[j]:
                cache[i] = max(cache[i], cache[j] + 1)
    return cache

upCache = dp(A)
A.reverse()
downCache = dp(A)
downCache.reverse()

maxResult = 0
for i in range(N):
    maxResult = max(maxResult, upCache[i] + downCache[i] - 1)
print(maxResult)</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>이전에 연습했던 문제를 통해 아무 도움 없이 문제를 해결할 수 있었다!! 역시 차근차근 문제를 해결해 나가니 성장하는 것 같다. 앞으로도 파이팅!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 31일차 TIL - 백준: 줄세우기(2631) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-31%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-31%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Wed, 27 Nov 2024 09:50:11 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/2631">2631</a></td>
<td align="center">줄세우기</td>
<td align="center">DP</td>
<td align="center">골드4</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>이 문제는 결국 <a href="https://www.acmicpc.net/problem/11053">가장 긴 증가하는 부분 수열</a> 찾기이다!</p>
<p>이미 오름 차순으로 정렬된 번호는 그대로 두고 나머지 번호들을 옮기면 된다.</p>
<p>그래서 가장 긴 증가하는 부분 수열의 길이를 찾아 N에서 빼주면 답이 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!
var people: [Int] = []
for _ in 0..&lt;N {
    people.append(Int(readLine()!)!)
}

var dp: [Int] = Array(repeating: 1, count: N)
for i in 0..&lt;N {
    for j in 0..&lt;i {
        if people[i] &gt; people[j] {
            dp[i] = max(dp[i], dp[j] + 1)
        }
    }
}

print(N - dp.max()!)</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">N = int(input())
people = []
for _ in range(N):
    people.append(int(input()))

dp = [1] * N
for i in range(N):
    for j in range(i):
        if people[i] &gt; people[j]:
            dp[i] = max(dp[i], dp[j] + 1)

print(N - max(dp))</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>핵심만 캐치 했으면 아주 쉽게 해결할 수 있는 문제였다. 하지만 빠르게 캐치하지 못해서 아쉽다. 더 많은 문제를 경험해 보자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 30일차 TIL - 백준: 상자넣기(1965) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-30%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-30%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Tue, 26 Nov 2024 05:24:13 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/1965">1965</a></td>
<td align="center">상자넣기</td>
<td align="center">DP</td>
<td align="center">실버2</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>지금 상자에 앞(왼쪽)에 상자들이 몇 개 들어올 수 있는지 확인하면 된다.</p>
<p>하지만 그냥 계산하면 중복 연산이 많기 때문에 DP(다이나믹 프로그래밍)을 사용한다.</p>
<p>dp 테이블을 정의하고 상자를 차례로 접근한다. 현재 접근 중인 상자 앞(왼쪽)에 현재 상자 크기 보다 작은게 있다면 그 상자(작은 상자)의 dp 값에 1을 더한다.</p>
<p>앞에 작은 상자가 여개 일 수도 있으니 모두 같은 연산을 하고 그중 최댓값을 현재 dp에 저장한다.</p>
<p>그리고 dp 테이블에서 최댓값을 찾으면 답이 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!
let nums = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }

var dp: [Int] = Array(repeating: 0, count: N)
for i in stride(from: 0, to: N, by: 1) {
    var max = 1
    for j in stride(from: 0, to: i, by: 1) {
        if nums[i] &gt; nums[j] {
            let num = dp[j]+1
            if max &lt; num { max = num }
        }
    }
    dp[i] = max
}

print(dp.max()!)</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">n = int(input())
nums = list(map(int, input().split(&quot; &quot;)))

dp = [0] * n
for i in range(n):
    maxNum = 1
    for j in range(0, i):
        if nums[i] &gt; nums[j]:
            num = dp[j] + 1
            if num &gt; maxNum: maxNum = num
    dp[i] = maxNum

print(max(dp))</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>오늘도 해결하기 쉬운 문제가 나왔다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 29일차 TIL - 백준: 파도반 수열(9461) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-29%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-29%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Mon, 25 Nov 2024 11:05:52 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/9461">9461</a></td>
<td align="center">파도반 수열</td>
<td align="center">DP</td>
<td align="center">실버3</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>P(1)부터 P(10)까지 첫 10개 숫자 <code>1, 1, 1, 2, 2, 3, 4, 5, 7, 9</code> 에서 점화식을 찾으면 매우 쉽게 해결할 수 있다.</p>
<p>유심히 봐보면 다음과 같은 점화식을 만들 수 있다. <strong><code>P(N) = P(N-2) + P(N-2)</code></strong></p>
<p>위 점화식으로 dp 테이블을 채우고 테스트 케이스를 출력하면 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!
var dp = [1, 1, 1, 2, 2, 3, 4, 5, 7, 9] + Array(repeating: 0, count: 90)

for i in stride(from: 10, to: 100, by: 1) {
    dp[i] = dp[i-2] + dp[i-3]
}

for _ in 0..&lt;N {
    print(dp[Int(readLine()!)!-1])
}</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">N = int(input())
dp = [1, 1, 1, 2, 2, 3, 4, 5, 7, 9] + [0] * 90

for i in range(10, 100):
    dp[i] = dp[i-2] + dp[i-3]

for _ in range(N):
    print(dp[int(input())-1])</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>오늘은 해결하기 쉬운 문제가 나왔다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 28일차 TIL - 백준: 가장 큰 증가하는 부분 수열(11055) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-28%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-28%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Sun, 24 Nov 2024 05:59:41 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/11055">11055</a></td>
<td align="center">가장 큰 증가하는 부분 수열</td>
<td align="center">DP</td>
<td align="center">실버2</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>수열을 순서대로 방문해서 방문 중인 수 기준으로 왼쪽에 있는 수들 중 본인보다 작은 수의 dp 테이블 값에 본인 값(방문 중인 수)을 더해 본인 순서 dp 테이블에 저장하면 된다.</p>
<p>방문 중인 수 왼쪽에 작은 수가 여러 개 있으면 합이 가장 큰 것을 dp 테이블에 저장하면 된다. </p>
<p>그리고 dp 테이블에서 최댓값을 출력하면 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!
let nums = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }

var dp = nums
for i in 0..&lt;N {
    for j in 0..&lt;i {
        if nums[j] &lt; nums[i] {
            dp[i] = max(dp[i], dp[j]+nums[i])
        }
    }
}

print(dp.max()!)</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">N = int(input())
nums = list(map(int, input().split(&quot; &quot;)))

dp = [] + nums
for i in range(N):
    for j in range(0, i):
        if nums[j] &lt; nums[i]:
            dp[i] = max(dp[i], dp[j]+nums[i])

print(max(dp))</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>DP는 문제 풀이에 비해 설명하는 것이 어려운 것 같다. 누군가에게 알려준다고 생각하듯이 연습하자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 27일차 TIL - 백준: 가장 긴 감소하는 부분 수열(11722) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-27%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-27%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Sun, 24 Nov 2024 01:27:21 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/11722">11722</a></td>
<td align="center">가장 긴 감소하는 부분 수열</td>
<td align="center">DP</td>
<td align="center">실버2</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>수열에서 i번째 수 보다 0~(i-1)번째 수에서 더 큰 값이 있다면 해당 수의 부분 수열의 길이에 +1 해주면 된다.</p>
<p>DP 테이블을 N 길이 만큼 1로 초기화 한다. 1로 초기화 하는 이유는 부분 수열의 초소 길이가 자기 자신 1개이기 때문이다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!
var nums = readLine()!.split(separator: &quot; &quot;).map{ Int($0)! }

var dp = Array(repeating: 1, count: N)
for i in 0..&lt;N {
    for j in 0..&lt;i {
        if nums[i] &lt; nums[j] {
            dp[i] = max(dp[i], dp[j]+1)
        }
    }
}

print(dp.max()!)</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>어렵진 않은 문제인데 뭔가 기존에 풀었던 DP문제와 조금 달라 빠르게 풀지 못 했다. 조금 더 다양한 문제를 풀어보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 26일차 TIL - 백준: 돌 게임(9655) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-26%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-26%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Fri, 22 Nov 2024 07:20:27 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/9655">9655</a></td>
<td align="center">돌 게임</td>
<td align="center">DP</td>
<td align="center">실버5</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>규칙만 찾으면 매우 간단한 문제이다.</p>
<p>두 가지 방법으로 해결할 수 있다.</p>
<blockquote>
<p><strong>방법 1 : 홀수짝수</strong></p>
</blockquote>
<p>직접 주어진 규칙에 따라 이기는 사람을 찾아보면 N이 홀수일 때는 상근이가, 짝수일 때는 창영이가 이기는 것을 알 수 있다.</p>
<blockquote>
<p><strong>방법 2 : DP</strong></p>
</blockquote>
<p>DP의 점화식은 <code>dp[N] = dp[N-3] 또는 dp[N-1]의 반대</code> 이다. 아래 예제로 살펴보자.</p>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/6ed31c70-bf18-49a8-b0e6-bc9a721ccb4f/image.png" alt=""></p>
<p>N이 4일 때 <code>dp[4]</code>의 값은 <code>dp[3]</code>과 <code>dp[1]</code>의 반대 값이다.</p>
<p><img src="https://velog.velcdn.com/images/rayleigh_/post/30cb7c0f-f37d-4695-afd9-b8717e8c7495/image.png" alt=""></p>
<p>N이 5일 때 <code>dp[5]</code>의 값은 <code>dp[4]</code>과 <code>dp[2]</code>의 반대 값이다.</p>
<p>위 예제는 돌을 1개씩 가져간 경우이지만 3개씩 가져간 경우도 해보면 동일한 규칙이다.</p>
<p>그래서 아래와 같이 두 가지 방법으로 문제를 해결할 수 있다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">// 방법 1 : 홀짝
Int(readLine()!)!%2 == 0 ? print(&quot;CY&quot;) : print(&quot;SK&quot;)

// 방법 2 : DP
let N = Int(readLine()!)!

var dp = Array(repeating: 0, count: 1000)
dp[0] = 1
dp[1] = 2
dp[2] = 1

if N &gt; 2 {
    for i in 3..&lt;N {
        if dp[i-1] == 1 || dp[i-3] == 1 { dp[i] = 2 }
        else { dp[i] = 1 }
    }
}

dp[N-1] == 1 ? print(&quot;SK&quot;) : print(&quot;CY&quot;)</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python"># 방법 1 : 홀짝
print(&quot;CY&quot;) if int(input())%2 == 0 else print(&quot;SK&quot;)

# 방법 2 : DP
N = int(input())

dp = [0] * 1000
dp[0] = 1
dp[1] = 2
dp[2] = 1

for i in range(3, N):
    if dp[i-1] == 1 or dp[i-3] == 1: dp[i] = 2
    else: dp[i] = 1

print(&quot;SK&quot;) if dp[N-1] == 1 else print(&quot;CY&quot;)</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<h3 id="python-삼항-연산자">Python 삼항 연산자</h3>
<pre><code class="language-python">[참일때] if [조건문] else [거짓일때]</code></pre>
<p>파이썬의 삼항 연산자는 위와 같은 형태이다. 보편적인 <code>[조건문] ? [참일때] : [거짓일때]</code> 형태와 다르다. 잘 기억해두자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 25일차 TIL - 백준: 주사위 쌓기(2116) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-25%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-25%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Thu, 21 Nov 2024 12:31:53 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">백준</td>
<td align="center"><a href="https://www.acmicpc.net/problem/2116">2116</a></td>
<td align="center">주사위 쌓기</td>
<td align="center">완전탐색</td>
<td align="center">골드5</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>이 문제를 처음 읽어보면 움칫한다. (어떻게 하라는 걸까?)</p>
<p>특별한 것은 없다. <strong>완전탐색(브루트포스)</strong>로 모든 경우의 수를 확인하면 된다.</p>
<p>가장 중요한 것은 1번(가장 아래) 주사위이다. 그래서 1번 주사위의 모든 각 면이 바닥을 향할 때 규칙에 맞게 주사위를 쌓고 기둥 한 면의 최댓값을 구하면 된다.</p>
<p><strong>[5개 주사위 예제]</strong></p>
<ol>
<li>1번 주사위의 0번 인덱스 숫자를 바닥면으로 정한다.</li>
<li>1번 주사위의 윗면 숫자를 구한다.</li>
<li>1번 주사위의 사이드(바닥,위면 제외) 숫자들을 구해 sides 배열 저장한다.
(반복문 2번~5번 주사위)</li>
<li>2번 주사위의 바닥 숫자는 1번 주사위의 윗면 숫자이다.</li>
<li>2번 주사위의 윗면 숫자를 구한다.</li>
<li>2번 주사위의 사이드 숫자들을 구해 sides 배열에 저장한다.
(3~5번 주사위도 위와 같이 반복하여 사이드 숫자들을 구한다)</li>
</ol>
<p>그러면 sides에는 [1번 주사위 사이드, 2번 주사위 사이드, 3번 주사위 사이드 ...]가 저장 된다.</p>
<p>이제 각 주사위 사이드에서 최대값을 골라낸다.
[1번 사이드 최대값, 2번 사이드 최대값, 3번 사이드 최대값 ...] 이를 모두 더하면 답이 된다!!</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">let N = Int(readLine()!)!

var dices: [[Int]] = []
for _ in 0..&lt;N {
    dices.append(readLine()!.split(separator: &quot; &quot;).map{ Int($0)! })
}

// 주사위의 반대편 숫자를 구하는 함수
func getOppositeNum(currentNum: Int, dice: [Int]) -&gt; Int {
    let idx = dice.firstIndex(of: currentNum)
    switch idx {
    case 0: return dice[5]
    case 1: return dice[3]
    case 2: return dice[4]
    case 3: return dice[1]
    case 4: return dice[2]
    case 5: return dice[0]
    default: return 0
    }
}

// 주사위에서 밑면, 위면을 제외한 사이드 숫자들을 구하는 함수
func getSideNums(bottomNum: Int, upperNum: Int, dice: [Int]) -&gt; [Int] {
    var pDice = dice
    pDice.remove(at: pDice.firstIndex(of: bottomNum)!)
    pDice.remove(at: pDice.firstIndex(of: upperNum)!)
    return pDice
}

var result: [Int] = []
for i in 0..&lt;6 {
    var sides: [[Int]] = []
    var bottomNum = dices[0][i]
    var upperNum = getOppositeNum(currentNum: bottomNum, dice: dices[0])
    sides.append(getSideNums(bottomNum: bottomNum, upperNum: upperNum, dice: dices[0]))

    for j in 1..&lt;N {
        bottomNum = upperNum
        upperNum = getOppositeNum(currentNum: bottomNum, dice: dices[j])
        sides.append(getSideNums(bottomNum: bottomNum, upperNum: upperNum, dice: dices[j]))
    }
    result.append(sides.map{ $0.max()! }.reduce(0, +))
}

print(result.max()!)</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>처음에는 복잡해 보여 당황했지만 규칙에 맞게 해보니 생각하는 데로 풀렸다. 당황하지 말고 성실하게 풀자!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 24일차 TIL - 프로그래머스: 전력망을 둘로 나누기(86971) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-24%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-24%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Wed, 20 Nov 2024 07:03:07 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/86971">86971</a></td>
<td align="center">전력망을 둘로 나누기</td>
<td align="center">완전탐색</td>
<td align="center">Lv.2</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>아이디어는 간단하다. 직접 전선을 하나씩 끊어 보면서 <strong>두 전력망의 송전탑 개수의 차이</strong>를 구하면 된다. 즉, 완전탐색이다.</p>
<p>전선(간선)을 하나씩 제거하기 위해 wires 요소들을 순서대로 한 개씩 제거하고 (두 개의 전력망을 가진) 그래프로 만들었다. 그리고 그 그래프를 <strong>DFS</strong>를 통해 탐색하여 두 전력망의 송전탑 개수의 차이를 구했다.</p>
<p>이후 송전탑 개수의 차이 중에 <strong>최소</strong>를 반환하면 된다!</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ n:Int, _ wires:[[Int]]) -&gt; Int {    
    var result: [Int] = []
    for i in 0..&lt;(n-1) {
        // 간선을 하나 제거하고 그래프를 만든다(전선 끊기)
        var graph: [[Int]] = Array(repeating: [], count: n+1)
        for (j, wire) in wires.enumerated() {
            if i == j { continue }
            graph[wire[0]].append(wire[1])
            graph[wire[1]].append(wire[0])
        }

        // DFS로 연결된 송전탐의 개수를 구한다
        var visited = Array(repeating: false, count: n+1)
        func dfs(_ v: Int, _ count: Int) -&gt; Int {
            visited[v] = true
            var nCount = count+1
            for k in graph[v] {
                if !visited[k] {
                    nCount = dfs(k, nCount)
                }
            }
            return nCount
        }

        // 그래프를 탐색한다
        // 간선(전선)을 하나 끊었으므로 counts에는 2개가 추가 된다
        var counts: [Int] = []
        for t in 1...n {
            if !visited[t] {
                counts.append(dfs(t, 0))
            }
        }
        result.append(abs(counts[0]-counts[1]))
    }
    return result.min()!
}</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<p>처음에는 복잡해 보여 당황했지만 막상 해보니 생각하는 데로 바로 풀렸다. 다만 코드가 길어지다 보니 인덱스 범위 실수가 잦았다. 더 집중해서 신속하게 풀어보자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 23일차 TIL - 프로그래머스: 소수 찾기(42839) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-23%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-23%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Tue, 19 Nov 2024 05:13:50 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42839">42839</a></td>
<td align="center">소수 찾기</td>
<td align="center">완전탐색</td>
<td align="center">Lv.2</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>숫자 종이 개수가 최대 7로 경우의 수가 많지 않아 완전탐색으로 진행했다.</p>
<p><strong>DFS</strong>로 숫자 종이로 만들 수 있는 숫자의 모든 경우를 탐색했다. 탐색하면서 해당 숫자가 소수인지를 확인하여 <code>result</code> Set 자료형(중복이 있기 때문)에 담았다.</p>
<p>소수를 판별하는 함수를 직접 구현해야 한다. 가장 기본적인 방법으로 구현했다. (<strong><code>O(N)</code></strong>)</p>
<p>결국 result에 담긴 요소의 개수가 답이 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ numbers:String) -&gt; Int {
    let nums = numbers.map{ String($0) }

    func isPrimeNum(_ n: [String]) -&gt; Bool {
        guard let num = Int(n.joined()) else { return false }
        if num &lt;= 1 { return false }
        if num &lt;= 3 { return true }
        if num % 2 == 0 { return false }
        for i in 2..&lt;sqrt(num) {
            if num % i == 0 { return false }
        }
        return true
    }

    var result: Set&lt;Int&gt; = []
    var visited = Array(repeating: false, count: nums.count)

    func dfs(_ nnum: [String]) {
        for (i, num) in nums.enumerated() {
            if nnum.isEmpty &amp;&amp; num == &quot;0&quot; { continue }
            var newNum = nnum + [num]
            if !visited[i] {
                visited[i] = true
                if isPrimeNum(newNum) {
                    result.insert(Int(newNum.joined())!)
                }
                dfs(newNum)
                visited[i] = false
            }
        }
    }
    dfs([])
    return result.count
}</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<h3 id="소수prime-number-판별">소수(Prime Number) 판별</h3>
<p>이번에는 가장 기본적인 소수 판별 알고리즘을 사용했다. 하지만 O(N)으로 판발하려는 숫자가 클수록 비효율적이다.</p>
<p>그래서 <strong>에라토스테네스의 체</strong>와 같은 알고리즘이 존재한다. 시간초과를 대비하여 학습해 두자.</p>
<p><a href="https://kbhetrr.dev/blog/primality-test/">참고 : 어떤 수가 소수(Prime Number)인지 아닌지 판별하는 다양한 알고리즘</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 22일차 TIL - 프로그래머스: 피로도(87946) Swift]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-22%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-22%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Mon, 18 Nov 2024 13:09:46 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/87946">87946</a></td>
<td align="center">피로도</td>
<td align="center">완전탐색</td>
<td align="center">Lv.2</td>
<td align="center">Swift</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>던전의 개수가 최대 8로 경우의 수가 많지 않고 특별한 규칙이 없기 때문에 완전탐색으로 할만하다.</p>
<p><strong>DFS</strong>로 탐색했으며 탐색하면서 피로도를 계산하여 던전을 탐험할 수 있는지 확인하고 탐험한 최대 던전 수를 구하면 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ k:Int, _ dungeons:[[Int]]) -&gt; Int {
    var visited = Array(repeating: false, count: dungeons.count)
    func dfs(_ k: Int, _ count: Int, _ maxCount: Int) -&gt; Int {
        var mc = maxCount
        for (i, dungeon) in dungeons.enumerated() {
            if !visited[i] &amp;&amp; k &gt;= dungeon[0] {
                visited[i] = true
                mc = dfs(k-dungeon[1], count+1, mc)
                visited[i] = false
            } 
        }
        return max(mc, count)
    }
    return dfs(k, 0, 0)
}</code></pre>
<h2 id="🤔">🤔</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 21일차 TIL - 프로그래머스: 카펫(42842) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-21%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-21%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Sun, 17 Nov 2024 10:50:19 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42842">42842</a></td>
<td align="center">카펫</td>
<td align="center">완전탐색</td>
<td align="center">Lv.2</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>완전탐색으로 카펫의 최소 높이(3)부터 1씩 증가시키면서 yellow 개수가 실제 개수와 일치할 때까지 탐색한다. </p>
<p>yellow는 1이상이므로 카펫의 전체 높이는 3 이상이다. 그래서 초기 <code>height</code>를 <code>3</code>으로 정의한다.
카펫의 <code>width</code>는 <code>(brown + yellow)/height</code>로 계산할 수 있다.</p>
<p>반복문을 돌면서 yellow 개수를 구하고(<code>(width-2) * (height-2)</code>) 일치하다면 반복문 종료, 아니면 높이를 1 증가시키고 width를 다시 계산한다.</p>
<p>이 과정을 반복하면 답을 구할 수 있다. 즉, 카펫의 최소 높이부터 격자의 개수를 계산하며 탐색하는 것이다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ brown:Int, _ yellow:Int) -&gt; [Int] {
    var height = 3
    var width =  (brown + yellow)/height
    while true {
        if (width-2) * (height-2) == yellow { break }
        height += 1
        width = (brown + yellow)/height
    }
    return [width, height]
}</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">def solution(brown, yellow):
    height = 3
    width = (brown+yellow)/height
    while True:
        if (width-2) * (height-2) == yellow: break
        height += 1
        width = (brown+yellow)/height

    return [width, height]</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<h3 id="첫-시도의-반례">첫 시도의 반례</h3>
<p>처음에는 아래와 같이 풀이했다. 기본 테스트 케이스는 통과했지만 제출 채점은 통과할 수 없었다.</p>
<pre><code class="language-python">def solution(brown, yellow):
    yellowX = yellow
    yellowY = 1
    while yellowX &gt;= yellowY:
        if yellowX*2 + yellowY*2 + 4 == brown:
            break
        else:
            yellowX /= 2
            yellowY *= 2

    return [yellowX+2, yellowY+2]</code></pre>
<p>이것에 대한 반례로 <code>Parameters(brown: 24, yellow: 25)</code>, <code>Return([7, 7])</code>가 있다.
즉, 위의 코드는 높이가 짝수인 경우만 탐색하므로 답을 찾을 수 없다.</p>
<p>반례를 찾고 생각하며 문제를 해결해 보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[99클럽 코테 스터디 4기 20일차 TIL - 프로그래머스: 모의고사(42840) Swift & Python]]></title>
            <link>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-20%EC%9D%BC%EC%B0%A8-TIL</link>
            <guid>https://velog.io/@rayleigh_/99%ED%81%B4%EB%9F%BD-%EC%BD%94%ED%85%8C-%EC%8A%A4%ED%84%B0%EB%94%94-4%EA%B8%B0-20%EC%9D%BC%EC%B0%A8-TIL</guid>
            <pubDate>Sat, 16 Nov 2024 07:54:57 GMT</pubDate>
            <description><![CDATA[<h2 id="ℹ️-문제-정보">ℹ️ 문제 정보</h2>
<table>
<thead>
<tr>
<th align="center">플랫폼</th>
<th align="center">번호</th>
<th align="center">제목</th>
<th align="center">유형</th>
<th align="center">난이도</th>
<th align="center">언어</th>
</tr>
</thead>
<tbody><tr>
<td align="center">프로그래머스</td>
<td align="center"><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42840">42840</a></td>
<td align="center">모의고사</td>
<td align="center">완전탐색</td>
<td align="center">Lv.1</td>
<td align="center">Swift, Python</td>
</tr>
</tbody></table>
<h2 id="🚀-나의-접근-방법">🚀 나의 접근 방법</h2>
<p>다 탐색을 하는 거라 특별한 알고리즘은 없다. 얼마나 간결하게 코드를 작성하느냐가 중요하다.</p>
<blockquote>
<p>1번 수포자가 찍는 방식 : 1, 2, 3, 4, 5 ... 반복 <strong>(5개)</strong>
2번 수포자가 찍는 방식 : 2, 1, 2, 3, 2, 4, 2, 5 ... 반복 <strong>(8개)</strong>
3번 수포자가 찍는 방식 : 3, 3, 1, 1, 2, 2, 4, 4, 5, 5 ... 반복 <strong>(10개)</strong></p>
</blockquote>
<p>문제 정답(<code>answers</code>)이 리스트로 주어졌다. 그리고 <code>answers</code>의 각 index로 <strong><code>index%(반복되는 답 개수)</code></strong>를 계산하여 각 수포자가 찍는 답을 알 수 있다.
<strong>⬇️ 예시</strong></p>
<pre><code class="language-python">pick = [
        [1, 2, 3, 4, 5],
        [2, 1, 2, 3, 2, 4, 2, 5],
        [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    ]
for i, answer in enumerate(answers):
    if answer == pick[0][i%5]: result[0][1] += 1
    if answer == pick[1][i%8]: result[1][1] += 1
    if answer == pick[2][i%10]: result[2][1] += 1</code></pre>
<p>그리고 조건에 맞게 가장 많은 문제를 맞힌 사람을 return하면 된다.</p>
<h2 id="✍️-나의-코드">✍️ 나의 코드</h2>
<h3 id="swift">Swift</h3>
<pre><code class="language-swift">import Foundation

func solution(_ answers:[Int]) -&gt; [Int] {
    let pick = [
        [1, 2, 3, 4, 5],
        [2, 1, 2, 3, 2, 4, 2, 5],
        [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    ]

    var result: [(Int, Int)] = [(1, 0), (2, 0), (3, 0)]
    for (j, ans) in answers.enumerated() {
        if ans == pick[0][j%5] { result[0].1 += 1 }
        if ans == pick[1][j%8] { result[1].1 += 1 }
        if ans == pick[2][j%10] { result[2].1 += 1 }
    }

    return result.filter{$0.1 == result.max{$0.1 &lt; $1.1}!.1}.map{$0.0}
}</code></pre>
<h3 id="python">Python</h3>
<pre><code class="language-python">def solution(answers):
    pick = [
        [1, 2, 3, 4, 5],
        [2, 1, 2, 3, 2, 4, 2, 5],
        [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    ]

    result = [[1, 0], [2, 0], [3, 0]]
    for i, answer in enumerate(answers):
        if answer == pick[0][i%5]: result[0][1] += 1
        if answer == pick[1][i%8]: result[1][1] += 1
        if answer == pick[2][i%10]: result[2][1] += 1

    return list(map(lambda item: item[0], list(filter(lambda item: item[1] == max(result, key=lambda item: item[1])[1], result))))</code></pre>
<h2 id="🤔-회고">🤔 회고</h2>
<h3 id="고차함수-남용">고차함수 남용</h3>
<p>python 마지막 줄을 보면 고차함수가 매우 복잡하게 섞여있다. 저 정도면 그냥 반복문으로 하는것이 더욱 가독성이 좋을것 같다.</p>
<h3 id="swift와-python에서-tuple의-차이점">Swift와 Python에서 Tuple의 차이점</h3>
<ul>
<li>swift 튜플의 요솟값은 변화 가능하다.</li>
<li>python 튜플의 요솟값은 변화가 불가능하다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>