<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>prairie_sky.log</title>
        <link>https://velog.io/</link>
        <description>AI researcher</description>
        <lastBuildDate>Sat, 08 Apr 2023 16:05:52 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>prairie_sky.log</title>
            <url>https://images.velog.io/images/prairie_sky/profile/82bdca19-2da5-4a43-a799-044316478595/KakaoTalk_20210620_235937698.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. prairie_sky.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/prairie_sky" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Loss Functions and Optimization]]></title>
            <link>https://velog.io/@prairie_sky/Loss-Functions-and-Optimization</link>
            <guid>https://velog.io/@prairie_sky/Loss-Functions-and-Optimization</guid>
            <pubDate>Sat, 08 Apr 2023 16:05:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>CS231n 강의 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h3 id="참조">참조</h3>
<p><a href="https://www.youtube.com/playlist?list=PL3FW7Lu3i5JvHM8ljYj-zLfQRF3EO8sYv">CS231n 유튜브 강의</a>
<a href="http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture3.pdf">CS231n 강의 노트</a>
<a href="https://doromi.tistory.com/112?category=849309">https://doromi.tistory.com/112?category=849309</a></p>
<hr>

<h1 id="loss-functions-and-optimization">Loss Functions and Optimization</h1>
<h2 id="reminder-previous-lecture">Reminder Previous Lecture<img src="https://velog.velcdn.com/images/prairie_sky/post/4b164ec0-7eb8-4d92-866f-4f8624e58af8/image.png" alt=""></h2>
<p>Linear Classification은 위와 같이 입력 이미지와 W값의 곱으로 생각할 수 있다. 이 결과는 클래스의 개수와 같은 차원을 가진다. 이 중 가장 큰 결과값을 가지는 클래스로 예측한다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/957596b1-21d2-41a3-98e8-0a5ea96aeac7/image.png" alt="">다음은 가중치 W값을 랜덤으로 설정한 뒤 3개의 이미지에서 얻은 결과이다. 이 중 2가지는 가장 큰 값이 나타나는 예측된 클래스가 정답 클래스와 일치하지 않은 것을 확인할 수 있다. 그렇다면 올바른 가중치 W값을 어떻게 찾는 것일까? </p>
<br>

<h2 id="loss-function">Loss Function</h2>
<p><strong>Loss Function:</strong> 손실함수라고 불리며, 현재 사용하고 있는 이미지 분류기(모델)가 얼마 만큼의 손실을 가지고 있는지를 나타내는 함수이다.<img src="https://velog.velcdn.com/images/prairie_sky/post/1f3f23ba-21bb-4b24-a69a-47b2ec48f650/image.png" alt="">어떤 Loss Function을 $$L_{i}$$라고 하자. 각 N개의 데이터에서 구해지는 손실값들을 더한 뒤 N으로 나눈 평균값을 Loss 값으로 사용하는 것을 확인할 수 있다. $$L_{i}$$ 함수에는 어떤 종류가 있는지 알아보자.</p>
<br>

<h3 id="multiclass-svm-loss">Multiclass SVM loss<img src="https://velog.velcdn.com/images/prairie_sky/post/189bb56d-226d-4977-ab4a-365e52610a3c/image.png" alt=""></h3>
<p>Multiclass SVM loss를 설명하자면 다음과 같다.</p>
<ul>
<li>Linear Classification인 $$f(x_{i}, W)$$ 에서 나온 결과를 $$s$$ 라고 하자.</li>
<li>정답인 클래스의 $$s$$ 값을 $$s_{y_{i}}$$라고 하고 나머지 클래스와 이 값을 비교한다.</li>
<li>정답인 클래스와 나머지를 비교했을 때, 정답보다 다른 클래스의 점수가 더 높다면 이 차이만큼이 Loss인 것이다.</li>
<li>위에서 구한 Loss값에서 <strong>safety margin</strong>이라는 값을 추가한다. 이는 정답 클래스가 적어도 다른 클래스보다 <strong>safety margin</strong> 값 만큼은 커야 한다는 의미이며 본 예시에서 <code>safety margin = 1</code> 이다.</li>
<li>Loss 값이 0보다 작은 음수 값인 경우에는 포함하지 않는다.</li>
<li>위 그래프에서 가로축은 $$s_{y_{i}}$$ 값이고 세로축은 $$L_{i}$$의 값인 Loss 값을 표현하였다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/c9ad91a7-d4b2-43a7-81d1-66578eb09cec/image.png" alt="">다음은 3개의 그림에 대한 Linear Classification 결과이다.
이 중 고양이 사진에 대한 Loss Function을 계산해보았다.
고양이는 3.2값을 가지며 나머지 자동차와 개구리에 대한 Loss 값은 다음과 같다.</p>
<ul>
<li>Loss(class:<code>cat</code>) = 0</li>
<li>Loss(class:<code>car</code>) = max(0, 5.1-3.2+1) = 2.9</li>
<li>Loss(class:<code>frog</code>) = max(0, -1.7-3.2+1) = 0
고양이 사진의 전체 Loss = 0 + 2.9 + 0 = 2.9</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/9e65e763-a935-499e-8a59-84610f63c395/image.png" alt=""> 나머지 두 사진도 위와 같은 방법으로 계산한다. 이 Loss 값들을 모두 더하고 사진 개수 만큼 나눈 값을 <strong>Multiclass SVM loss</strong> 라고 한다.</p>
<br>

<p><span style="color:red"><strong>Multiclass SVM loss의 특징</strong></span></p>
<ul>
<li>정답 스코어가 <code>safety margin = 1</code> 을 만족하는 범위라면 Loss 값에 변화를 주지 않는다.</li>
<li>만약 Loss 값이 0이라고 할 때, <code>W: weight parameter</code> 값에 임의의 상수를 곱해도 Loss 값은 0이다.</li>
<li>위 점에서 Multiclass SVM loss는 유일하지 않다.</li>
<li>모든 $$s$$값이 0이라고 하면 <code>Loss = class 수 - 1</code> 값을 가진다. 이러한 특성은 Loss function의 작동을 Debug 하기에 적절하다.</li>
<li>Loss의 최솟값은 0이며 최대값은 무한대이다. </li>
</ul>
<br>

<h3 id="regularization">Regularization</h3>
<p>그렇다면 Loss function의 값이 줄어들수록 좋은 성능을 가질까? 
정답은 &#39;좋을 수도 있고 아닐 수도 있다&#39; 이다.</p>
<p>Loss가 줄어든다는 것은 <code>Train</code> 데이터에 대해서 좋은 성능을 가지게 된다는 뜻이다.
하지만 이것은 <code>Test</code> 데이터에 대해 좋은 성능을 가진다는 것을 보장해 주지 않는다.
이 문제와 관련된 것이 바로 <strong>overfitting(과적합)</strong> 이다.</p>
<p><strong>overfitting</strong>이란 Train 데이터에 대해서는 좋은 성능을 가지도록 학습되지만, Test 데이터에 대해서는 오히려 성능이 떨어지는 현상을 말한다.</p>
<p>그렇다면 이 문제를 어떻게 해결해야 할까? 정답은 <code>Regularization</code> 에 있다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/4eb3307a-3354-4dd1-ae81-59ef28423592/image.png" alt=""> <strong>Regularization</strong> 은 W 값에 제약을 가한다. 위 그림을 보면 파란색은 Train 데이터, 초록색은 Test 데이터이다. 예측한 파란색 선은 Train 데이터에 overfitting 되어 있는 것을 확인할 수 있다. </p>
<p>W의 값이 복잡한 값을 가지지 않게 하기 위해, <strong>W 값에 대해서 평가하는 함수를 추가하는 것</strong>을 <code>Regularization</code> 이라고 한다. Regularization 을 통해 모델은 더 단순한 W를 선택할 수 있다. <strong>(모델에 soft한 제약을 줌, penalty)</strong></p>
<ul>
<li>&quot;weight decay&quot; : 특정 가중치가 비이상적으로 커지는 것을 방해하는것 이다.</li>
<li>&quot;local noise&quot;와 outlier(특이점)의 영향을 적게 받도록 한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/43a9d566-a590-40ab-857d-f4622838a72b/image.png" alt=""> 아래는 Regularization 에서 사용하는 function의 예시이다. 먼저 <strong>$$\lambda$$: Regularization strength</strong> 는 Regularization 값을 어느 정도로 사용할지를 정하는 값이고 그 이후 나오는 <strong>$$R(W)$$</strong> 는 Regularization 함수이다. 종류는 <code>L2 regularization</code>, <code>L1 regularization</code>, <code>Batch normalization</code>, <code>Elastic net</code>, <code>Dropout</code>, <code>Stochastic depth</code> 등 다양한 Regularization 방법이 있다.</p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/60f83235-afdd-4f66-b82a-2518d90dde2d/image.png" alt=""> Train 데이터 $$x$$가 있고 서로 다른 $$w$$ 행렬 $$\omega_{1}$$과 $$\omega_{2}$$가 있다. $x$와 $w$의 내적을 구함으로써 Linear classification을 수행할 수 있다. Linear Classification 관점에서 $$\omega_{1}$$과 $$\omega_{2}$$는 같다. </p>
<p><strong>$L_{1}$ 에서는 $$\omega_{1}$$ 을 선호한다.</strong> 왜냐하면, $L_{1}$ 은 행렬에서 0이 아닌 요소가 많을 때 복잡하다고 생각한다.</p>
<p><strong>$L_{2}$ 에서는 $$\omega_{2}$$ 을 선호한다.</strong> 왜냐하면, $L_{2}$는 분류기의 복잡도를 각 값들이 얼마나 차이가 없는지로 비교하기 때문이다. Linear Classification에서 W는 얼마나 $x$가 output class와 비슷한지를 계산한다. 따라서 $L_{2}$는 변동이 심한 어떤 입력 $x$가 있고 그 특정요소에 의존하기 보다는 모든 $x$의 요소가 골고루 영향을 미치길 원할 때 사용한다.</p>
<blockquote>
<p>어떤 문제를 가지고 있을 때, 그 문제에서 &#39;복잡하다&#39;를 어떻게 정의할 것인지를 고민하여 적절한 Regularization을 사용하는 것이 중요하다.</p>
</blockquote>
<p>+) <strong>L1 regularization</strong>을 적용했을 때 두 weight 값은 같은 Loss를 가진다. 하지만 <strong>L2 regularization</strong>을 적용하면 $$\omega_{1}$$와 같은 경우는 1의 값을 가지지만, $$\omega_{2}$$와 같은 경우 <code>4 x (1/4)^2 = 1/4</code> 의 Loss를 가진다.</p>
<br>

