<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Being Programmer</title>
    <link>https://joyjangs.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Mon, 24 Aug 2026 11:21:04 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>joyjang</managingEditor>
    <image>
      <title>Being Programmer</title>
      <url>https://tistory1.daumcdn.net/tistory/4835006/attach/2518905d90e24203abdb85db3cf9f405</url>
      <link>https://joyjangs.tistory.com</link>
    </image>
    <item>
      <title>[CodeUp] Python 기초 100제 - 6010~6020</title>
      <link>https://joyjangs.tistory.com/39</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6010. 정수 1개 입력받아 int로 변환하여 출력하기 &lt;a href=&quot;https://codeup.kr/problem.php?id=6010&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;n = int(input())
print(n)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬에서의 모든 입력은 한 줄의 &lt;code&gt;str&lt;/code&gt; 클래스로 입력된다. 원하는 형태에서의 계산을 위해서는 반드시 &lt;b&gt;형변환&lt;/b&gt;이 필요하다.&lt;br /&gt;파이썬에는 char형이 따로 없다. &lt;code&gt;chr&lt;/code&gt;함수가 char형으로 변환해준다고 나와있지만 정확히는 크기가 1인 &lt;code&gt;str&lt;/code&gt; 클래스로 변환해주는 함수이다. 기본적으로 &lt;code&gt;int&lt;/code&gt;는 28bit, &lt;code&gt;str&lt;/code&gt;은 50bit의 크기를 가지고 사이즈가 커지면서 거의 무한하게(메모리 크기만큼) 커질 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6011. 실수 1개 입력받아 변환하여 출력하기&lt;a href=&quot;https://codeup.kr/problem.php?id=6011&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;f = float(input())
print(f)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬에서는 &lt;code&gt;float&lt;/code&gt;함수를 사용하면 문자열로 나타내어진 숫자를 &lt;b&gt;실수&lt;/b&gt;로 변환할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6012. 정수 2개 입력받아 그대로 출력하기1 &lt;a href=&quot;https://codeup.kr/problem.php?id=6012&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;a = int(input())
b = int(input())
print(a)
print(b)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;input&lt;/code&gt;함수는 개행문자까지 입력을 받기 때문에 두 줄로 입력되는 입력에 대해서 두 번 &lt;code&gt;input&lt;/code&gt;을 해주어야 한다. &lt;code&gt;print&lt;/code&gt;도 마찬가지로 &lt;code&gt;default&lt;/code&gt;로 &lt;b&gt;줄바꿈&lt;/b&gt;이 되기 때문에 두 번 함수를 실행해 주어야 한다.&lt;br /&gt;만약 출력을 한 번만 실행을 하고 싶다면 다음과 같은 방법이 존재한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;print(a, b, sep='\n')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;input&lt;/code&gt;의 경우에는 &lt;code&gt;input().split('\n')&lt;/code&gt;으로 줄바꿈을 나누어서 입력을 받지 못하므로 한 번씩 사용해주어야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6013. 문자 2개 입력받아 순서 바꿔 출력하기1 &lt;a href=&quot;https://codeup.kr/problem.php?id=6013&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;a = input()
b = input()
print(b)
print(a)&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6014. 실수 1개 입력받아 3번 출력하기 &lt;a href=&quot;https://codeup.kr/problem.php?id=6014&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;f = float(input())
print(f, f, f, sep='\n')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 값을 3번 출력하는 방법은 다양하다. &lt;code&gt;print&lt;/code&gt;를 3번 사용해도 되고 &lt;code&gt;for&lt;/code&gt;문 같은 반복문을 사용해도 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6015. 정수 2개 입력받아 그대로 출력하기2 &lt;a href=&quot;https://codeup.kr/problem.php?id=6015&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;a, b = map(int, input().split())
print(a, b, sep='\n')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;input().split()&lt;/code&gt;함수에서는 공백을 default로 문자열을 나누어서 리스트에 저장한다. 따라서 &lt;code&gt;input().split()&lt;/code&gt;은 &lt;code&gt;list&lt;/code&gt;를 반환한다.&lt;br /&gt;&lt;code&gt;map&lt;/code&gt;함수의 첫 번째 인자는 하나의 함수이고 두 번째 인자는 리스트나 튜플같이 iterable한 자료형이다. &lt;code&gt;map&lt;/code&gt;은 첫 번째 인자로 들어온 함수를 두 번째 인자의 &lt;b&gt;각각의 요소들에 적용시키는 함수&lt;/b&gt;이다.&lt;br /&gt;위에서는 &lt;code&gt;input().split()&lt;/code&gt;의 결과로 ['1', '2']가 &lt;code&gt;map&lt;/code&gt;의 두 번째 인자가 될 것이고 '1'과 '2'에 각각 &lt;code&gt;int&lt;/code&gt;를 적용하여 &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;에 저장한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6016. 문자 2개 입력받아 순서 바꿔 출력하기2 &lt;a href=&quot;https://codeup.kr/problem.php?id=6016&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;a, b = input().split()
print(b, a)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;print&lt;/code&gt;함수에 여러 개의 입력이 있는 경우 default값으로 두 값 사이에 공백이 생기도록 출력한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6017. 문장 1개 입력받아 3번 출력하기 &lt;a href=&quot;https://codeup.kr/problem.php?id=6017&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;s = input()
print(s, s, s)&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6018. 시간 입력받아 그대로 출력하기 &lt;a href=&quot;https://codeup.kr/problem.php?id=6018&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;h, m = input().split(':')
print(h, m, sep=':')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;split&lt;/code&gt;함수에 &lt;code&gt;':'&lt;/code&gt;를 입력으로 넣게 되면 &lt;code&gt;':'&lt;/code&gt;를 기준으로 문자를 나누어서 리스트에 저장한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6019. 연월일 입력받아 순서 바꿔 출력하기 &lt;a href=&quot;https://codeup.kr/problem.php?id=6019&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;y, m, d = input().split('.')
print(d, m, y, sep='-')&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;gt; 6020. 주민번호 입력받아 형태 바꿔 출력하기 &lt;a href=&quot;https://codeup.kr/problem.php?id=6020&quot;&gt;&amp;larr;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;front, back = input().split('-')
print(front, back, sep='')&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;</description>
      <category>프로그래밍/CodeUp</category>
      <category>CodeUp</category>
      <category>python</category>
      <category>기초100제</category>
      <category>파이썬</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/39</guid>
      <comments>https://joyjangs.tistory.com/39#entry39comment</comments>
      <pubDate>Mon, 20 Jun 2022 22:56:01 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 편집 거리 알고리즘 ( Edit Distance )</title>
      <link>https://joyjangs.tistory.com/38</link>
      <description>&lt;h1&gt;&lt;b&gt;[Python] 편집거리 알고리즘&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;편집거리 알고리즘&lt;/b&gt;은 &lt;b&gt;두 문자열의 유사도를 판단하는 알고리즘&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;수정, 삽입, 삭제&lt;/b&gt; 기능이 있다고 할 때 몇 번의 동작이 필요한지 측정한다. 문자열 내에서 위치 변환 같은 기능이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원 메모이제이션 배열을 사용하는 &lt;b&gt;Dynamic Programming&lt;/b&gt;의 한 종류이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;편집거리 알고리즘의 규칙&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;str1&lt;/code&gt;에서 &lt;code&gt;i&lt;/code&gt;번째 문자와 &lt;code&gt;str2&lt;/code&gt;에서 &lt;code&gt;j&lt;/code&gt;번째 문자를 서로 비교한다.&lt;/li&gt;