<ul>
<li><p><span style="color:red"><strong>L1 regularization</strong></p>
<ul>
<li>weight 값이 0으로 수렴하는 것이 많은 형태이다. 이를 Sparse matrix(희소행렬)이라고 부른다. 다시 말해, W 값이 희소행렬이 될 수 있도록 한다.</li>
<li>위에서 0의 값이 많다는 이야기는 어떤 특징들을 무시하겠다는 것으로 볼 수 있다.</li>
</ul>
</li>
<li><p><span style="color:red"><strong>L2 regularization</strong></p>
<ul>
<li>가장 보편적인 방법으로 Euclidean Norm에 패널티를 주는 것이다.</li>
<li>weight 값이 큰 값은 점점 줄이며 대부분의 값들이 0의 가까운 값인 가우시안 분포를 가진다.</li>
<li>weight가 0이 아니라는 점에서 모든 특징들을 무시하지 않고 조금씩은 참고하겠다는 것으로 볼 수 있다.</li>
</ul>
</li>
<li><p><strong>Elasticnet</strong>은 L1과 L2를 합친 것이다.</p>
</li>
</ul>
<br>


<h3 id="softmax-classifier">Softmax Classifier<img src="https://velog.velcdn.com/images/prairie_sky/post/327b23e7-492f-42de-818c-b32f08fbfb59/image.png" alt=""></h3>
<p>Softmax는 스코어를 가지고 <strong>클래스별 확률 분포를 계산하는 방법</strong>이다.
또한, <strong>Multinomial Logistic Regression(다항 로지스틱 회귀)</strong>이라고도 불린다.</p>
<p>각 스코어에 지수를 취해 양수가 되게 만든 뒤에 지수들의 합으로 정규화를 한다. 이 과정을 통해, 확률 분포를 얻을 수 있고 이것이 바로 해당 클래스일 확률이 된다. 이 값은 확률이기 때문에 0-1 사이의 값을 가지며 모든 확률들의 합은 1이다. 정답 클래스의 확률값은 1에 가까운 값이며, <strong>Loss</strong>는 <code>-log(해당 클래스일 확률)</code> 로 정의된다. </p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/3ad2906b-ee66-4c97-9349-98eb1b78ba62/image.png" alt=""> 손실함수는 얼마나 좋은지가 아니라 얼마나 &#39;구린지&#39;를 측정하는 것이기 때문에 log에 -를 붙인다. 해당 클래스 확률일 확률이 0에 가까울수록 loss값은 무한대로 커지고 1에 가까울수록 loss는 0에 가까워진다. </p>
<p>  이론적으로 softmax의 최댓값은 무한대, 최솟값은 0이다. 하지만, 컴퓨터가 무한대 연산을 잘 못하기 때문에(유한정밀도) Loss가 0인 경우는 절대 없다. </p>
<p>  스코어들이 모두 0근처에 모여 있는 작은 수일 경우 Loss는 어떻게 될까? 스코어들이 비슷하다면 <code>-log(1/클래스 개수)</code> 가 된다. (0에 가까운 스코어 값이 지수를 취해 지수들의 합으로 정규화하면 1에 가까운 확률값을 얻을 수 있음) log는 분자와 분모를 뒤집을 수 있기 때문에, 이점을 활용하면 <code>log(클래스 개수)</code> 가 된다. 이 점은 오류가 발생해 문제점을 찾고자 *<em>디버깅할 때 유용하다. *</em></p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/36ddc843-c648-47aa-953c-e959f9b70f21/image.png" alt=""> SVM loss와 같은 형태는 <code>hinge loss</code>, Softmax의 경우 <code>cross entropy loss</code> 라고도 불린다.</p>
<p>  <strong>SVM loss와 Softmax의 차이</strong></p>
<ul>
<li>SVM loss는 정답과 그 외의 클래스 간 margin 만이 최종 결과값에 영향을 주기 때문에 스코어가 조금 변한다고 해서 SVM loss가 변하거나 하지 않는다.</li>
<li>Softmax는 0-1 사이의 확률값만을 도출하기 때문에 정답 스코어가 충분히 높고 다른 클래스 스코어가 충분히 낮아도 최대한 정답 클래스에 확률을 몰아 넣으려고 한다.</li>
</ul>
<p>다시 말해, SVM loss는 일정 margin만 넘기면 더이상 성능 개선에 신경을 쓰지 않는 반면, softmax는 계속해서 성능을 높이려고 노력한다.
<br></p>
<h2 id="optimization">Optimization</h2>
<p>Loss를 줄이는 가중치 w를 찾는 것을 <strong>최적화</strong>라고 한다.</p>
<h3 id="random-search">Random Search<img src="https://velog.velcdn.com/images/prairie_sky/post/b2eb5af6-a071-4f2b-a677-e319e7d1a67e/image.png" alt=""><img src="https://velog.velcdn.com/images/prairie_sky/post/12ce8986-19c5-4578-9acc-4afbd2ec0c6c/image.png" alt=""></h3>
<p>   아무런 기준 없이 <strong>무작위로 w값을 변경해보며 가장 좋은 성능을 가지는 값을 찾는 것</strong>이다. Random Search를 사용하면 약 15.5%의 성능을 가지는 것을 확인할 수 있으나 현재 최고 성능인 SOTA가 95%인 점을 보면 좋은 방법이 아니라는 걸 알 수 있다.</p>
<h3 id="local-geometry">Local Geometry</h3>
<p>  <strong>기하학적 특성을 이용하여 최적화 방법을 수행</strong>할 수 있다. 
  <img src="https://velog.velcdn.com/images/prairie_sky/post/4e07259f-7c43-4a04-bf1a-c2bffbc77916/image.png" alt=""> 눈을 감고 가장 낮은 지대를 찾아 걸어 이동할 때를 상상해보자. 우리는 발로 경사를 느끼고 어느 방향으로 내려가야 하는지를 직감적으로 알 수 있다. 경사를 느끼고 방향을 정해서 내려가는 것을 반복하다 보면 가장 낮은 지대를 찾을 수 있을 것이다. 이 방법은 NN이나 Linear Classifier를 훈련시킬 때 일반적으로 사용된다.</p>
<p>  <img src="https://velog.velcdn.com/images/prairie_sky/post/cf2d4702-f01f-46e3-98f5-8e4c56dc8e0c/image.png" alt=""> 어떤 점 x에서 도함수(derivative)를 계산해보면 작은 스텝 h가 있고 그 스텝 간의 함수 차이를 비교하기 위해 뺄셈을 하여 스텝 간격을 0에 가깝게 만들면 이것이 바로 그 점에서의 경사가 된다. 
<img src="https://velog.velcdn.com/images/prairie_sky/post/4d7d6f76-2b37-45b2-a60a-357a972bd3ee/image.png" alt=""></p>
<p>  이 개념은 다변수 함수(multi-variable function)로도 확장시킬 수 있다. 실제로 x는 스칼라가 아니라 벡터로 x가 벡터이기 때문에 이 개념을 다변수로 확장시켜야 한다. 다변수인 상황에서 미분으로 일반화하면 gradient이고 gradient는 벡터 x의 각 요소의 편도함수들의 집합이다. (*편도함수는 독립변수가 2개 이상인 다변수함수에서의 도함수를 의미함) 입력이 3개면 gradient도 3개가 된다. gradient는 편도함수들의 벡터가 되고 방향은 함수에서 가장 많이 올라가는 방향이다. </p>
<p>특정 방향에서 얼마나 경사가 가파른지 알고 싶을 때 그 방향의 unit 벡터와 gradient 벡터를 내적하면 된다. gradient는 임의의 어떤 점에서의 선형 1차 근사 함수를 알려주기 때문에 많은 딥러닝 알고리즘들이 <strong>gradient를 계산하고 파라미터 벡터를 반복적으로 업데이트</strong> 하는 데에 사용한다.  </p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/be66053d-90b2-45de-9e6f-42036472ab34/image.png" alt=""> 컴퓨터로 gradient를 유용하게 사용할 수 있는 방법은 유한차분법(finite difference method)를 이용하는 것이다. 예시를 보면, 벡터의 두 번째 요소에 아주 작은 값 h(0.0001)을 더하고 loss를 구해보자. 기존 w에서의 loss와 h를 더했을 때의 loss의 차이를 계산하여 위 식에 나온 것처럼 극한 값을 이용해 gradient를 구할 수 있다. 이것을 각 요소마다 반복하면 된다. 
  <img src="https://velog.velcdn.com/images/prairie_sky/post/4a6a3ec9-4ffa-429c-904b-ec5cbb4eaaf1/image.png" alt=""> 벡터 요소마다 반복해서 수행하면 시간이 많이 걸리지만, 미분을 이용하면 바로 gradient를 수할 수 있다. </p>
<p>  얻은 gradient의 반대 방향으로 w를 업데이트하고 아주 조금씩 이동하여 loss가 최저인 지점에 수렴하게 하는 것이 목표이다. step size를 정하는 하이퍼파라미터 learning rate를 올바른 값으로 설정하는 것도 중요하다. </p>
<p>  손실함수를 정의한 것을 생각해보면, Loss를 구할 때 전체 Train 데이터 세트의 loss 평균으로 사용하였다. 하지만 실제로는 데이터의 개수 N이 매우 커질 수 있기 때문에 시간이 오래 걸리게 된다. (ImageNet의 경우 데이터 수가 130만개)</p>
<p>  gradient를 계산하는 과정을 살펴보면 Loss는 그저 각 데이터의 loss의 gradient 합이라는 것을 알 수 있다. 그렇기 때문에 N개의 전체 Train 데이터 세트를 한 번 더 돌면서 계산해야 한다. 그래서 실제로는 <strong>Stochastic Gradient Descent</strong> 방식을 사용한다. </p>
<h3 id="stochastic-gradient-descent">Stochastic Gradient Descent<img src="https://velog.velcdn.com/images/prairie_sky/post/98de1934-62af-42b3-a2b6-ad4515ea49e0/image.png" alt=""></h3>
<p>  전체 데이터 세트의 gradient와 loss를 계산하기 보다는 <strong>Minibatch</strong>라는 작은 트레이닝 샘플로 나누어서 학습하는 방식이다. 보통 2의 제곱으로 정해지며 32,64,128를 주로 쓰는 편이다. Minibatch를 이용하여, Loss의 전체 합의 추정치와 실제 gradient의 추정치를 계산할 수 있다. SGD 방식은 거의 모든 DNN 알고리즘에서 사용되는 기본적인 학습 알고리즘이다. 
  <br></p>
<h2 id="특징-변환">특징 변환</h2>
<p>Linear Classification은 이미지에서 좋은 방법은 아니다. 그래서 DNN이 유행하기 전에는 Linear Classification을 이용하기 위해 두가지 과정을 거쳤다.</p>
<p><strong>1. 이미지의 여러가지 특징표현을 계산</strong>
  : 모양새, 컬러 히스토그램, edge 형태와 같은 특징 표현을 연결한 특징벡터
<strong>2. 이 특징벡터를 Linear Classification의 입력값으로 사용</strong>
  <br></p>
<h3 id="컬러-히스토그램">컬러 히스토그램<img src="https://velog.velcdn.com/images/prairie_sky/post/560885a7-f4f5-4947-9ec0-be9bad71fada/image.png" alt=""></h3>
<p>  각 이미지에서 <code>Hue</code> 값만을 뽑아 <code>각 색깔별 픽셀의 개수</code> 를 세는 것이다. 개구리의 경우 초록색이 많음을 볼 수 있다. </p>
<h3 id="histogram-of-oriented-gradient">Histogram of Oriented Gradient<img src="https://velog.velcdn.com/images/prairie_sky/post/2a67e078-a836-49a4-9d1c-924b6c2ca965/image.png" alt=""></h3>
<p>  이미지를 8*8 픽셀로 나눠서 <code>각 픽셀의 지배적인 edge 방향</code>을 계산한다.</p>
<h3 id="bag-of-words">Bag of Words<img src="https://velog.velcdn.com/images/prairie_sky/post/ecc60e08-5ee5-4a9e-97b4-3905ab94a6ea/image.png" alt=""></h3>
<p>  NLP에서 영감을 받은 방식으로 어떤 문장에서 여러 단어들의 발생 빈도를 세서 특징벡터로 사용하는 방식을 이미지에 적용한 것이다. 이미지들을 임의로 조각내고 각 조각들을 k-means 알고리즘을 이용해 군집화한다. 다양하게 구성된 각 군집들은 다양한 색과 다양한 방향에 대한 edge도 포착할 수 있다. 이러한 것들을 <strong>시각 단어(visual words)</strong>라고 부른다.</p>
<p>5-10년 전에는 대부분 이렇게 특징 벡터를 뽑아 Linear Classification의 input으로 사용하였다. 이 개념들은 CNN과 DNN으로 넘어간다고 크게 달라지지 않는다. 유일하게 다른 점이 있다면, <strong>이미 만들어 놓은 특징을 쓰기 보다는 데이터로부터 특징을 직접 학습하려 한다는 점</strong>이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[시스템(Systems)]]></title>
            <link>https://velog.io/@prairie_sky/%EC%8B%9C%EC%8A%A4%ED%85%9CSystems</link>
            <guid>https://velog.io/@prairie_sky/%EC%8B%9C%EC%8A%A4%ED%85%9CSystems</guid>
            <pubDate>Tue, 04 Apr 2023 09:43:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>디지털 신호 처리 연구의 기반이 되는 선수과목, &#39;신호및시스템&#39; 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h2 id="시스템이란">시스템이란?</h2>
<ul>
<li>한 신호를 다른 신호로 변환하는 규칙(mapping)이 정해진 물리적, 전자기적 요소들의 집합
<img src="https://velog.velcdn.com/images/prairie_sky/post/1a893c3b-4815-4888-a04e-eef6f60804b3/image.jpeg" alt=""> </li>
<li>LPF(Low Pass Filter)는 낮은 주파수를 통과시키고 높은 주파수는 통과시키지 않음
<img src="https://velog.velcdn.com/images/prairie_sky/post/36917dbf-824a-4d36-a8c4-4f96d75701a7/image.jpeg" alt=""></li>
<li>input 함수는 $x(t)$, output 함수는 $y(t)$, system 함수는 $h(t)$</li>
<li>$y(t)=x(t)\circledast h(t)$ ➡️ <strong>convolution</strong></li>
</ul>
<br>
<hr>


<h2 id="시스템-유형types-of-systems">시스템 유형(Types of Systems)</h2>
<h3 id="1-linear-systems-and-nonlinear-systems">1. Linear Systems and Nonlinear Systems</h3>
<ul>
<li>Linear System은 Superposition(sum)과 Homogeneity(product) 성질을 만족해야 함
<img src="https://velog.velcdn.com/images/prairie_sky/post/1bf2cb87-1398-4706-89c7-f1666e0b8a89/image.jpeg" alt="">예시를 들자면,
<img src="https://velog.velcdn.com/images/prairie_sky/post/7ab67262-e81a-47c7-8234-a7ba8e74d4ca/image.jpeg" alt=""></li>
<li>$x_1(t)+x_2(t)$와 $(x_1(t)+x_2(t))^2$의 결과값이 다름 ➡️ $y(t)=x^2(t)$는 Non-linear 함
<img src="https://velog.velcdn.com/images/prairie_sky/post/0631fa7a-677f-4986-932c-a523066fb813/image.jpeg" alt=""></li>
<li>반대로 적분의 경우, 합법칙에 의해 두 값이 동일하기 때문에 linear 함</li>
<li>합과 곱의 결과값이 동일하여야 함<br>

</li>
</ul>
<h3 id="2-stable-systems-and-unstable-systems">2. Stable Systems and Unstable Systems</h3>
<ul>
<li>Bounded Signal: 모든 시간 t에 대해 유한한 값을 가짐</li>
<li>Unbounded Signal: 임의의 순간에 대해 무한한 값을 가짐
<img src="https://velog.velcdn.com/images/prairie_sky/post/c3ea2213-42bc-485d-8866-dd0cfa5b9406/image.jpeg" alt=""></li>
<li>Stable System이라면, 아래 조건 식을 만족해야 함
<img src="https://velog.velcdn.com/images/prairie_sky/post/0394e6ab-8739-4f9d-8375-2dc1378f26d7/image.jpeg" alt="">예시를 바탕으로 정리하자면,
<img src="https://velog.velcdn.com/images/prairie_sky/post/ae257c2a-eda7-49f1-9e13-181521e4df07/image.jpeg" alt=""></li>
<li>조건식을 만족하면 <strong>Stable</strong>, 조건식을 만족하지 못하지만 모든 시간 t에 대해 일정한 값을 가질 경우 <strong>Marginally Stable</strong>, 조건식을 만족하지도 못하면서 무한한 값을 가질 경우 <strong>Unstable</strong><br>

</li>
</ul>
<h3 id="3-static-systems-and-dynamic-systems">3. Static Systems and Dynamic Systems</h3>
<ul>
<li>Static System ➡️ Memoryless</li>
<li>Dynamic System ➡️ Memory
<img src="https://velog.velcdn.com/images/prairie_sky/post/b3a30a78-de7b-4081-8bc6-f96f461221f3/image.jpeg" alt=""></li>
<li>Static은 현재의 input 값 만을 고려함</li>
<li>Dynamic은 과거와 미래 input 값까지 모두 고려함<br>
### 4. Casual Systems and Non-casual Systems</li>
<li>Casual System ➡️ 현재 input 값, 과거 input 값, 과거&amp;현재 input 값 모두를 고려함
<img src="https://velog.velcdn.com/images/prairie_sky/post/2d237cf1-1d63-4727-b61d-a092990acdb1/image.jpeg" alt=""></li>
<li>모든 Static System은 Casual System임</li>
<li>하지만, 그 역의 경우는 성립하지 않음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[신호의 분류(2)]]></title>
            <link>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8%EC%9D%98-%EB%B6%84%EB%A5%982</link>
            <guid>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8%EC%9D%98-%EB%B6%84%EB%A5%982</guid>
            <pubDate>Sat, 01 Apr 2023 07:28:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>디지털 신호 처리 연구의 기반이 되는 선수과목, &#39;신호및시스템&#39; 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h2 id="classification-of-signals">Classification of signals</h2>
<ol>
<li>Continuous time &amp; Discrete time ✅</li>
<li>Real &amp; Imaginary ✅</li>
<li>Periodic &amp; NonPeriodic ✅</li>
<li><strong>Even &amp; Odd ✅</strong></li>
<li>** Energy &amp; Power ✅**</li>
<li><strong>Deterministic &amp; Random ✅</strong></li>
</ol>
<hr>