&lt;li&gt;두 문자가 같으면 &lt;code&gt;dp[i-1][j-1]&lt;/code&gt;의 값을 그대로 가져온다.&lt;/li&gt;
&lt;li&gt;두 문자가 다르면 &lt;code&gt;dp[i-1][j]&lt;/code&gt;, &lt;code&gt;dp[i][j-1]&lt;/code&gt;, &lt;code&gt;dp[i-1][j-1]&lt;/code&gt; 중 최소값에 1을 더해서 &lt;code&gt;dp[i][j]&lt;/code&gt;에 저장&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;설명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;편집 거리를 계산할 때 &lt;b&gt;기준을 먼저 잡아야 한다&lt;/b&gt;. 왼쪽 문자열에서 위쪽 문자열로 변환한다고 기준을 잡겠다. 왼 쪽의 H와 위 쪽의 H를 비교할 때는 'PH' 가 'PYTH' 가 되기 위해서 연산이 몇 번 필요한 지 확인하는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;C:%5CUsers%5CJONGIN%5CPictures%5C%ED%8E%B8%EC%A7%91%EA%B1%B0%EB%A6%AC%5C%EA%B7%B8%EB%A6%BC1.png&quot; alt=&quot;&quot; /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2126&quot; data-origin-height=&quot;1435&quot; data-filename=&quot;그림1.png&quot; width=&quot;400&quot; height=&quot;270&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9tyyz/btrhsf9gLL2/7h1o6HCj5UsYBKU9vGxTMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9tyyz/btrhsf9gLL2/7h1o6HCj5UsYBKU9vGxTMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9tyyz/btrhsf9gLL2/7h1o6HCj5UsYBKU9vGxTMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9tyyz%2Fbtrhsf9gLL2%2F7h1o6HCj5UsYBKU9vGxTMK%2Fimg.png&quot; data-origin-width=&quot;2126&quot; data-origin-height=&quot;1435&quot; data-filename=&quot;그림1.png&quot; width=&quot;400&quot; height=&quot;270&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 상태는 위와 같다. 첫 행으로 설명을 하자면 빈 문자열{} 이 {}, P, PY, PYT, ... 로 바뀌기 위해서 몇 번의 연산이 필요한 지 나타내는 것이다. {}에서 {}이 되려면 아무 연산이 필요 없으므로 0, PYT가 되려면 P, Y, T를 각각 삽입해야 하므로 3이 된다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;C:%5CUsers%5CJONGIN%5CPictures%5C%ED%8E%B8%EC%A7%91%EA%B1%B0%EB%A6%AC%5C%EA%B7%B8%EB%A6%BC3.png&quot; alt=&quot;&quot; /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2442&quot; data-origin-height=&quot;1267&quot; data-filename=&quot;그림3.png&quot; width=&quot;400&quot; height=&quot;208&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceBMpo/btrhjYs2mux/65Xg01JGskB4fCKaFXlx5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceBMpo/btrhjYs2mux/65Xg01JGskB4fCKaFXlx5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceBMpo/btrhjYs2mux/65Xg01JGskB4fCKaFXlx5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceBMpo%2FbtrhjYs2mux%2F65Xg01JGskB4fCKaFXlx5k%2Fimg.png&quot; data-origin-width=&quot;2442&quot; data-origin-height=&quot;1267&quot; data-filename=&quot;그림3.png&quot; width=&quot;400&quot; height=&quot;208&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'PH'가 'PYTH'가 되기 위한 연산의 수는 'P'를 'PYT'로 바꾸는 연산의 수와 같다. 두 문자열에서 똑같은 'H'를 붙이는 것이기 때문이다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;C:%5CUsers%5CJONGIN%5CPictures%5C%ED%8E%B8%EC%A7%91%EA%B1%B0%EB%A6%AC%5C%EA%B7%B8%EB%A6%BC4.png&quot; alt=&quot;&quot; /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2478&quot; data-origin-height=&quot;1617&quot; data-filename=&quot;그림4.png&quot; width=&quot;400&quot; height=&quot;261&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmhZuK/btrhnbr4tKu/AeWOymHWKWQYx5rI14rrR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmhZuK/btrhnbr4tKu/AeWOymHWKWQYx5rI14rrR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmhZuK/btrhnbr4tKu/AeWOymHWKWQYx5rI14rrR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmhZuK%2Fbtrhnbr4tKu%2FAeWOymHWKWQYx5rI14rrR1%2Fimg.png&quot; data-origin-width=&quot;2478&quot; data-origin-height=&quot;1617&quot; data-filename=&quot;그림4.png&quot; width=&quot;400&quot; height=&quot;261&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'O'와 'H'를 비교한 경우를 생각해보자.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;A의 경우&lt;/b&gt;를 보면 'PH'에서 'PYT'로 2번의 연산으로 변환이 되었다고 생각한다. 다음 줄로 오면서 'O'가 더해지고 'PYTO'가 된 상황이다. 이 때는 'O'를 'H'로 &lt;b&gt;수정&lt;/b&gt; 연산을 하면 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;B의 경우&lt;/b&gt; 'PH'를 'PYTH'로 2번의 연산으로 변환이 되었다고 생각한다. 마찬가지로 다음 줄로 넘어가면서 'O'가 더해지고 'PYTHO'가 된 상황이다. 이 경우에는 'O'를 &lt;b&gt;삭제&lt;/b&gt; 연산을 하게 되면 'PYTH'로 만들 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;C의 경우&lt;/b&gt; 'PHO'를 'PYT'로 2번의 연산으로 변환이 되었다고 생각한다. 이 경우에는 다음 줄이 되는 것이 아니므로 'O'가 더해지는 것은 아니다. 'PYT'에서 'H'를 &lt;b&gt;삽입&lt;/b&gt;하는 연산을 하게 되면 'PYTH'로 만들 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각의 횟수는 2번의 연산에 한 번 더 연산을 하는 과정이 필요하므로 3번 연산을 하면 'PHO'를 'PYTH'로 바꿀 수 있다. 우리는 최소 편집 거리를 찾기 때문에 &lt;b&gt;A, B, C 과정을 한 후 최소값&lt;/b&gt;을 dp 테이블에 넣어주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 같은 문자끼리 비교하는 경우에는 A의 연산의 특수한 경우로 생각하면 된다. 수정 연산을 생각할 때 두 문자가 같으므로 수정을 굳이 안 해도 되는 경우라고 생각한다. 그리고 &lt;b&gt;&lt;code&gt;dp[i-1][j-1]&lt;/code&gt;&lt;/b&gt;은 &lt;code&gt;dp[i-1][j] + 1&lt;/code&gt;, &lt;code&gt;dp[i][j-1] + 1&lt;/code&gt;과 비교했을 때 &lt;b&gt;최솟값을 가지는 것이 보장&lt;/b&gt;된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결과&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;C:%5CUsers%5CJONGIN%5CPictures%5C%ED%8E%B8%EC%A7%91%EA%B1%B0%EB%A6%AC%5C%EA%B7%B8%EB%A6%BC5.png&quot; alt=&quot;&quot; /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;654&quot; data-filename=&quot;그림5.png&quot; width=&quot;400&quot; height=&quot;271&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VBXWx/btrhjX8It2X/ByiLxki5WY8oVPj275fNs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VBXWx/btrhjX8It2X/ByiLxki5WY8oVPj275fNs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VBXWx/btrhjX8It2X/ByiLxki5WY8oVPj275fNs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVBXWx%2FbtrhjX8It2X%2FByiLxki5WY8oVPj275fNs1%2Fimg.png&quot; data-origin-width=&quot;967&quot; data-origin-height=&quot;654&quot; data-filename=&quot;그림5.png&quot; width=&quot;400&quot; height=&quot;271&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 계산이 끝난 후의 결과는 그림과 같다. 이 후에 우리는 &lt;code&gt;dp[-1][-1]&lt;/code&gt;을 계산하면 최소 편집 거리를 구할 수 있다. &lt;b&gt;최소 편집 거리를 만드는 경로는 여러가지&lt;/b&gt;가 될 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CODE&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;def edit_dist(str1, str2):
    dp = [[0] * (len(str2)+1) for _ in range(len(str1) + 1)]
    for i in range(1, len(str1)+1):
        dp[i][0] = i
    for j in range(1, len(str2)+1):
        dp[0][j] = j

    for i in range(1, len(str1)+1):
        for j in range(1, len(str2)+1):
            if str1[i-1] == str2[j-1]:
                dp[i][j] = dp[i-1][j-1]

            else:
                dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1

    return dp[-1][-1]