<h3 id="🧡-even-and-odd-signals">🧡 Even and Odd signals</h3>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/eb54926f-910b-452c-ac06-2e04d6ebad59/image.png" alt=""></p>
<ul>
<li>$$x(t)=x(-t)$$ 부호가 같다면 <strong>even signal</strong> 이다.</li>
<li>$$x(t)=-x(-t)$$ 부호가 다르다면 <strong>odd signal</strong> 이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/975e3075-3b54-4831-aa89-c86522fe4f2f/image.jpeg" alt=""></p>
<ul>
<li>$$x(t)=2rect(\frac{t}{4})$$의 경우, 세로 축을 기준으로 folding 하면 기존의 함수식과 동일한 것을 확인할 수 있다. ➡️ $$x(t)=x(-t)$$ ➡️ <strong>even signal</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/f7dd6d3e-4b8b-40f4-88ee-b33db1b2f4de/image.jpeg" alt=""></p>
<ul>
<li>$$x(t)=2sin(t)$$의 경우, 세로 축과 가로 축(t축)을 기준으로 folding 하면 기존의 함수식과 동일한 것을 확인할 수 있다. ➡️ $$x(t)=-x(-t)$$  ➡️ <strong>odd signal</strong></li>
<li>$$x(t)=cos(t)$$의 경우, 가로 축(t축)을 기준으로 folding 하면 기존의 함수식과 동일한 것을 확인할 수 있다. ➡️ $$x(t)=x(-t)$$ ➡️ <strong>even signal</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/a978213c-c8c1-4592-8d47-03516e45685b/image.jpeg" alt=""></p>
<ul>
<li>위와 같은 unit step function인 $u(t)$는 <strong>even signal</strong>도 아니고 <strong>odd signal</strong>도 아니다.</li>
</ul>
<br>

<h4 id="problems-on-even-and-odd-signal">Problems on Even and Odd signal</h4>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/f2b0cd88-5c28-4b2e-9c0b-d05300722542/image.png" alt=""> $x(t)=x_{e}(t)+x_{o}(t)$
$x(-t)=x_{e}(t)-x_{o}(t)$ 을 가정해보자.</p>
<p>두 식을 더하면, $2x_{e}(t)=x(t)+x(-t)$ 란 식이 나온다.
위 식은 even, odd signal에 따라 다음과 같이 분리 될 수 있다.</p>
<ul>
<li>$x_{e}(t)=\frac{x(t)+x^*(-t)}{2}$</li>
<li>$x_{o}(t)=\frac{x(t)-x^*(-t)}{2}$</li>
</ul>
<p>+) <code>*</code> 는 <strong>conjugate operation</strong>을 나타낸다. conjugate에는 &#39;짝으로 결합한&#39;이라는 뜻으로, a+bi와 a-bi가 &#39;짝으로 결합해&#39; 있는 것을 예시로 볼 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/404b6530-bcbe-451f-8d1c-6d29262a9983/image.png" alt=""> 위 그래프에서 첫 번째 두 번째 식은 even, odd signal을 나타내고 있지 않다. 3번째 식은 even signal을, 4번째 식은 odd signal을 각각 나타내고 있는 것을 확인할 수 있다. </p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/03c1efa7-4e1d-4bef-afa1-22505ff64180/image.png" alt=""></p>
<ul>
<li>$x(t)=e^{jt}$의 경우, $x(t)=x^<em>(-t)$이므로 *</em>even signal이다.**</li>
<li>$x(t)=te^{jt}$의 경우, $x(t)=-x^<em>(-t)$이므로 *</em>odd signal이다.**</li>
</ul>
<br>

<h3 id="🧡-energy-and-power-signal">🧡 Energy and Power signal<img src="https://velog.velcdn.com/images/prairie_sky/post/715c8596-65bb-4a3f-88af-cbae0206119c/image.jpeg" alt=""></h3>
<p>에너지 값은 위와 같은 식으로 나타낼 수 있다. ($$\alpha=\infty$$)
에너지는 0 &lt; E &lt; $\alpha$ 조건식을 만족해야 한다.</p>
<ul>
<li>Continous time ➡️ $$\int_{-\alpha}^{\alpha}|{x(t)|^2dt}$$</li>
<li>Discrete time ➡️ $$\sum_{n=-\alpha}^{\alpha}|{x(n)|^2}$$</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/919c6142-1bad-44d1-b57f-7a916d0d8130/image.png" alt=""> Power의 평균값은 $$\frac{Energy}{Time}$$ 을 통해 구할 수 있다.</p>
<ul>
<li>Continous time ➡️ $$\lim_{T \to \alpha}\frac{1}{T}\int_{T}|{x(t)|^2dt}$$</li>
<li>Discrete time ➡️ $\lim_{N \to \alpha}\frac{1}{2N+1}\sum_{n=N}^{N}|{x(n)|^2}$</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/64079eb1-a0b4-43b8-b4da-315c8d42f76f/image.png" alt=""></p>
<ul>
<li>0 &lt; E &lt; $\alpha$ 이면 *<em>Energy signal이다. *</em></li>
<li>E = $\alpha$ 이고 0 &lt; $Pow_{g}$ &lt; $\alpha$ 이면, <strong>Power signal이다.</strong> (power signal의 energy는 $\alpha$ 이다.)</li>
<li>E = $\alpha$ 이고 $Pow_{g}$ 도 $\alpha$ 라면, <strong>energy도 아니고 power signal도 아니다.</strong></li>
</ul>
<br>

<h4 id="problems-on-energy-and-power-signal">Problems on Energy and Power signal</h4>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/824eec70-afdd-4d42-816a-cf45013aa802/image.png" alt=""> 위 식의 결과값이 $E=\frac{1}{2a}$로 이 값은 $\alpha(=\infty)$보다 작으므로 위 함수식은 Energy signal을 나타낸다.</p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/ab18b67c-47b7-4474-ab20-3dbaa127e199/image.png" alt=""> 위 식의 결과값이 $E=\alpha$, $Pow_{g}$ &lt; $\alpha$를 만족하므로 위 함수식은 Power Signal을 나타낸다.</p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/dbd76138-87ce-439c-89af-ffa83e25b610/image.png" alt=""> 위 식의 결과값이 $E=\alpha$, $Pow_{g}=\alpha$를 만족하므로 위 함수식은 Engergy Singal도 아니고 Power Signal도 아니다.</p>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/b61341fa-6a92-402c-87bb-a40ca59572ae/image.png" alt=""> 순서대로 위 문제들의 나타낸 그래프이다.</p>
<ul>
<li><strong>Energy Signal</strong>은 <code>0</code>을 향해 나아간다.</li>
<li><strong>Power Signal</strong>은 <code>0이 아닌 특정 값으로 일정(constant)</code>하게 나아간다.</li>
<li><strong>NENP(Engergy도 Power Signal도 아님)</strong>는 <code>무한대</code>를 향해 나아간다.</li>
</ul>
<br>


<h4 id="problems-on-discrete-time-signal">Problems on discrete time signal</h4>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/9baf64e3-1bb5-4319-b795-f1f7a209ed62/image.png" alt=""> 무한 등비 급수 공식을 이용하여 위 식이 나타내는 신호가 무엇인지를 알 수 있다. </p>
<p><code>무한등비 급수 공식</code> : $\sum_{n=0}^{\alpha}{x^n}=\frac{1}{1-x}; |x|&lt;1$</p>
<p>$x(n)=a^n u(n)$ 을 가정해보자.</p>
<ul>
<li>$a&lt;1$ 이면, <strong>Energy Signal이다.</strong> (0 &lt; E &lt; $\alpha$)</li>
<li>$a&gt;1$ 이면, <strong>NENP 이다.</strong> ($E=\alpha$, $Pow_{g}=\alpha$)</li>
<li>$a=1$ 이면, <strong>Power Signal이다.</strong> ($E=\alpha$, 0 &lt; $Pow_{g}$ &lt; $\alpha$)</li>
</ul>
<br>

<h3 id="🧡-deterministic-and-random-signal">🧡 Deterministic and Random signal</h3>
<ul>
<li><strong>&#39;Deterministic&#39;</strong>이란 의미는 식으로 정립이 가능하고 이를 통해 예측 가능하다는 뜻이다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/b0c6fce0-69ef-4bf0-9f60-17d8048b2c7a/image.jpeg" alt=""> <strong>random signal</strong>은 예측 불가능하며 식으로 나타낼 수 없다.<img src="https://velog.velcdn.com/images/prairie_sky/post/334f909f-0730-44be-aaf2-1164953abcb1/image.jpeg" alt=""> 신호는 다음과 같이  분류할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 모음사전]]></title>
            <link>https://velog.io/@prairie_sky/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AA%A8%EC%9D%8C%EC%82%AC%EC%A0%84</link>
            <guid>https://velog.io/@prairie_sky/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AA%A8%EC%9D%8C%EC%82%AC%EC%A0%84</guid>
            <pubDate>Mon, 13 Mar 2023 08:09:14 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-📚">문제 📚</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/84512">프로그래머스 &#39;모음사전(완전탐색)&#39; 문제 보기</a></p>
<p>사전에 알파벳 모음 &#39;A&#39;, &#39;E&#39;, &#39;I&#39;, &#39;O&#39;, &#39;U&#39;만을 사용하여 만들 수 있는, 길이 5 이하의 모든 단어가 수록되어 있습니다. 사전에서 첫 번째 단어는 &quot;A&quot;이고, 그다음은 &quot;AA&quot;이며, 마지막 단어는 &quot;UUUUU&quot;입니다.</p>
<p>단어 하나 word가 매개변수로 주어질 때, 이 단어가 사전에서 몇 번째 단어인지 return 하도록 solution 함수를 완성해주세요.</p>
<p><strong>제한사항</strong></p>
<ul>
<li>word의 길이는 1 이상 5 이하입니다.</li>
<li>word는 알파벳 대문자 &#39;A&#39;, &#39;E&#39;, &#39;I&#39;, &#39;O&#39;, &#39;U&#39;로만 이루어져 있습니다.</li>
</ul>
<p><br></br></p>
<h2 id="문제-설명-👩🏫">문제 설명 👩‍🏫</h2>
<p>두 가지 입력 예시를 통해 문제를 어떻게 풀어야 할지 생각해보자.</p>
<blockquote>
<p><strong>#1</strong>
<strong>입력(word):</strong> &quot;AAAAE&quot; 
<strong>출력(result):</strong> 6
사전에서 첫 번째 단어는 &quot;A&quot;이고, 그다음은 &quot;AA&quot;, &quot;AAA&quot;, &quot;AAAA&quot;, &quot;AAAAA&quot;, &quot;AAAAE&quot;, ... 와 같습니다. &quot;AAAAE&quot;는 사전에서 6번째 단어입니다.</p>
</blockquote>
<blockquote>
<p><strong>#2</strong>
<strong>입력(word):</strong> &quot;AAAE&quot; 
<strong>출력(result):</strong> 10
&quot;AAAE&quot;는 &quot;A&quot;, &quot;AA&quot;, &quot;AAA&quot;, &quot;AAAA&quot;, &quot;AAAAA&quot;, &quot;AAAAE&quot;, &quot;AAAAI&quot;, &quot;AAAAO&quot;, &quot;AAAAU&quot;의 다음인 10번째 단어입니다.</p>
</blockquote>
<p><br></br></p>
<h2 id="코드-👩💻">코드 👩‍💻</h2>
<h3 id="solution-1">Solution 1</h3>
<pre><code class="language-python">from itertools import product  # 중복순열

def solution(word):
    lst = list()

    for i in range(1,6):
        for j in product([&#39;A&#39;,&#39;E&#39;,&#39;I&#39;,&#39;O&#39;,&#39;U&#39;], repeat = i):
            lst.append(&#39;&#39;.join(j))
    lst.sort()  # 문자정렬
    return lst.index(word)+1</code></pre>
<blockquote>
<p><strong>중복을 허용한 순열을 통해 문제를 풀 수 있다. (product와 repeat)</strong>
i가 1일 때: A, E, I, O, U로 만든 순열 ➡️ A, E, I, O, U
i가 2일 때: A, E, I, O, U로 만든 순열 ➡️ AA, AE, AI, AO, AU, EE, EI, ...
i가 3일 때: A, E, I, O, U로 만든 순열 ➡️ AAA, AAE, AAI, AAO, AEA, AEI, AEO, ...
...
<strong>join을 통해 문자 리스트들을 하나의 문자열로 바꿔주고 lst에 저장한다.</strong>
&#39;&#39;.join([&#39;A&#39;],[&#39;E&#39;])는 &#39;AE&#39;이다.
<strong>sort()함수를 이용하면 문자가 알파벳 순으로 정렬된다.</strong>
이후, 해당 word값이 몇 번째인지 찾아 1을 더하고 정답을 출력한다.</p>
</blockquote>
<br>

<h3 id="solution-2">Solution 2</h3>
<pre><code class="language-python">from itertools import product

# lambda를 이용한 solution 함수
solution = lambda word: sorted([&#39;&#39;.join(j) for i in range(5) for j in product(&#39;AEIOU&#39;, repeat=i+1)]).index(word)+1</code></pre>
<blockquote>
<p><strong>lambda 표현식</strong></p>
</blockquote>
<ul>
<li>함수를 한 줄로 표기할 때 쓰인다.
<code>lambda 매개변수 : 표현식</code></li>
</ul>
<blockquote>
<p><strong>sort함수와 sorted 함수 차이</strong></p>
</blockquote>
<ul>
<li>sorted 함수는 정렬된 새로운 리스트를 리턴한다. </li>
<li>sort 메소드는 아무것도 리턴시켜주지 않는다. (None을 리턴)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 숫자 문자열과 영단어]]></title>
            <link>https://velog.io/@prairie_sky/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90%EC%97%B4%EA%B3%BC-%EC%98%81%EB%8B%A8%EC%96%B4</link>
            <guid>https://velog.io/@prairie_sky/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90%EC%97%B4%EA%B3%BC-%EC%98%81%EB%8B%A8%EC%96%B4</guid>
            <pubDate>Mon, 13 Mar 2023 07:08:51 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-📚">문제 📚</h2>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/81301">프로그래머스 &#39;숫자 문자열과 영단어(level 1)&#39; 문제 보기</a></p>
<p>네오와 프로도가 숫자놀이를 하고 있습니다. 네오가 프로도에게 숫자를 건넬 때 일부 자릿수를 영단어로 바꾼 카드를 건네주면 프로도는 원래 숫자를 찾는 게임입니다.</p>
<p>다음은 숫자의 일부 자릿수를 영단어로 바꾸는 예시입니다.</p>
<ul>
<li>1478 → &quot;one4seveneight&quot;</li>
<li>234567 → &quot;23four5six7&quot;</li>
<li>10203 → &quot;1zerotwozero3&quot;</li>
</ul>
<p>이렇게 숫자의 일부 자릿수가 영단어로 바뀌어졌거나, 혹은 바뀌지 않고 그대로인 문자열 s가 매개변수로 주어집니다. s가 의미하는 원래 숫자를 return 하도록 solution 함수를 완성해주세요.</p>
<p><strong>제한사항</strong></p>
<ul>
<li>1 ≤ s의 길이 ≤ 50</li>
<li>s가 &quot;zero&quot; 또는 &quot;0&quot;으로 시작하는 경우는 주어지지 않습니다.</li>
<li>return 값이 1 이상 2,000,000,000 이하의 정수가 되는 올바른 입력만 s로 주어집니다.</li>
</ul>
<p><br></br></p>
<h2 id="문제-설명-👩🏫">문제 설명 👩‍🏫</h2>
<p>두 가지 입력 예시를 통해 문제를 어떻게 풀어야 할지 생각해보자.</p>
<blockquote>
<p><strong>#1</strong>
<strong>입력:</strong> &quot;2three45sixseven&quot; 
<strong>출력:</strong> 234567</p>
</blockquote>
<blockquote>
<p><strong>#1</strong>
<strong>입력:</strong> &quot;123&quot; 
<strong>출력:</strong> 123</p>
</blockquote>
<ol>
<li>문자열 입력을 받는다.</li>
<li>받은 문자열 안에 영단어가 있으면 대치하는 숫자로 바꿔준다.</li>
<li>정수로 출력한다.</li>
</ol>
<p><br></br></p>
<h2 id="코드-👩💻">코드 👩‍💻</h2>
<h3 id="solution-1">Solution 1</h3>
<pre><code class="language-python">words = (&#39;zero&#39;,&#39;one&#39;,&#39;two&#39;,&#39;three&#39;,&#39;four&#39;,&#39;five&#39;,&#39;six&#39;,&#39;seven&#39;,&#39;eight&#39;,&#39;nine&#39;)

def solution(s):
    answer = s
    for idx, word in enumerate(words):
        answer = answer.replace(word, str(idx))
    return int(answer)</code></pre>
<blockquote>
<p>enumerate 함수와 replace 함수를 이용하여 idex값과 words 튜플의 원소값을 바꿔준다.</p>
</blockquote>
<br>

<h3 id="solution-2">Solution 2</h3>
<pre><code class="language-python">keys = (&#39;zero&#39;,&#39;one&#39;,&#39;two&#39;,&#39;three&#39;,&#39;four&#39;,&#39;five&#39;,&#39;six&#39;,&#39;seven&#39;,&#39;eight&#39;,&#39;nine&#39;)
values = (&#39;0&#39;,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;)
dic = dict(zip(keys, values))

def solution(s):
    answer = s
    for key, value in dic.items():
        answer = answer.replace(key, value)
    return int(answer)</code></pre>
<blockquote>
<p>딕셔너리 함수인 dic.items()를 이용해 key, value에 각각 숫자 문자열, 인덱스 값으로 불러온다.</p>
</blockquote>
<br>

<h3 id="solution-3">Solution 3</h3>
<pre><code class="language-python">keys = (&#39;zero&#39;,&#39;one&#39;,&#39;two&#39;,&#39;three&#39;,&#39;four&#39;,&#39;five&#39;,&#39;six&#39;,&#39;seven&#39;,&#39;eight&#39;,&#39;nine&#39;)
values = (&#39;0&#39;,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;)
dic = dict(zip(keys, values))

def solution(s):
    answer = &#39;&#39;
    word = &#39;&#39;
    for i in s:
        if i.isdigit():
            answer += i
        else:
            word += i
            if word in keys:
                answer += dic[word]
                word = &#39;&#39;
    return int(answer)</code></pre>
<blockquote>
<p>기본적인 딕셔너리 구조를 이용해 숫자이면 정답 문자열에 포함하고, 숫자가 아니라면 딕셔너리의 key값(문자열)에 해당하는 value(숫자)를 가져와 정답 문자열에 포함한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[신호의 분류(1)]]></title>
            <link>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8%EC%9D%98-%EB%B6%84%EB%A5%981</link>
            <guid>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8%EC%9D%98-%EB%B6%84%EB%A5%981</guid>
            <pubDate>Thu, 09 Mar 2023 03:14:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>디지털 신호 처리 연구의 기반이 되는 선수과목, &#39;신호및시스템&#39; 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h2 id="classification-of-signals">Classification of signals</h2>
<p><strong>1. Continuous time &amp; Discrete time</strong> ✅
<strong>2. Real &amp; Imaginary</strong> ✅
<strong>3. Periodic &amp; NonPeriodic</strong> ✅
4. Even &amp; Odd
5. Energy &amp; Power
6. Deterministic &amp; Random</p>
<hr>

<h3 id="🧡-continuous-time--discrete-time">🧡 Continuous time &amp; Discrete time</h3>
<h4 id="continuous-time">Continuous time<img src="https://velog.velcdn.com/images/prairie_sky/post/2335959d-4eec-4566-9e54-86dd3da2dd52/image.jpeg" alt=""></h4>
<ul>
<li>모든 시간 t에 대해 함수가 정의된다.<h4 id="discrete-time">Discrete time<img src="https://velog.velcdn.com/images/prairie_sky/post/f68c00f4-8604-4bec-981c-7bf81f0d8b79/image.jpeg" alt=""></h4>
</li>
<li>특정 시간 t에 대해 일정한 간격으로 함수가 정의된다.<br>

</li>
</ul>
<h3 id="🧡-real--imaginary">🧡 Real &amp; Imaginary</h3>
<ul>
<li>$x(t)=3$일 때, $x^<em>(t)=3^</em>=3$ ➡️ Real Signal</li>
<li>$x(t)=3j$일 때, $x^<em>(t)=3j^</em>=-3j=-x(t)$ ➡️ Odd Signal</li>
<li>Real Signal이라면 허수부가 0이 되어야하고 Imaginary Signal이라면 실수부가 0이 되어야 한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/743cc25f-df90-4277-9811-115f755dc0ea/image.jpeg" alt=""></p>
<ul>
<li>Complex Signal은 실수부와 허수부를 모두 가지고 있는 신호이다.</li>
<li>공식을 통해 $e^{j\Theta}=cos(\Theta)+jsin(\Theta)$를 유도할 수 있다.<br>

</li>
</ul>
<h3 id="🧡-periodic-and-aperiodicap-signal">🧡 Periodic and Aperiodic(AP) signal</h3>
<ul>
<li>Periodic Signal: 주기성을 가지고 있는 신호</li>
<li>Aperiodic(AP) Signal: 주기성을 가지고 있지 않고 패턴화 되지 않는 신호</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/11e835f2-f415-4c42-b885-84ee7478aebf/image.jpeg" alt=""></p>
<ul>
<li><p>T는 Time Period를 의미하며 $T=\frac{2\pi}{w}$
<img src="https://velog.velcdn.com/images/prairie_sky/post/6314cd82-de0d-4692-9ccb-b76d9afaf614/image.jpeg" alt=""></p>
</li>
<li><p>$x(t)=2sin(100\pi t)+3cos(300\pi t)$ ➡️ 2개 이상의 함수들로 이루어진 신호의 주기를 구해보자!</p>
<ol>
<li>각 함수별 시간 주기를 구한다. $T_1, T_2, T_3 ...$ </li>
<li>$T_1$을 각 주기로 나눈다. $\frac{T_1}{T_2}, \frac{T_1}{T_3}, \frac{T_1}{T_4}$ 이때 유리수(rational number)로 나타낼 수 있으면 $x(t)$는 periodic 함수이다.</li>
<li>과정 2에서 구한 값에 $T_1$을 곱한 값이 $T_0$이 된다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/00dafb75-5ba7-4d3a-878f-4447650e69bf/image.jpeg" alt=""></p>
</li>
<li><p>과정 2의 결과가 유리수($\frac{3}{1}$)이므로 Periodic signal이다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/2c4c89f2-81f3-46c9-ba7f-7e56f4fe1717/image.jpeg" alt=""></p>
</li>
<li><p>과정 2의 결과가 무리수($\frac{2}{\pi}$)이므로 Aperiodic signal이다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/11e9b287-0718-43a3-b697-8ff26964fffc/image.jpeg" alt=""></p>
</li>
<li><p>과정 2에서 분모의 최소공배수가 2이므로 과정 3에서 $T_1$값에 2가 곱해진다.</p>
</li>
</ul>
<h4 id="periodity-of-discrete-time-signals">Periodity of Discrete time signals</h4>
<ul>
<li>Discrete time의 경우 m은 N을 정수로 변환하는데 필요한 최소 정수값, N은 time period 안에 존재하는 샘플들의 개수를 의미한다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/fb4fbc9c-6cf1-467f-856f-39ab1aa6e106/image.jpeg" alt=""></li>
<li>$\frac{m}{N}=\frac{w}{2\pi}$의 값이 유리수(rational number)라면 신호가 periodic한 성질을 갖는다고 할 수 있으며 m과 N의 추정값을 구할 수 있다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/5a888b23-d36f-4162-98d7-8258c65b250a/image.jpeg" alt=""></li>
<li>식의 결과값이 무리수이므로 AP 신호이다.
<img src="https://velog.velcdn.com/images/prairie_sky/post/1673deac-f979-40ae-ab16-515aa4cad1a3/image.jpeg" alt=""></li>
<li>$e^{j\pi}=cos(\pi)+jsin(\pi)=-1$ ➡️ $x[n]=(-1)^n$을 $e^{j\pi}$로 바꿀 수 있다.</li>
<li>$x[n]=(-1)^n=e^{j\pi n}$ ➡️ $\pi$는 $w$로 바꿀 수 있다.</li>
<li>$\frac{m}{N}=\frac{\pi}{2\pi}=\frac{1}{2}$로 유리수가 나오므로 이 신호는 Periodic하다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[신호의 연산]]></title>
            <link>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8%EC%9D%98-%EC%97%B0%EC%82%B0Operations-on-Signals</link>
            <guid>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8%EC%9D%98-%EC%97%B0%EC%82%B0Operations-on-Signals</guid>
            <pubDate>Thu, 02 Mar 2023 05:10:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>디지털 신호 처리 연구의 기반이 되는 선수과목, &#39;신호및시스템&#39; 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h3 id="🧡-shifting">🧡 Shifting<img src="https://velog.velcdn.com/images/prairie_sky/post/d644e5d4-3204-48e0-9148-d5fd59b91bf0/image.jpeg" alt=""></h3>
<ul>
<li>$$x(t+t_0)$$ 이면 왼쪽으로 그래프를 이동</li>
<li>$$x(t-t_0)$$ 이면 오른쪽으로 그래프를 이동</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/b8ae8af8-0a94-4d0f-934d-72f4fd54a253/image.jpeg" alt=""></p>
<h3 id="🧡-time-scaling">🧡 Time Scaling<img src="https://velog.velcdn.com/images/prairie_sky/post/9139f756-ede5-473f-968e-9cbbc9bab6d1/image.jpeg" alt=""></h3>
<ul>
<li>$a$ 가 1보다 크면 확장(Expansion)</li>
<li>$a$ 가 1보다 작으면 압축(Compression)</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/6396c6ef-11db-4148-81d7-4bab9be7859e/image.jpeg" alt=""></p>
<h3 id="🧡-foldingtime-reversal">🧡 Folding(Time Reversal)<img src="https://velog.velcdn.com/images/prairie_sky/post/ecdb2dc0-359a-493b-a1aa-0ca9da80a494/image.jpeg" alt=""></h3>
<ul>
<li>세로 축을 기준으로 회전</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/acca3b04-60f2-44d4-90f2-ebd16e46a8bb/image.jpeg" alt=""></p>
<ul>
<li>세로 축을 기준으로 대칭이면 변함 없음</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/e0c7bedd-6d20-43da-a34b-ff80c09629e2/image.jpeg" alt=""></p>
<ul>
<li>복합 연산일 경우, Shifting 먼저 적용 후에 Scaling과 Folding 적용<br>

</li>
</ul>
<h3 id="🧡-adding-subtraction">🧡 Adding, Subtraction</h3>
<h4 id="--adding">- Adding<img src="https://velog.velcdn.com/images/prairie_sky/post/ff319f75-cbbf-4a72-a9dd-0f55d2478cd2/image.jpeg" alt=""></h4>
<h4 id="--subtraction">- Subtraction<img src="https://velog.velcdn.com/images/prairie_sky/post/b67af8fe-b973-444f-8a5d-b8fc445b5a2e/image.jpeg" alt=""></h4>
<ul>
<li>gate signal을 step signal 함수 표기 방식으로 나타낼 수 있음</li>
<li>$Arect(\frac{t}{T})=A[u(t+\frac{T}{2})-u(t-\frac{T}{2})]$<br>

</li>
</ul>
<h3 id="🧡-multiplication">🧡 Multiplication<img src="https://velog.velcdn.com/images/prairie_sky/post/622ed2dd-86ff-4df9-a9b7-186f14b916ab/image.jpeg" alt=""></h3>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/a87f2eb6-5099-473c-80ad-6629b6d5fba6/image.jpeg" alt=""></p>
<h3 id="🧡-differentiation">🧡 Differentiation<img src="https://velog.velcdn.com/images/prairie_sky/post/4b7cf96d-e10d-41c6-b3fd-cb0e1eb31007/image.jpeg" alt=""></h3>
<ul>
<li>unit Ramp function 미분 ➡️ unit Step function 미분 ➡️ unit Impulse function 미분</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[신호]]></title>
            <link>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8</link>
            <guid>https://velog.io/@prairie_sky/%EC%8B%A0%ED%98%B8</guid>
            <pubDate>Mon, 27 Feb 2023 12:50:55 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>디지털 신호 처리 연구의 기반이 되는 선수과목, &#39;신호및시스템&#39; 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h2 id="signals">Signals</h2>
<ul>
<li>정보를 전달하기 위한 물리적인 파형</li>
<li>수학적 정의<ul>
<li>독립변수(Independent variable): Time</li>
<li>종속변수(dependent variable): Function </li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/bde28af9-7864-44d6-807c-60b740690f06/image.jpeg" alt=""></p>
<h2 id="basic-signals">Basic Signals</h2>
<ul>
<li>Step Signal</li>
<li>Ramp Signal</li>
<li>Impulse Signal</li>
<li>Parabolic Signal</li>
</ul>
<br>



<h3 id="🧡-step-signals">🧡 Step Signals<img src="https://velog.velcdn.com/images/prairie_sky/post/60d53b2e-a53a-449d-92ca-85f1edb1abbe/image.jpeg" alt=""></h3>
<ul>
<li>일정 시간 동안 값이 일정함<br/>

</li>
</ul>
<h3 id="🧡-impluse-signals">🧡 Impluse Signals<img src="https://velog.velcdn.com/images/prairie_sky/post/13770d22-cacd-4f73-bf77-bc38b5504fd2/image.jpeg" alt=""></h3>
<ul>
<li>특정 시간 t에 값의 변화가 있음</li>
<li>자극으로 인한 짧은 입력 신호가 제공될 때의 출력</li>
<li>현실적으로 불가능한 표현</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/6e61ea2a-ab51-410f-ba48-198dd8892fa9/image.jpeg" alt=""></p>
<ul>
<li>신호의 면적이 1 </li>
<li>현실적인 표현</li>
</ul>
<p><img src="https://velog.velcdn.com/images/prairie_sky/post/c5822685-7b34-4adc-b2b4-54a89a17fb48/image.jpeg" alt=""></p>
<h3 id="🧡-ramp-signals-and-parabolic-signals">🧡 Ramp Signals and Parabolic Signals<img src="https://velog.velcdn.com/images/prairie_sky/post/e345297f-51c6-4fcc-97e2-18ebf1963403/image.jpeg" alt=""></h3>
<br>

<h3 id="🧡-all-signals-summary">🧡 All Signals Summary<img src="https://velog.velcdn.com/images/prairie_sky/post/953104c7-5e28-43cd-aff6-77b8b0213aea/image.jpeg" alt=""></h3>
<ul>
<li><strong>Singularity Function:</strong> 자연계에서 존재할 수 없는 함수이나, 수학적으로 근사화시킬 수 있는 함수 형태</li>
</ul>
<br>

<h3 id="🧡-standard-signals">🧡 Standard Signals<img src="https://velog.velcdn.com/images/prairie_sky/post/589912bd-ec09-4840-9d6e-eaa1ae525eac/image.jpeg" alt=""><img src="https://velog.velcdn.com/images/prairie_sky/post/dd1b98c4-f56a-4880-929c-0e58f6716bc8/image.jpeg" alt=""></h3>
<br>

<h3 id="🧡-gate-signal-or-rectangular-signal">🧡 Gate Signal or Rectangular Signal<img src="https://velog.velcdn.com/images/prairie_sky/post/d6fe987e-a70a-411b-bf5b-d2cc9645ae8a/image.jpeg" alt=""><img src="https://velog.velcdn.com/images/prairie_sky/post/02e2c7ab-3bba-4065-be4b-4115415b6520/image.jpeg" alt=""></h3>
<ul>
<li><strong>signum function:</strong> 수의 부호를 판별하는 함수<br>


</li>
</ul>
<h3 id="🧡-sampling-signal-or-sync-signal">🧡 Sampling Signal or Sync Signal<img src="https://velog.velcdn.com/images/prairie_sky/post/3d159145-0f45-4c51-b3df-529350fa994e/image.jpeg" alt=""></h3>
<ul>
<li><strong>Operations on Signals ➡️ Basic Signal, Standard Signal에 적용</strong><ul>
<li>Shifting</li>
<li>Scaling</li>
<li>Folding(time reversal)</li>
<li>Add | Sub | Mul</li>
<li>Differentiation</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[확률]]></title>
            <link>https://velog.io/@prairie_sky/%ED%99%95%EB%A5%A0</link>
            <guid>https://velog.io/@prairie_sky/%ED%99%95%EB%A5%A0</guid>
            <pubDate>Tue, 21 Feb 2023 14:26:19 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>인공지능 연구의 기반이 되는 선수과목, &#39;확률및통계&#39; 내용을 복습하기 위해 쓴 글입니다. 내용에 오류가 있을 시, 조언 및 지적해주시면 감사하겠습니다.</p>
</blockquote>
<h2 id="11-사건">1.1 사건</h2>
<ul>
<li><p><strong>통계적 실험(statistical experiment):</strong> 통계적 목적 아래 관찰이나 측정을 얻어내는 일련의 과정</p>
</li>
<li><p><strong>관찰값(observation):</strong> 측정되거나 관찰된 값</p>
</li>
<li><p>*<em>표본공간(sample space): *</em>측정 가능한 모든 결과들의 집합</p>
<ul>
<li>sample space을 이루는 개개의 실험 결과를 element 또는 sample point라고 함</li>
<li>추출 방법에 따라 <strong>비복원추출(without replacement)</strong>, <strong>복원추출(replacement)</strong>로 나눠짐</li>
</ul>
</li>
<li><p><strong>사건(event):</strong> 표본 공간의 부분집합으로 어떤 조건을 만족하는 특정한 표본점들의 집합</p>
<ul>
<li>하나의 표본점으로 구성된 사건 ➡️ <strong>단순사건(simple event), 근원사건(elementary event)</strong></li>
<li>두 개의 표본점으로 구성된 사건 ➡️ <strong>복합사건(compound event)</strong></li>
<li>표본점이 하나도 들어있지 않은 사건 ➡️ <strong>공사건(empty event)</strong></li>
<li>$$A \cup B$$ ➡️ <strong>A와 B의 합사건(union of events)</strong></li>
<li>$$A \cap B$$ ➡️ <strong>A와 B의 공집합(intersection of events)</strong></li>
<li>$$A - B$$ ➡️ <strong>A에는 있으나 B에는 없는 차사건(difference of events)</strong></li>
<li>$A^c$ ➡️ **A 안에 있지 않은 표본점으로 구성된 여사건(complementary event)</li>
</ul>
</li>
<li><p>*</p>
<ul>
<li>$$A \cap B= \emptyset$$ ➡️ <strong>공통의 표본점을 갖지 않음. 배반사건(exclusive)</strong>, <ul>
<li>n 개의 사건 중에서 쌍마다 배반사건(pairwisely mutually exclusive)일 경우도 존재함, 이 합 사건이 표본공간 S인 사건을 분할(partition)이라 함</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="12-확률">1.2 확률</h2>
<ul>
<li><p>** 확률(probability)**: 동일한 조건 아래서 동일한 실험을 무수히 반복하여 실시할 때, 어떤 특정한 사건이 발생하는 비율
<img src="https://velog.velcdn.com/images/prairie_sky/post/3608af5f-abd4-4ef0-aaee-d9d142a61a20/image.jpeg" alt=""></p>
</li>
<li><p><strong>조건부 확률</strong>: P(A) &gt; 0 인 어떤 사건 A가 주어졌다는 조건 아래서, 사건 B가 나타날 확률<img src="https://velog.velcdn.com/images/prairie_sky/post/caa9b768-0f99-48e3-96f7-828bbddb8991/image.jpeg" alt=""></p>
<ul>
<li><p><strong>$$P(A \cap B)=P(A)P(B|A)$$</strong></p>
</li>
<li><p><strong>$$P(A \cap B \cap C)=P(A \cap B)P(C|A \cap B)=P(A)P(B|A)P(C|A \cap B)$$</strong></p>
</li>
<li><p>P(A) &gt; 0 또는 P(B) &gt; 0 일 때 사건 A의 발생여부가 사건 B의 발생에 영향을 미치지 않는 경우 ➡️ <strong>A와 B는 독립(independent)</strong></p>
<ul>
<li>$P(A \cap B)=P(A)P(B)$</li>
<li>$P(A|B)=P(A), P(B|A)=P(B)$</li>
</ul>
</li>
<li><p>독립이 아닌 경우 ➡️ <strong>A와 B는 종속(dependent)</strong></p>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="13-베이즈-정리">1.3 베이즈 정리</h2>
<ul>
<li><strong>전확률 공식(formula of total probability)</strong>
<img src="https://velog.velcdn.com/images/prairie_sky/post/525f4cf2-00a4-4379-89df-85d1c82a0dc0/image.jpeg" alt=""></li>
<li><strong>베이즈 정리(Bayes&#39; theorem)</strong>
<img src="https://velog.velcdn.com/images/prairie_sky/post/bf3b1c85-4d88-4f0c-9da4-82ad829c785a/image.jpeg" alt=""><ul>
<li>베이즈 정리는 사전확률을 통해 더 많은 정보를 수집하는 수단으로 사용될 수 있다는 점에서 중요함</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 캐시]]></title>
            <link>https://velog.io/@prairie_sky/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BA%90%EC%8B%9CPython</link>
            <guid>https://velog.io/@prairie_sky/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BA%90%EC%8B%9CPython</guid>
            <pubDate>Mon, 18 Oct 2021 08:13:35 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-📚">문제 📚</h2>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/17680">프로그래머스 캐시 문제 보기 </a></p>
<p>지도개발팀에서 근무하는 제이지는 지도에서 도시 이름을 검색하면 해당 도시와 관련된 맛집 게시물들을 데이터베이스에서 읽어 보여주는 서비스를 개발하고 있다.
이 프로그램의 테스팅 업무를 담당하고 있는 어피치는 서비스를 오픈하기 전 각 로직에 대한 성능 측정을 수행하였는데, 제이지가 작성한 부분 중 데이터베이스에서 게시물을 가져오는 부분의 실행시간이 너무 오래 걸린다는 것을 알게 되었다.
어피치는 제이지에게 해당 로직을 개선하라고 닦달하기 시작하였고, 제이지는 DB 캐시를 적용하여 성능 개선을 시도하고 있지만 캐시 크기를 얼마로 해야 효율적인지 몰라 난감한 상황이다.</p>
<p>어피치에게 시달리는 제이지를 도와, DB 캐시를 적용할 때 캐시 크기에 따른 실행시간 측정 프로그램을 작성하시오.</p>
<p><strong>[입력]</strong></p>
<ul>
<li>캐시 크기(cacheSize)와 도시이름 배열(cities)을 입력받는다.</li>
<li>cacheSize는 정수이며, 범위는 0 ≦ cacheSize ≦ 30 이다.</li>
<li>cities는 도시 이름으로 이뤄진 문자열 배열로, 최대 도시 수는 100,000개이다.</li>
<li>각 도시 이름은 공백, 숫자, 특수문자 등이 없는 영문자로 구성되며, 대소문자 구분을 하지 않는다. 도시 이름은 최대 20자로 이루어져 있다.</li>
</ul>
<p><strong>[출력]</strong></p>
<ul>
<li>입력된 도시이름 배열을 순서대로 처리할 때, &quot;총 실행시간&quot;을 출력한다.</li>
</ul>
<p><br></br></p>
<h2 id="문제-설명-👩🏫">문제 설명 👩‍🏫</h2>
<p>두 가지 입력 예시를 통해 문제를 어떻게 풀어야 할지 생각해보자.</p>
<blockquote>
<p><strong>#1</strong>
<strong>캐시 크기 :</strong> 3 
<strong>도시이름 :</strong> [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;, &quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;NewYork&quot;, &quot;LA&quot;] 
<strong>실행시간 :</strong> 50</p>
</blockquote>
<blockquote>
<p><strong>#2</strong>
<strong>캐시 크기 :</strong> 3 
<strong>도시이름 :</strong> [&quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;, &quot;Jeju&quot;, &quot;Pangyo&quot;, &quot;Seoul&quot;] 
<strong>실행시간 :</strong> 21</p>
</blockquote>
<p><br></br></p>
<h2 id="코드-👩💻">코드 👩‍💻</h2>
<pre><code class="language-python">from collections import deque

def solution(cacheSize, cities):
    answer = 0
    cache = deque(maxlen=cacheSize)  # maxlen: deque의 길이의 최댓값을 설정

    for c in cities:
        c = c.lower()   # 대소문자 구분 X

        # cache hit - 캐시 내 데이터가 존재할 경우
        # 같은 데이터가 중복해서 들어갈 수 없으므로 remove 후 다시 append 작업
        if c in cache:
            cache.remove(c)
            cache.append(c)
            answer += 1
        # cache miss - 캐시 내 데이터가 존재하지 않을 경우
        else:
            cache.append(c)
            answer += 5
    return answer
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준 1253] 좋다]]></title>
            <link>https://velog.io/@prairie_sky/%EB%B0%B1%EC%A4%80-1253-%EC%A2%8B%EB%8B%A4-Python</link>
            <guid>https://velog.io/@prairie_sky/%EB%B0%B1%EC%A4%80-1253-%EC%A2%8B%EB%8B%A4-Python</guid>
            <pubDate>Mon, 18 Oct 2021 07:48:29 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-📚">문제 📚</h2>