print(edit_dist('PYTHON', 'PHOTO'))     # 4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/Python</category>
      <category>Levenshtein Distance</category>
      <category>python</category>
      <category>파이썬</category>
      <category>편집거리</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/38</guid>
      <comments>https://joyjangs.tistory.com/38#entry38comment</comments>
      <pubDate>Tue, 12 Oct 2021 21:55:55 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 소수 판별 알고리즘</title>
      <link>https://joyjangs.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script src=&quot;https://polyfill.io/v3/polyfill.min.js?features=es6&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;h1&gt;[Python] 소수 판별 알고리즘&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도가 낮은 알고리즘 문제 중에서 자주 나오는 문제가 소수 판별 문제이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소수 : 1과 자기 자신 이외에 약수를 가지지 않는 2 이상의 자연수&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소수를 판별하는 방법은 크게 두 가지로 나뉜다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;반복문 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 방법은 반복문 사용이다. 자연수 n이 소수인지 판별하기 위해서 2부터 \( [\sqrt{n}] \)까지 나누었을 때 나머지가 0이 있는지 확인하는 방법이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Code&lt;/h4&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;from math import sqrt

def is_prime(n):
    if n &amp;lt; 2:
        return False
    for i in range(2, int(sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;sqrt(n)&lt;/code&gt;까지만 확인하는 이유는 \( \sqrt{n} \) 보다 큰 약수는 이미 작은 약수를 확인하면서 확인하기 때문이다. 예를 들어서 &lt;code&gt;n&lt;/code&gt;이 20인 경우 36의 약수는 1, 2, 3, 4, 6, 9, 12, 18, 36 이지만 9, 12, 18은 4, 3, 2와 한쌍이기 때문에 6까지만 검사하게 되면 9, 12, 18이 36의 약수인 것을 알 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;에라토스테네스의 체&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아스토스테네스의 체는 여러 개의 소수를 판별할 때 유용하다. 또는 큰 수에 대해서 소수 여부를 판별할 때 시간복잡도가 많이 개선된다. 크기가 &lt;code&gt;n&lt;/code&gt;인 배열을 만든 후에 처음 두 칸은 &lt;code&gt;False&lt;/code&gt;로 설정하고 이후의 배열은 모두 &lt;code&gt;True&lt;/code&gt;로 초기화해준다. 이후 배열을 한 번 순회하면서 소수를 찾고 소수의 배수들을 모두 False로 변환해준다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Code&lt;/h4&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;def is_prime(n):
    prime = [False, False, True] + [True, False] * ( (n - 1) // 2)
    # 2를 제외한 모든 짝수는 소수가 아님
    for i in range(3, n+1, 2):
        if prime[i]:
            for j in range(i*i, n+1, 2*i):
                prime[j] = False

    return prime[n]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드의 베이스라인은 위와 같다. 소수 판별 문제에서는 어떤 수가 소수인지 판별하는 문제도 있지만 &lt;code&gt;n&lt;/code&gt;이하의 자연수 중 소수가 몇 개인지, 어떤 수들인지를 알기 위한 문제가 많다. &lt;code&gt;j&lt;/code&gt;에 대한 &lt;code&gt;for&lt;/code&gt;문에서 범위가 &lt;code&gt;i * i&lt;/code&gt; 부터 &lt;code&gt;n + 1&lt;/code&gt;까지 간격은 &lt;code&gt;2 * i&lt;/code&gt;로 큰 수들을 &lt;code&gt;False&lt;/code&gt;로 변환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;i * i&lt;/code&gt;부터 시작하는 이유는 &lt;code&gt;i * (i - 2), i * (i - 4), ...&lt;/code&gt;은 &lt;code&gt;i - 2&lt;/code&gt;번 째 반복문에서 &lt;code&gt;(i - 2) * (i - 2) + 2 * (i - 2)&lt;/code&gt;가 되어서 한 번 방문을 했거나 또는 소수가 아닌 수의 배수이기 때문에 방문할 필요가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;2 * i&lt;/code&gt;씩 건너띄는 이유는 간단하다. 홀수에 짝수를 더하면 홀수이기 때문이다. 짝수는 2를 제외하고는 소수가 아니기 때문에 굳이 방문할 필요가 없다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;n = 1000000
prime = [False, False, True] + [True, False] * ((n - 1) // 2)
prime_number = [2]
for i in range(3, n+1, 2):
    if prime[i]:
        if i &amp;gt; 1000:                    
            prime_number.append(i)
        for j in range(i*i, n+1, 2*i):    # i * i 이하의 수는 i 전에 한 번씩 검사됨
            prime[j] = False

print(prime_number)        # 1,000과 1,000,000 사이의 소수
print(len(prime_number))# 1,000과 1,000,000 사이 소수의 개수&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 처럼 &quot;1,000보다 큰 소수를 모두 구하여라.&quot; 같은 문제를 풀 때 에라토스테네스의 체가 유용하게 쓰이고 많은 알고리즘 문제를 해결할 때 에라토스테네스의 체를 사용하다.&lt;br /&gt;하지만 무조건적으로 에라토스 테네스의 체가 좋다고 얘기할 순 없다. &lt;code&gt;n&lt;/code&gt;이 소수인지 판별하기 위해서 크기가 &lt;code&gt;n+1&lt;/code&gt;인 리스트를 생성해야 한다. 이론상 &lt;code&gt;O(Nlog(logN))&lt;/code&gt;이라고 되어 있고 반복문을 사용할 때는 &lt;code&gt;O(sqrt(N))&lt;/code&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1000000007 과 같은 큰 소수가 소수인지 판별하는 데에는 반복문을 사용하는 것이 훨씬 빠르다는 얘기다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Code&lt;/h4&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import time
from math import sqrt


def is_prime(n):
    prime = [False, False] + [True] * (n - 1)
    for i in range(3, int(sqrt(n))+1, 2):
        if prime[i]:
            for j in range(i*i, n+1, 2*i):
                prime[j] = False

    return prime[n]


def is_prime2(n):
    if n % 2 == 0:
        return False
    for i in range(3, int(sqrt(n))+1, 2):
        if n % i == 0:
            return False
    return True


start = time.time()
is_prime(1000000007)        # 에라토스테네스의 체
print(time.time() - start)

start = time.time()
is_prime2(1000000007)       # 반복문 사용
print(time.time() - start)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;50&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccHEMP/btrhfzz0xUh/duVw76wLNuFFuMhixrGGHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccHEMP/btrhfzz0xUh/duVw76wLNuFFuMhixrGGHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccHEMP/btrhfzz0xUh/duVw76wLNuFFuMhixrGGHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccHEMP%2Fbtrhfzz0xUh%2FduVw76wLNuFFuMhixrGGHK%2Fimg.png&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;50&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에라토스테네스의 체도 &lt;code&gt;sqrt(n)&lt;/code&gt;까지만 해서 &lt;code&gt;n&lt;/code&gt;이 소수인지 판별하도록 했음에도 불구하고 출력 결과에서 보면 많이 차이가 나는 것을 알 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에라토스테네스의 체를 사용하게 되면 여러 개의 소수를 한 번에 구할 수 있고, 한 번 구해놓고 나면 O(1)로도 판별이 가능하기 때문에 여러 개의 소수를 구하는 경우에는 꼭 에라토스테네스의 체를 사용하는 것이 좋다. 입력이 하나이고 그 수가 소수인지 판별할 때는 그냥 간단하게 반복문을 사용하는 것이 좋다.&lt;/p&gt;</description>
      <category>프로그래밍/Python</category>
      <category>python</category>
      <category>소수 판별</category>
      <category>에라토스테네스의 체</category>
      <category>파이썬</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/37</guid>
      <comments>https://joyjangs.tistory.com/37#entry37comment</comments>
      <pubDate>Mon, 11 Oct 2021 23:30:48 +0900</pubDate>
    </item>
    <item>
      <title>[백준][파이썬] 23080번 - 스키테일 암호</title>
      <link>https://joyjangs.tistory.com/36</link>
      <description>&lt;h1&gt;&lt;b&gt;[백준][파이썬] 23080번 - 스키테일 암호&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 번호 : 23080번 - 스키테일 암호&lt;br /&gt;문제 출처 : &lt;a href=&quot;https://www.acmicpc.net/problem/23080&quot;&gt;https://www.acmicpc.net/problem/23080&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1633618155728&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;23080번: 스키테일 암호&quot; data-og-description=&quot;첫 번째 줄에&amp;nbsp;막대의 굵기 \(K\)가 주어진다.&amp;nbsp;두 번째 줄에&amp;nbsp;알파벳 소문자만으로 구성된 암호문 \(S\)가 주어진다.&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/23080&quot; data-og-url=&quot;https://www.acmicpc.net/problem/23080&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bNtTdj/hyLSvl4SOv/HUHcBE7KfKILryNkGTgqKk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/23080&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/23080&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bNtTdj/hyLSvl4SOv/HUHcBE7KfKILryNkGTgqKk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;23080번: 스키테일 암호&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 줄에&amp;nbsp;막대의 굵기 \(K\)가 주어진다.&amp;nbsp;두 번째 줄에&amp;nbsp;알파벳 소문자만으로 구성된 암호문 \(S\)가 주어진다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;2120&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KTSSO/btrg8cRcIUB/uoMKKAjIwr4GYN4u1QDZB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KTSSO/btrg8cRcIUB/uoMKKAjIwr4GYN4u1QDZB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KTSSO/btrg8cRcIUB/uoMKKAjIwr4GYN4u1QDZB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKTSSO%2Fbtrg8cRcIUB%2FuoMKKAjIwr4GYN4u1QDZB1%2Fimg.png&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;2120&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Code&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;k = int(input())
s = input()

answer = ''
for i in range(0, len(s), k):
    answer += s[i]

print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Idea&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;막대 둘레에 따라서 문자열을 출력하면 되는 간단한 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;s\[k\*0\], s\[k\*1\], s\[k\*2\], ...&lt;/code&gt; 순으로 출력하면 되기 때문에 &lt;code&gt;range(시작, 끝, 간격)&lt;/code&gt; 을 이용해서 &lt;code&gt;k&lt;/code&gt;마다 문자를 출력했다.&lt;/p&gt;</description>
      <category>프로그래밍/BAEKJOON</category>
      <category>IUPC</category>
      <category>구현</category>
      <category>문자열</category>
      <category>백준</category>
      <category>스키테일 암호</category>
      <category>파이썬</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/36</guid>
      <comments>https://joyjangs.tistory.com/36#entry36comment</comments>
      <pubDate>Thu, 7 Oct 2021 23:50:35 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 진수 변환</title>
      <link>https://joyjangs.tistory.com/35</link>
      <description>&lt;h1&gt;[Python] 진수 변환&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩테스트 문제들을 풀다보면 진수 변환을 하는 문제가 자주 등장한다. 오늘은 진수 변환을 하는 방법 2가지를 소개한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;10 진수 -&amp;gt; n 진수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10진수를 n 진수로 바꾸는 것은 학생 때 배웠던 2진법 변환방법을 코드로 구현한 것과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바꾸고 싶은 수를 n으로 나누고 나머지와 몫을 확인한다. 몫이 0이 되면 나머지들을 역순으로 문자열에 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;600&quot; height=&quot;314&quot; data-origin-width=&quot;3272&quot; data-origin-height=&quot;1711&quot; data-filename=&quot;이진법.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xw2y4/btrgDUwBE9I/4m6J9QEH3CnqEL3k8wk82K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xw2y4/btrgDUwBE9I/4m6J9QEH3CnqEL3k8wk82K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xw2y4/btrgDUwBE9I/4m6J9QEH3CnqEL3k8wk82K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxw2y4%2FbtrgDUwBE9I%2F4m6J9QEH3CnqEL3k8wk82K%2Fimg.png&quot; width=&quot;600&quot; height=&quot;314&quot; data-origin-width=&quot;3272&quot; data-origin-height=&quot;1711&quot; data-filename=&quot;이진법.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 반복문 사용&lt;/h3&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;def convert_iter(num, base):
    power = 0
    tmp = ''
    while num:
        tmp = str(num%base) + tmp
        num //= base
    return tmp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법으로는 10진수까지의 변환만 가능하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 재귀함수 사용&lt;/h3&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;import string

def convert_recur(num, base):
    number = string.digits + string.ascii_uppercase
    q, r = divmod(num, base)
    return convert_recur(q, base) + number[r] if q else number[r]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;string.digits = '0123456789'&lt;/code&gt;이고 &lt;code&gt;string.ascii_uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'&lt;/code&gt;이다. 둘 다 문자열이고 따라서 우리가 구하고자 하는 수가 x일 때 &lt;code&gt;number[x] = 'x'&lt;/code&gt;로 11 진수 이상의 진법도 표현 가능하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;n 진수 -&amp;gt; 10진수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n 진수를 10진수로 바꾸는 방법은 굉장히 간단하다. 내장 &lt;code&gt;int&lt;/code&gt;함수에 구현되어 있다. 사용 방법은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;hsp&quot;&gt;&lt;code&gt;base_2 = '10011010010'
base_8 = '2322'
base_16 = '4d2'

print(int(base_2, 2))    # 1234
print(int(base_8, 8))    # 1234
print(int(base-16, 16)) # 1234&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;int(number_string, base)&lt;/code&gt;로 나타낼 수 있다. 첫 번째 인자는 무조건 문자열이어야 하고 &lt;code&gt;base&lt;/code&gt;가 달라지면 값도 달라진다. 그리고 만약 문자열이 &lt;code&gt;'1234'&lt;/code&gt;인데 2진법으로 나타낸 수라고 하는 것은 에러가 발생한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이외의 방법들&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;내장 함수 사용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2진법, 8진법, 16진법은 파이썬 내장 함수로 진수 변환이 가능하다.&lt;/p&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;h = hex(1234)
o = oct(1234)
b = bin(1234)

print(h)    # '0x4d2'
print(o)    # '0o2322'
print(b)    # '0b10011010010'
# 다시 10진수로 변환하기
print(int(h, 16)) # 1234
print(int(o, 8)) # 1234
print(int(b, 2)) # 1234&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;변환 시간 측정&lt;/h3&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;import time

start = time.time()
for _ in range(100000):
    bin(1234)
print(&quot;내장 함수 시간 : {}&quot;.format(time.time()-start))

start = time.time()
for _ in range(100000):
    convert_iter(1234, 2)
print(&quot;반복 함수 시간 : {}&quot;.format(time.time()-start))

start = time.time()
for _ in range(100000):
    convert_recur(1234, 2)
print(&quot;재귀 함수 시간 : {}&quot;.format(time.time()-start))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;68&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW7Wvv/btrgDVvtltf/pKftk2uRUDndX18hGOXc4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW7Wvv/btrgDVvtltf/pKftk2uRUDndX18hGOXc4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW7Wvv/btrgDVvtltf/pKftk2uRUDndX18hGOXc4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW7Wvv%2FbtrgDVvtltf%2FpKftk2uRUDndX18hGOXc4K%2Fimg.png&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;68&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확실히 파이썬은 내장 함수를 안다면 무조건 내장함수를 쓰는 것이 효율적이다. 재귀 함수가 오히려 더 효율이 좋을 거라 생각했는데 반복 함수를 사용할 때가 더 효율이 좋다. 시간 복잡도의 차이보다 함수 호출에서 시간이 조금 더 걸려서인 듯 하다.&lt;/p&gt;</description>
      <category>python</category>
      <category>진법</category>
      <category>진수</category>
      <category>진수변환 시간</category>
      <category>파이썬</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/35</guid>
      <comments>https://joyjangs.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 3 Oct 2021 01:31:17 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조][Python] : Queue with 2 Stacks(스택으로 큐 구현하기)</title>
      <link>https://joyjangs.tistory.com/34</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;자료구조 with Python : 스택 2개로 큐 구현하기&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐를 구현하는 방법 중 하나는 스택을 두 개 사용하는 것이다. 여기서는 스택 자료구조를 직접 사용하지 않고 파이썬 내장 리스트를 사용하여 스택을 대신한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;큐의 구조&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;enqueue : 뒤 쪽으로 원소를 삽입하는 함수&lt;/li&gt;
&lt;li&gt;dequeue : 가장 앞에 위치한 원소를 제거하면서 반환하는 함수&lt;/li&gt;
&lt;li&gt;is_empty : 큐가 비어있는지 확인하는 함수&lt;/li&gt;
&lt;li&gt;transfer : in_stack의 원소들을 모두 out_stack으로 옮기는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스택 2개를 사용한 큐의 구현&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;class Queue(object):
    def __init__(self):
        self.in_stack = []
        self.out_stack = []

    def isEmpty(self):
        return not(bool(self.in_stack) or bool(self.out_stack))

    def transfer(self):
        while self.in_stack:
            self.out_stack.append(self.in_stack.pop())

    def enqueue(self, item):
        return self.in_stack.append(item)

    def dequeue(self):
        if not self.out_stack:
            self.transfer()
        if not self.isEmpty():
            return self.out_stack.pop()
        else:
            print(&quot;Queue is empty!&quot;)

    def __repr__(self):
        tmp = []
        tmp += self.out_stack[::-1]
        tmp += self.in_stack
        if tmp:
            return repr(tmp)
        else:
            return &quot;Queue is empty!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;enqueue&lt;/code&gt;를 하게 되면 &lt;code&gt;in_stack&lt;/code&gt; 리스트에 데이터를 입력한다. 그러다 &lt;code&gt;dequeue&lt;/code&gt;를 실행했을 때 &lt;code&gt;out_stack&lt;/code&gt;이 비어있으면 &lt;code&gt;in_stack&lt;/code&gt;의 모든 원소들을 &lt;code&gt;pop&lt;/code&gt;하여서 가져온다. 이후에 &lt;code&gt;out_stack&lt;/code&gt;의 원소들을 &lt;code&gt;pop&lt;/code&gt;하게 되면 큐의 동작처럼 FIFO로 데이터가 출력되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;확인코드&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;queue = Queue()
for i in range(1, 4):
    queue.enqueue(i)
print(queue)
print(&quot;dequeue: {0}&quot;.format(queue.dequeue()))
print(&quot;dequeue: {0}&quot;.format(queue.dequeue()))
queue.enqueue(4)
queue.enqueue(5)
print(queue)
print(&quot;dequeue: {0}&quot;.format(queue.dequeue()))
print(queue)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;138&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JkCe1/btrgC6cVv4Y/zN30gxxRCOksATKPF5604K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JkCe1/btrgC6cVv4Y/zN30gxxRCOksATKPF5604K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JkCe1/btrgC6cVv4Y/zN30gxxRCOksATKPF5604K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJkCe1%2FbtrgC6cVv4Y%2FzN30gxxRCOksATKPF5604K%2Fimg.png&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;138&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;고찰&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 중요한 아이디어는 &lt;code&gt;in_stack&lt;/code&gt;의 데이터들은 모두 &lt;code&gt;out_stack&lt;/code&gt;보다 늦게 들어온 데이터라는 것이다. &lt;code&gt;out_stack&lt;/code&gt;에 원소가 있다면 &lt;code&gt;in_stack&lt;/code&gt;에서 원소를 가져오지 않고 &lt;code&gt;pop&lt;/code&gt;을 해야했다. LIFO를 두 번 사용해서 FIFO로 만드는 게 꽤 흥미로웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/자료구조</category>
      <category>python</category>
      <category>스택</category>
      <category>자료구조</category>
      <category>큐</category>
      <category>파이썬</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/34</guid>
      <comments>https://joyjangs.tistory.com/34#entry34comment</comments>
      <pubDate>Sun, 3 Oct 2021 00:14:48 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조][Python] : Queue(큐)</title>
      <link>https://joyjangs.tistory.com/33</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;자료구조 with Python : Queue(큐)&lt;/h2&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐는 스택과 다르게 항목이 들어온 순서대로 접근이 가능하다. 먼저 들어온 데이터가 먼저 나가는 선입선출(FIFO) 구조다. 큐도 스택처럼 랜덤 액세스가 제한된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;큐의 구조&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;front : 큐의 가장 앞을 가리키는 포인터&lt;/li&gt;
&lt;li&gt;rear : 큐의 가장 뒤를 가리키는 포인터&lt;/li&gt;
&lt;li&gt;enqueue : rear 뒤에 원소를 삽입하는 함수&lt;/li&gt;
&lt;li&gt;dequeue : front 위치의 원소를 제거하면서 반환하는 함수&lt;/li&gt;
&lt;li&gt;is_empty : 큐가 비어있는지 확인하는 함수&lt;/li&gt;
&lt;li&gt;size : 큐의 크기를 확인하는 함수&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;큐의 구현&lt;/h3&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;pre class=&quot;ruby&quot;&gt;&lt;code&gt;class Queue(object):
    def __init__(self):
        self.items = []
        self.front = 0
        self.rear = -1

    def isEmpty(self):
        return self.front &amp;gt; self.rear

    def enqueue(self, item):
        self.items.append(item)
        self.rear += 1

    def dequeue(self):
        if self.isEmpty():
            print(&quot;Queue is empty&quot;)
        else:
            self.front += 1
            return self.items[self.front - 1]

    def __repr__(self):
        return repr(self.items[self.front:self.rear+1])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;items&lt;/code&gt; 리스트에 &lt;code&gt;enqueue()&lt;/code&gt;함수로 데이터를 넣으면 가장 뒤를 나타내는 &lt;code&gt;rear&lt;/code&gt;가 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;dequeue&lt;/code&gt;를 하면 &lt;code&gt;front&lt;/code&gt;가 가리키는 데이터를 반환하고 &lt;code&gt;front&lt;/code&gt;가 1 증가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;큐가 비어있는 지 여부는 &lt;code&gt;front &amp;gt; rear&lt;/code&gt;로 알 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;확인코드&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;queue = Queue()
for i in range(1, 4):
    queue.enqueue(i)
print(queue)
print(&quot;dequeue: {0}&quot;.format(queue.dequeue()))
print(&quot;dequeue: {0}&quot;.format(queue.dequeue()))
queue.enqueue(4)
queue.enqueue(5)
print(queue)
print(&quot;dequeue: {0}&quot;.format(queue.dequeue()))
print(queue)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;138&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvbF6K/btrgBlPB9Uk/5QCaEadNOG9O7B9pi3bRL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvbF6K/btrgBlPB9Uk/5QCaEadNOG9O7B9pi3bRL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvbF6K/btrgBlPB9Uk/5QCaEadNOG9O7B9pi3bRL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvbF6K%2FbtrgBlPB9Uk%2F5QCaEadNOG9O7B9pi3bRL0%2Fimg.png&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;138&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 큐의 동작이 어떻게 이뤄지는지 확인하기 위함이고 이렇게 계속 사용하게 되면 &lt;code&gt;dequeue()&lt;/code&gt;를 하더라도 데이터가 남아있기 때문에 좋은 방법은 아니라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉬운 구현은 &lt;code&gt;list&lt;/code&gt;자료형을 이용해서 append와 &lt;code&gt;pop(0)&lt;/code&gt;를 사용하는 방법이지만 &lt;code&gt;pop(0)&lt;/code&gt; 의 경우 시간복잡도가 &lt;code&gt;O(N)&lt;/code&gt;이기 때문에 이 또한 비효율적이다.&lt;/p&gt;</description>
      <category>프로그래밍/자료구조</category>
      <category>python</category>
      <category>queue</category>
      <category>자료구조</category>
      <category>큐</category>
      <category>파이썬</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/33</guid>
      <comments>https://joyjangs.tistory.com/33#entry33comment</comments>
      <pubDate>Sat, 2 Oct 2021 23:14:49 +0900</pubDate>
    </item>
    <item>
      <title>[ATmega128] GPIO 활용 - 7 세그먼트</title>
      <link>https://joyjangs.tistory.com/32</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[ATmega128] 7 세그먼트&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 예제는 WinAVR 컴파일러 환경에서 동작합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 예제는 스위치로 시계 같은 장치에서 사용되는 7세그먼트를 직접 제어하는 예제이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;회로도&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;257&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBUDnx/btrgCFT5MBd/sjPdTfaa2zX64CJYNVwKV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBUDnx/btrgCFT5MBd/sjPdTfaa2zX64CJYNVwKV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBUDnx/btrgCFT5MBd/sjPdTfaa2zX64CJYNVwKV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBUDnx%2FbtrgCFT5MBd%2FsjPdTfaa2zX64CJYNVwKV0%2Fimg.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;257&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소스코드&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;#define F_CPU 16000000
#include &amp;lt;avr/io.h&amp;gt;
#include &amp;lt;util/delay.h&amp;gt;
unsigned char num_data[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x27, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};    
//cathod common 형의 비트 패턴

void main(void){
    unsigned char ch;
    DDRB=0xff;            //PB를 출력으로 설정
    DDRD=0x00;            //PD를 입력으로 설정
    PORTD= 0x0f;        //풀업저항 사용
    while(1){
        ch = (~PIND)&amp;amp;0x0f;    
//스위치에 따른 입력값을 정수로 숫자로 변환
        PORTB = num_data[ch];    //PORTB에 숫자에 따른 비트 패턴을 출력
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;158&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FdXqu/btrgB4zP8X6/FVIKNtv2vFbhAoJW9t2rEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FdXqu/btrgB4zP8X6/FVIKNtv2vFbhAoJW9t2rEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FdXqu/btrgB4zP8X6/FVIKNtv2vFbhAoJW9t2rEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFdXqu%2FbtrgB4zP8X6%2FFVIKNtv2vFbhAoJW9t2rEK%2Fimg.png&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;158&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 오히려 LED 예제보다 더 간단하다. 스위치를 통해 2진수 입력을 받아서 7-세그먼트에 16진수 숫자를 출력하는 프로그램이다. &lt;code&gt;num_data[]&lt;/code&gt;배열은 7-세그먼트 부품마다 다르게 입력해 주어야 한다. 여기서 사용한 7-세그먼트는 7SEG-COM-CATHODE라는 소자로 공통 단자가 GND이고 LED에 HIGH 신호가 인가되면 LED가 켜지는 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사진과 비슷하지만 DP 단자가 없다. 예를 들어서 2를 켜기 위해서는 a, b, d, e, g LED가 활성화 되어야하기 때문에&lt;code&gt;0b01011011&lt;/code&gt; 가 출력되어야 한다. cathode, athode 방식에 따라서 &lt;code&gt;num_data[]&lt;/code&gt; 배열이 달라진다. 그 이유는 공통 단자가 GND이냐 Vcc이냐에 따라 &lt;code&gt;HIGH&lt;/code&gt;를 출력하면 불이 켜지는지 &lt;code&gt;LOW&lt;/code&gt;를 출력하면 불이 켜지는 지 달라지기 때문이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주의할 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치가 택트 스위치가 아니라 푸쉬 스위치를 써서 입력값을 유지할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치 입력값을 확인할 때 스위치가 눌려져 있으면 1을 의미하지만 핀으로는 LOW가 입력된다. 예를 들어서 입력을 &lt;code&gt;10 = 0b1010&lt;/code&gt;으로 주었을 때 PIND는 0101을 입력으로 받는다. 따라서 not연산&lt;code&gt;~&lt;/code&gt; 을 해준 다음 0x0f와 &lt;code&gt;&amp;amp;&lt;/code&gt;연산을 해준다.&lt;/p&gt;</description>
      <category>임베디드/ATmega128</category>
      <category>7-세그먼트</category>
      <category>ATmega128</category>
      <category>gpio</category>
      <category>WinAVR</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/32</guid>
      <comments>https://joyjangs.tistory.com/32#entry32comment</comments>
      <pubDate>Sat, 2 Oct 2021 21:25:09 +0900</pubDate>
    </item>
    <item>
      <title>[ATmega128] GPIO 활용 - LED 예제2</title>
      <link>https://joyjangs.tistory.com/31</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;[ATmega128] LED 예제2&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 예제는 WinAVR 컴파일러 환경에서 동작합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 예제는 스위치 여러 개로 LED 여러 개를 컨트롤 하는 예제이다. LED가 켜지면 순차적으로 LED가 켜졌다가 꺼지도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 위 입력은 LED를 켜고 끄는 ON/OFF 스위치이고 그 다음은 LED가 바뀌는 데 걸리는 시간을 줄이고 다른 스위치는 LED가 바뀌는 데 걸리는 시간을 늘리는 스위치이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;회로도&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;310&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TjMn2/btrgA6ykLkY/ntQYMVCsZSuUcFOCFNSnh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TjMn2/btrgA6ykLkY/ntQYMVCsZSuUcFOCFNSnh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TjMn2/btrgA6ykLkY/ntQYMVCsZSuUcFOCFNSnh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTjMn2%2FbtrgA6ykLkY%2FntQYMVCsZSuUcFOCFNSnh1%2Fimg.png&quot; data-origin-width=&quot;551&quot; data-origin-height=&quot;310&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소스코드&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;#define F_CPU 16000000
#include &amp;lt;avr/io.h&amp;gt;
#include &amp;lt;util/delay.h&amp;gt;
unsigned char led_on = 0;        //led_on이 1이면 led를 동작하도록 하기 위한 변수
unsigned char led = 0xfe;            //PD0의 LED만 켜지게 하기 위한 초기값
int delay_time = 10;
void delay(int delay_time){            //delay_time 변수 값만큼 50ms씩 delay
    while(delay_time--){
        _delay_ms(50);
    }
}
void main(){
    DDRD = 0x00;            //PD2~0을 입력으로 설정
    DDRB = 0xff;            //PB7~0을 출력으로 설정
    PORTD = 0x07;        //풀업저항을 사용하기 위해 PORTD2~0 = 1
    PORTB = 0xff;                //PORTB의 초기값 설정
    unsigned char key;
    while(1){
        key = PIND &amp;amp; 0x07;        //PIND와 들어온 신호를 비교
        switch(key){    //button이 GND와 연결되어 있어서 눌리면 0      열려있으면 1의 값이 입력
            case 0b00000110:        //PD.0과 연결된 버튼이 눌린 경우
                led_on=~led_on;        //led_on을 스위칭
                break;
            case 0b00000101:        //PD.1과 연결된 버튼이 눌린 경우
                if(led_on){            //LED가 꺼졌다가 다시 켜졌을 때 delay_time이 꺼지기 전의 값을 유지하기 위한 조건문
                    if(delay_time&amp;gt;1){
                    delay_time--;    
//delay 하는 횟수를 감소
                    }
                }
                break;
            case 0b00000011:        //PD2와 연결된 버튼이 눌린 경우
                if(led_on){            
                    if(delay_time&amp;lt;21){
                    delay_time++;    //delay 하는 횟수를 증가
                    }
                }
                break;
        }
        if(led_on){                    
            PORTB=led;        //PORTB에 led값을 출력
            delay(delay_time);        //delay_time * 50ms 만큼 delay
            if(led==0x7f)        //PB7과 연결된 LED가 켜진 경우
                led=0xfe;        //led를 초기값으로 설정
            else
                led=(led&amp;lt;&amp;lt;1)|0x01;    //led 변수를 한칸씩 shift하면서 0번 비트를 1로 세트한다.
        }
        else
        PORTB=0xff;    //led_on이 0인 경우 led를 모두 끔
            _delay_ms(200);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 예제와 마찬가지로 스위치는 GND와 연결되어 있고 LED는 Vcc와 연결되어 있다. 입력 값을 확인하기 위해서 &lt;code&gt;PIND &amp;amp; 0x07&lt;/code&gt;을 해주어서 하위 3비트의 입력값을 비교하고 해당 스위치에 맞는 동작을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스위치에 따른 동작이 끝나면 &lt;code&gt;led_on&lt;/code&gt; 플래그가 1이면 다음 LED를 켜고 다음에 켜질 LED를 &lt;code&gt;led&lt;/code&gt;변수에 입력한다. &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; 연산은 이진수를 왼쪽으로 쉬프트하는 연산기호이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;delay&lt;/code&gt; 함수를 따로 선언해 준 이유는 &lt;code&gt;_delay_ms()&lt;/code&gt; 함수가 입력값으로 변수를 받지 않아서이다. &lt;code&gt;x = 1&lt;/code&gt;이고 &lt;code&gt;_delay_ms(x)&lt;/code&gt;를 하게 되면 에러가 발생하므로 적당한 ms를 설정하고 반복 횟수로 지연 시간을 조절해야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주의할 점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제에서는 여러 개의 키가 동시에 눌리는 경우에 동작이 되지 않는다. 이런 경우를 위해서 나중에 인터럽트에 대해서 공부하게 된다. &lt;code&gt;while&lt;/code&gt;문 마지막에 LED가 꺼진 경우 200ms의 delay를 주게 되었는데 이것은 버튼을 눌렀다가 떼기 전에 다시 while문의 처음으로 돌아가서 여러 번 눌린 것으로 인식될 수 있기 때문이다. 이것 또한 인터럽트를 적용하고 입력 방식을 변경하면 해결할 수 있다.&lt;/p&gt;</description>
      <category>임베디드/ATmega128</category>
      <category>ATmega128</category>
      <category>LED</category>
      <category>WinAVR</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/31</guid>
      <comments>https://joyjangs.tistory.com/31#entry31comment</comments>
      <pubDate>Sat, 2 Oct 2021 21:03:26 +0900</pubDate>
    </item>
    <item>
      <title>[ATmega128] GPIO 활용 - LED 예제1</title>
      <link>https://joyjangs.tistory.com/30</link>
      <description>&lt;h2&gt;[ATmega128] LED 예제1&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;해당 예제는 WinAVR 컴파일러 기준 코드입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;회로도&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;312&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcJ5ZR/btrgAMGQVZO/y1DuzljJSZEOLgalcHchrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcJ5ZR/btrgAMGQVZO/y1DuzljJSZEOLgalcHchrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcJ5ZR/btrgAMGQVZO/y1DuzljJSZEOLgalcHchrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcJ5ZR%2FbtrgAMGQVZO%2Fy1DuzljJSZEOLgalcHchrk%2Fimg.png&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;312&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;소스코드&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#define F_CPU 16000000
#include&amp;lt;avr/io.h&amp;gt;
#include&amp;lt;util/delay.h&amp;gt;
unsigned char led_on;
void PB_LEDOnOff(void) // LED ON/OFF 함수
{
    if (led_on) {            //led가 켜진 상태이면
        PORTB=0b00000001;    // LED 끔
        led_on = 0;
    }
    else {                //LED가 꺼진 상태이면
        PORTB=0b00000000;    // LED 켬
        led_on = 1;
    }
}
int main(void){
    unsigned char key;
    DDRB = 0b00000001; // 입출력 방향 설정
    DDRD = 0b00000000; // 입출력 방향 설정
    PORTD = 0b00000001; // 풀업저항 설정
    PORTB = 0b00000000;    //PORTB에 초기값 0x00으로 설정
    led_on = 1;
    while(1)
    {
        key = (PIND &amp;amp; 0b00000001); // 버튼 스위치 값을 읽기
        switch(key) // key와 값이 일치하면 해당 case 실행문을 실행
        {
        case 0b00000000: // 스위치가 눌렸음을 확인
            PB_LEDOnOff();
            _delay_ms(500); // 0.5초 시간 지연 발생
            break;
        default: // 변수와 값이 불일치하면 아무것도 하지 않음
            break;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3&gt;코드 설명&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;DDRB = 0b00000001&lt;/code&gt;로 설정하여 &lt;code&gt;PB0&lt;/code&gt;을 출력으로 사용한다. &lt;code&gt;DDRD = 0b00000000&lt;/code&gt;이므로 &lt;code&gt;PD0&lt;/code&gt;를 입력으로 사용한다. &lt;code&gt;PORTD = 0b00000001&lt;/code&gt;로 하여 &lt;code&gt;PD0&lt;/code&gt;과 연결된 풀업 저항을 활성화 시킨다. 풀업저항이 활성화 되면 입력값은 &lt;code&gt;HIGH&lt;/code&gt; 상태를 유지시키고 Floating 현상을 방지해준다.&lt;/p&gt;
&lt;p&gt;LED의 핀 반대방향으로 VCC와 연결되어 있기 때문에 출력이 &lt;code&gt;LOW&lt;/code&gt;가 되어야 LED에 전압 강하가 생기기 때문에 불이 켜진다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;while&lt;/code&gt;문에서 보면 &lt;code&gt;key = (PIND &amp;amp; 0b00000001)&lt;/code&gt; 구문을 통해서 버튼 스위치의 입력값을 확인한다. 버튼이 눌리면 &lt;code&gt;PD0&lt;/code&gt;가 GND와 연결되면서 0의 값을 가지게 되므로 &lt;code&gt;0b00000000&lt;/code&gt; case에서 LED의 ON/OFF 상태를 변환시켜준다.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;주의할 점&lt;/h3&gt;
&lt;p&gt;LED 예제를 풀 때 주의할 점으로는 우선 스위치와 LED의 반대방향이 Vcc인지 GND인지 확인하는 것이다. 또한 LED의 방향도 중요하다. 삼각형 방향이 항상 전압이 높은 곳에서 낮은 곳으로 흐르도록 해주어야 한다.&lt;/p&gt;</description>
      <category>임베디드/ATmega128</category>
      <category>ATmega128</category>
      <category>LED</category>
      <category>WinAVR</category>
      <author>joyjang</author>
      <guid isPermaLink="true">https://joyjangs.tistory.com/30</guid>
      <comments>https://joyjangs.tistory.com/30#entry30comment</comments>
      <pubDate>Sat, 2 Oct 2021 20:46:55 +0900</pubDate>
    </item>
  </channel>
</rss>