<p><a href="https://www.acmicpc.net/problem/1253">백준 1253번 문제 보기</a></p>
<p>N개의 수 중에서 어떤 수가 다른 수 두 개의 합으로 나타낼 수 있다면 그 수를 “좋다(GOOD)”고 한다. N개의 수가 주어지면 그 중에서 좋은 수의 개수는 몇 개인지 출력하라. 수의 위치가 다르면 값이 같아도 다른 수이다.</p>
<p><strong>[입력]</strong>
첫째 줄에는 수의 개수 N(1 ≤ N ≤ 2,000), 두 번째 줄에는 i번째 수를 나타내는 Ai가 N개 주어진다. (|Ai| ≤ 1,000,000,000, Ai는 정수)</p>
<p><strong>[출력]</strong>
좋은 수의 개수를 첫 번째 줄에 출력한다.</p>
<blockquote>
<p>** input #1 **
10
1 2 3 4 5 6 7 8 9 10 <br>
** output #1 **
8</p>
</blockquote>
<blockquote>
<p>** input #2 **
6
0 0 3 3 3 3  <br>
** output #2 **
4</p>
</blockquote>
<p><br></br></p>
<h2 id="문제-설명-👩🏫">문제 설명 👩‍🏫</h2>
<p><del>문제 설명이라 적고 입력 예제 설명이라 쓴다</del></p>
<blockquote>
<p><strong>두 개의 수의 합으로 나타낼 수 있는 수 = 좋은 수</strong>
<strong>input #1의 경우 주어진 숫자들 중에서,</strong>
1 2 3 4 5 6 7 8 9 10
1과 다른 수를 더했을 때 나올 수 있는 수 : 3,4,5,6,7,8,9,10
2와 다른 수를 더했을 때 나올 수 있는 수 : 3,5,6,7,8,9,10
3과 다른 수를 더했을 때 나올 수 있는 수 : 4,5,7,8,9,10
4와 다른 수를 더했을 때 나올 수 있는 수 : 5,6,7,9,10
5와 다른 수를 더했을 때 나올 수 있는 수 : 6,7,8,9
6과 다른 수를 더했을 때 나올 수 있는 수 : 7,8,9,10
7과 다른 수를 더했을 때 나올 수 있는 수 : 8,9,10
8과 다른 수를 더했을 때 나올 수 있는 수 : 9,10
9와 다른 수를 더했을 때 나올 수 있는 수 : 10 <br>
좋은 수는 3,4,5,6,7,8,9,10으로 총 8개</p>
</blockquote>
<p>기본 예제인 <strong>input #1</strong>만 보고 완전 탐색 풀이법을 시도했다. 두 수를 더해서 나올 수 있는 모든 경우를 구한 후, set 자료형을 이용해 중복을 배제하여 좋은 수를 카운트 했는데 낮은 정답률에 이유가 있듯 보기 좋게 틀렸다. 처음에는 이유를 몰라 헤맸었는데 <strong>input #2</strong>를 보고 어떻게 풀어야 하는지 감이 왔다. 더한 두 수를 제외했을 때, 좋은 수의 존재 여부를 고려해야 했었다.</p>
<blockquote>
<p><strong>input #2 의 경우 주어진 숫자들 중에서,</strong>
0 0 3 3 3 3
0+0=0인데 만족하는 좋은 수가 존재하지 않는다.
0+3=3으로 각각 4개의 경우의 수가 존재한다.
그러므로 출력값은 4가 된다.</p>
</blockquote>
<p><br></br></p>
<h2 id="코드-👩💻">코드 👩‍💻</h2>
<pre><code class="language-python"># 좋은 수의 개수를 세는 함수
def solve():
    cnt = 0
    nums.sort()
    for i in range(len(nums)):
        if search(i, nums[i]):
            cnt += 1
    print(cnt)


# 좋은 수가 들어있는지 탐색하는 함수
def search(i, target):
    temp = nums[:i] + nums[i+1:]  # 타겟이 되는 nums[i]를 제외하고 탐색
    # print(temp)
    left = 0
    right = n-2  # 마지막 인덱스 n-1에서 타겟값 하나 더 빼서 n-2
    while left &lt; right:
        sum = temp[left] + temp[right]
        if target &lt; sum:
            right -= 1
        elif target &gt; sum:
            left += 1
        else:
            # print(i,target)
            return True
    return False


import sys
input = sys.stdin.readline

n = int(input())
nums = list(map(int, input().split()))
solve()
</code></pre>
<blockquote>
<p>target 값을 정하고 nums[i] (= target) 값을 제외한 배열에서 left, right 투 포인터를 이용한 탐색을 진행한다. 이런 식으로 풀이하면 <strong>input #2</strong>에서 두 수의 합이 배열 내에 존재하지 않을 경우를 고려하여 문제를 해결할 수 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[파이썬 알고리즘] 공주 구하기(큐)]]></title>
            <link>https://velog.io/@prairie_sky/%EA%B3%B5%EC%A3%BC-%EA%B5%AC%ED%95%98%EA%B8%B0%ED%81%90</link>
            <guid>https://velog.io/@prairie_sky/%EA%B3%B5%EC%A3%BC-%EA%B5%AC%ED%95%98%EA%B8%B0%ED%81%90</guid>
            <pubDate>Tue, 21 Sep 2021 10:39:55 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-📚">문제 📚</h2>
<p>어느 왕국의 이웃 나라 외동딸 공주가 숲 속의 괴물에게 잡혀갔습니다.
왕국에는 왕자가 N명이 있는데 서로 공주를 구하러 가겠다고 합니다. 왕국의 왕은 다음과 같은 방법으로 공주를 구하러 갈 왕자를 결정하기로 했습니다.</p>
<p>왕은 왕자들을 나이 순으로 1번부터 N번까지 차례로 번호를 매기고 1번 왕자부터 N번 왕자까지 순서대로 시계 방향으로 돌아가게 동그랗게 앉게 합니다. 그리고 1번 왕자부터 시계 방향으로 돌아가며 1부터 시작하여 번호를 외치게 합니다. 한 왕자가 K(특정 숫자)를 외치면 그 왕자는 공주를 구하러 가는데서 제외되고 원 밖으로 나오게 됩니다. 그리고 다음 왕자부터 다시 1부터 시작하여 번호를 외칩니다.</p>
<p>이렇게 해서 마지막까지 남은 왕자가 공주를 구하러 갈 수 있습니다.</p>
<p><strong>input</strong>
8 3</p>
<p><strong>output</strong>
7</p>
<p><br></br></p>
<h2 id="문제-설명-👩🏫">문제 설명 👩‍🏫</h2>
<p><img src="https://images.velog.io/images/prairie_sky/post/148863ca-a1fa-4366-8c8e-7abf7c72e26d/Screenshot_20210921-191623_Samsung%20Notes.jpg" alt=""></p>
<blockquote>
<p><strong>k=3번째 수만 빼준다.</strong>
1,2,3,4,5,6,7,8 - 뺀 수
1,2,4,5,6,7,8 - 3 
1,2,4,5,7,8 - 6
2,4,5,7,8 - 1
2,4,7,8 - 5
4,7,8 - 2
4,7 - 8
7 - 4</p>
</blockquote>
<p><br></br></p>
<h2 id="코드-👩💻">코드 👩‍💻</h2>
<pre><code class="language-python">from collections import deque

def solution(n, k):
    dq = list(range(1, n+1))
    prince = deque(dq)
    while prince:
        for i in range(k-1):
            cur = prince.popleft()
            prince.append(cur)
        prince.popleft()
        if len(prince) == 1:
            return prince[0]


n, k = map(int, input().split())
print(solution(n,k))</code></pre>
<blockquote>
<p>양방향에서 더하고 뺄 수 있는 <strong>deque</strong> 모듈을 이용해서 풀었다. k번째 전까지는 남아있어야 하는 원소이므로 왼쪽의 원소를 빼고 다시 오른쪽에 이어붙인다. k번째 수는 문제에서 설명했던 대로 그냥 빼준다.
이 작업은 deque가 비어있지 않는 동안 계속 반복되고, deque의 길이가 1이 될때 함수 결과값을 return 해줌으로써 끝이 난다.</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>