<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>xyz.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Tue, 02 Jul 2024 07:36:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>xyz.log</title>
            <url>https://velog.velcdn.com/images/xyz_27/profile/4ff5cf74-6a7f-40c6-8687-d38c5fb10c60/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. xyz.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/xyz_27" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Pytorch GPU 사용법을 찾아서...]]></title>
            <link>https://velog.io/@xyz_27/Pytorch-GPU-%EC%82%AC%EC%9A%A9%EB%B2%95%EC%9D%84-%EC%B0%BE%EC%95%84%EC%84%9C</link>
            <guid>https://velog.io/@xyz_27/Pytorch-GPU-%EC%82%AC%EC%9A%A9%EB%B2%95%EC%9D%84-%EC%B0%BE%EC%95%84%EC%84%9C</guid>
            <pubDate>Tue, 02 Jul 2024 07:36:54 GMT</pubDate>
            <description><![CDATA[<p>LGAimers Phase2를 이제서야 해보겠다고 붙잡고 있는데, 베이스라인 코드만 돌려도 에포크 1번에 19시간 예상이라고 한다...
(최초 작성일 기준 마지막 날이었음 ㅋㅋ)
이건 말도 안되는 것 같아서 gpu 사용 코드도 있는데 왜 그러지 하고 살펴봤더니</p>
<pre><code class="language-python">torch.cuda.is_available()</code></pre>
<p>코드에서 False가 떴다.</p>
<pre><code class="language-python">torch.__version__</code></pre>
<p>으로 버전을 확인해도 2.0.1+cpu 버전으로 확인되었다.</p>
<p>Pytorch에서 GPU를 사용하려면 세팅이 필요하다.
NVIDIA GeForce GTX 2080 Ti 기준으로 작성했다.</p>
<blockquote>
<p><strong>1. NVIDIA Driver 설치
2. CUDA 설치
3. cudnn 다운로드 및 설치
4. 환경 및 설치 버전에 맞춰 pytorch 설치
5. GPU 동작 확인</strong></p>
</blockquote>
<h2 id="1-nvidia-driver-설치">1. NVIDIA Driver 설치</h2>
<h3 id="🔗nvidia-driver-설치-페이지-httpswwwnvidiacomdownloadindexaspx">[🔗NVIDIA Driver 설치 페이지] (<a href="https://www.nvidia.com/Download/index.aspx">https://www.nvidia.com/Download/index.aspx</a>)</h3>
<p><img src="https://velog.velcdn.com/images/xyz_27/post/39ebcf59-07a9-43a9-bc41-b62029dfbba2/image.png" alt=""></p>
<p>이와 같이 그래픽 카드에 맞춰 설정 후 Search 버튼을 누른다.</p>
<p><img src="https://velog.velcdn.com/images/xyz_27/post/9ccd4446-809f-4c2c-827f-0ebc7b8ebe90/image.png" alt=""></p>
<p>검색된 드라이버를 다운로드 후 안내에 따라 설치한다.
설치 완료 후 재시작이 필요하다.</p>
<h2 id="2-cuda-설치">2. CUDA 설치</h2>
<p>CUDA를 설치하기 전에 Pytorch 설치에 요구되는 버전들을 확인해야 한다.</p>
<h3 id="🔗pytorch-설치-안내"><a href="https://pytorch.org/get-started/locally/">🔗PyTorch 설치 안내</a></h3>
<p><img src="https://velog.velcdn.com/images/xyz_27/post/7cd6e7b4-485d-4088-9ee7-2e1f4d544e27/image.png" alt=""></p>
<p>위와 같이 PyTorch Stable 버전(23/08/28 기준, 2.0.1), Windows, Pip, Python 환경의 경우, 
CUDA는 11.7, 11.8 버전 설치가 가능하다.</p>
<h3 id="🔗cuda-toolkit-설치-httpsdevelopernvidiacomcuda-toolkit-archive">[🔗CUDA Toolkit 설치] (<a href="https://developer.nvidia.com/cuda-toolkit-archive">https://developer.nvidia.com/cuda-toolkit-archive</a>)</h3>
<p>11.8 버전으로 설치해 보았다.
<img src="https://velog.velcdn.com/images/xyz_27/post/79d23f1b-b912-4c37-9a78-4fb0d3963913/image.png" alt="">
<img src="https://velog.velcdn.com/images/xyz_27/post/e1c63dfd-8df4-43c7-8685-3b10e085d83a/image.png" alt=""></p>
<p>local은 설치파일 전체를 다운로드해서 용량이 크다.
network로 다운받았다.</p>
<h2 id="3-cudnn-다운로드-및-설치">3. cudnn 다운로드 및 설치</h2>
<h3 id="🔗cudnn-설치"><a href="https://developer.nvidia.com/rdp/cudnn-archive">🔗cuDNN 설치</a></h3>
<p>CUDA 버전에 맞추어 cuDNN v8.9.7 (December 5th, 2023), for CUDA 11.x 설치</p>
<h2 id="4-환경-및-설치-버전에-맞춰-pytorch-설치">4. 환경 및 설치 버전에 맞춰 pytorch 설치</h2>
<hr>
<p>(23.12.11. 기준) 
torch 2.1.1 까지 업그레이드 됨
파이썬 3.8.9로 설치해서 사용함 (<a href="https://www.python.org/downloads/release/python-389/">https://www.python.org/downloads/release/python-389/</a>)
%pip install torch==2.1.1+cu118 torchvision==0.16.1+cu118 torchaudio==2.1.1+cu118 --extra-index-url <a href="https://download.pytorch.org/whl/cu118">https://download.pytorch.org/whl/cu118</a></p>
<hr>
<p>(24.07.02. 기준)
torch-2.3.1+cu118-cp310-cp310-linux_x86_64.whl
torchvision-0.18.1+cu118-cp310-cp310-linux_x86_64.whl
torchaudio-2.3.1+cu118-cp310-cp310-linux_x86_64.whl</p>
<p>까지 업그레이드 됨. linux 기반 python 3.10 버전 기준.
%pip install torch==2.3.1+cu118 torchvision==0.18.1+cu118 torchaudio==2.3.1+cu118 --extra-index-url</p>
<h2 id="5-gpu-동작-확인">5. GPU 동작 확인</h2>
<pre><code class="language-python">torch.cuda.is_available()</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day18 ~ Day20]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day18-Day20</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day18-Day20</guid>
            <pubDate>Sun, 10 Sep 2023 14:56:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/0b81d640-665c-4c5a-bd8e-cb83056f5296/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="규칙-찾기-문제는-재미있다---day18">규칙 찾기 문제는 재미있다. - Day18</h4>
<p>코드로 모든 경우의 수를 찾아 들어가는 것보다, 공통된 규칙을 찾고 그걸 바탕으로 알고리즘을 구현하는 게 더 재미있다.
완전 탐색...? 너무 힘들다.</p>
<h4 id="그런데-동적-프로그래밍이-뭘까---day18">그런데 동적 프로그래밍이 뭘까 - Day18</h4>
<p>Day18의 &#39;중첩 점&#39; 문제는 &#39;동적 프로그래밍과 시뮬레이션 문제를 혼합한 문제&#39;라고 한다.
동적 프로그래밍이란 뭘까...
&#39;복잡한 문제를 간단한 여러 개의 문제로 나누어 푸는 방법&#39;
하위 문제의 수가 기하급수적으로 증가할 때 유용하다. (중복 계산 제거)
최단 경로 문제, 행렬의 제곱 문제 등의 최적화에 사용된다.
(출처: <a href="https://ko.wikipedia.org/wiki/%EB%8F%99%EC%A0%81_%EA%B3%84%ED%9A%8D%EB%B2%95">https://ko.wikipedia.org/wiki/동적_계획법</a>)</p>
<p>아직 완벽히 이해하지는 못했는데다가, 동적 프로그래밍이 모든 경우의 수를 탐색하는 것과 마찬가지라고 해서 놀랐다.
이전에 풀었던 문제보다 이 문제가 더 재밌었던 이유는 뭘까...? 그냥 쉬웠나.</p>
<h4 id="마지막은-타임어택-성공---day-20">마지막은 타임어택 성공 - Day 20</h4>
<p>요즘 계속해서 정해코드 확인 후 뒤늦게 풀어봤는데, 마지막인만큼 24시간 안에 풀어봤다.
완전탐색 코드는 계속해서 이전 내용들을 참고하고 있지만 ㅠㅠ
계속 작성해보면서 직접 코딩해볼 수 있도록 해야지...</p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
<h4 id="day-18--중첩-점">Day 18 : 중첩 점</h4>
</blockquote>
<ul>
<li>map을 활용해서 한꺼번에 int로 바꾸는 동시에 각각 -1 을 해주고 싶었지만, 방법을 찾지 못했다...</li>
<li>나는 시작점부터 -1 방향으로 가도록 range를 작성했는데, 어차피 범위만 같으면 되므로, 정해코드에서는 종료점을 y+1, x+1로 지정했더라.<pre><code class="language-python">for _ in range(M):
  y, x, d = input().split()
  y = int(y) -1
  x = int(x) -1
&gt;
  if d == &quot;U&quot;:
      for i in range(y, -1, -1):
          square[i][x][0] += 1
  elif d == &quot;D&quot;:
      for i in range(y, N):
          square[i][x][0] += 1
  elif d == &quot;L&quot;:
      for i in range(x, -1, -1):
          square[y][i][1] += 1
  elif d == &quot;R&quot;:
      for i in range(x, N):
          square[y][i][1] += 1</code></pre>
</li>
</ul>
<blockquote>
<h4 id="day-19--대체-경로">Day 19 : 대체 경로</h4>
</blockquote>
<ul>
<li>이 문제는 최단 경로를 확인하는 방식을 알아야 한다.</li>
<li>여러 경로 중에 최단인 것을 찾아 내는 것은 불필요한 과정이다...</li>
<li>BFS 최단경로<blockquote>
<blockquote>
<p>출처: <a href="https://nulls.co.kr/graph/141">https://nulls.co.kr/graph/141</a>
어느 경로로 가든 상관없이 최단 경로의 탐색 횟수를 확인하는 것은 간단하다.
몇 단계까지 내려갔을 때 탐색 대상 변수를 찾았는지 확인하면 된다.</p>
</blockquote>
</blockquote>
<pre><code class="language-python">def bfs(S, off):
  if S == off:    # 시작 위치 공사중이면 -1 리턴
      return -1
&gt;
  visited = [0 for _ in range(N+1)]
  q = deque([S])
&gt;
  visited[S] = 1
  step = 1        # 시작지점 또한 단계 계산에 포함시킨다
&gt;
  while q:
      step += 1    # 다음 단계 시작 = 1단계 위치를 기반으로 **2단계 위치들 탐색**
&gt;
      # for문 다 돌아가야 다음 step
      for _ in range(len(q)):
          now = q.popleft()
&gt;
          # 현재 위치에서 도달할 수 있는 모든 점에 대해 탐색
          for to in city[now]:
              if visited[to] or to == off:
                  continue
&gt;
          # 도착지점에 도달했다면 step 리턴
              if to == E:
                  return step
&gt;
              # 아니라면 방문 기록 &amp; 큐에 추가
              visited[to] = 1
              q.append(to)
&gt;
      # 마지막까지 e로 가지 못했다면 -1 리턴
  return -1</code></pre>
</li>
</ul>
<blockquote>
<h4 id="day-20--연결-요소-제거하기">Day 20 : 연결 요소 제거하기</h4>
</blockquote>
<ul>
<li>이번 문제는 for문이 한 번 돌아갈 때마다 연결된 요소가 K개 이상인지 확인해야 한다.</li>
<li>bfs로 동일한 문자로 연결된 위치를 담는 리스트를 만들고, 이 리스트의 길이가 K개 이상이 되면 해당 위치를 &#39;.&#39;으로 바꾸는 과정을 거쳤다.</li>
<li>큐는 계속해서 빠져나와야 해서 리스트를 따로 만들었다.</li>
<li>방문기록은 필요 없는데, conli에서 계속 append하기 때문이다.<blockquote>
</blockquote>
<pre><code class="language-python">from collections import deque
&gt;
def bfs(y, x):
  global connected, conli
&gt;    
  dy = [-1, 1, 0, 0]
  dx = [0, 0, -1, 1]
&gt;    
  q = deque([(y, x)])
  conli = [(y, x)]
&gt;    
  while q:
      ny, nx = q.popleft()
&gt;        
      for k in range(4):
          my, mx = ny + dy[k], nx + dx[k]
&gt;            
          if my in (0, N+1) or mx in (0, N+1) or (my, mx) in conli:
              continue
&gt;            
          if board[my][mx] == d:
              q.append((my, mx))
              conli.append((my, mx))</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day16 ~ Day17]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day16-Day17</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day16-Day17</guid>
            <pubDate>Sun, 10 Sep 2023 14:50:14 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/4326582a-e05f-4bc4-8978-9ec3e2d593d8/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="문제를-잘-읽어야-한다---day16">문제를 잘 읽어야 한다 - Day16</h4>
<p>처음에 문제 이해가 되지 않아 예제의 답이 왜 그렇게 나오는지 몰랐는데,
알고보니 <code>다른 섬과 연합을 결성하지 않은 섬들도 각각 하나의 연합에 속해 있는 것으로 볼 때</code>라는 조건이 문제 속에 숨어 있었다.
답변 출력을 위해서는 문제를 꼼꼼히 읽는 것이 중요하다...</p>
<h4 id="바빠져서-문제를-풀기-위한-시간을-들이기-어려웠다ㅠ">바빠져서 문제를 풀기 위한 시간을 들이기 어려웠다ㅠ</h4>
<p>KDT 심화 과정에 등록해서 다시 학원에 다니기 시작했다.
틈틈이 구름에 들어와서 문제를 봤지만, 흐름이 끊기다보니 내가 작성한 변수를 어떤 의도로 넣었는지 까먹게 됐다.
한번에 쭉 이어서 공부할 수 있는 시간을 낼 수 있다면 좋을 것 같다.
아니면 주석으로 잘 노트해놓기!!</p>
<h4 id="소수점-이하로-나오는-숫자를-다룰-때-주의---day17">소수점 이하로 나오는 숫자를 다룰 때 주의 - Day17</h4>
<p>몫이나 나머지를 활용하는 게 아닌 나눗셈 결과를 가지고 코드를 풀어나갈 때,
숫자가 동일한지 비교하는 것은 불가능하다.
두 실수의 차이의 절댓값이 아주 작은 수보다 작을 때 같은 값으로 보고 코드를 풀어나갈 수 있다.</p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
<p>Day 16 : 연합</p>
</blockquote>
<ul>
<li>이전 문제에서는 특정 조건일 때 결과값에 +1을 해주는 방식이었다.</li>
<li>문제를 해결하기 위해서는 반대로 쓸 수도 있다는 것을 유의하자.</li>
<li>알고리즘 : 연합이 끝나서 새로운 섬을 만났을 때 +1<blockquote>
</blockquote>
<pre><code class="language-python">for i in range(1, N + 1):    # 모든 섬에 대해 탐색
  if visited[i]:
      continue
&gt;    
  q = deque([i])
  result += 1
  visited[i] = 1
&gt;    
  while q:
      now = q.popleft()
      for to in graph[now]:
          # 반대 섬에 방문하지 않았고, 오는 방향이 있으면
          if not visited[to] and now in graph[to]:
              # 연합 : q가 0이 되기 전까지 result에 1이 더해지지 않는다.
              q.append(to)        
              visited[to] = 1</code></pre>
<blockquote>
</blockquote>
</li>
</ul>
<blockquote>
<p>Day 17 : 그래프의 밀집도</p>
</blockquote>
<ul>
<li>조건을 만족하는 결과값을 출력하기 위해서 조건문을 잘 활용해야한다.</li>
</ul>
<ol>
<li>가장 밀도가 높은 컴포넌트를 출력한다.</li>
<li>1을 만족하는 컴포넌트가 여러 개라면, 컴포넌트를 구성하는 컴퓨터의 수가 가장 작은 컴포넌트를 출력한다.</li>
<li>2를 만족하는 컴포넌트가 여러 개라면, 더 작은 번호를 가진 컴퓨터가 있는 컴포넌트를 출력한다.<pre><code class="language-python">for i in range(1, N + 1):
 if not visited[i]:
     temp, tempDensity = bfs(i)
&gt;        
     if abs(tempDensity - density) &lt; 1e-8:    # 2. 만약! 밀도가 같다면
         if len(result) &gt; len(temp):            # - 컴퓨터 수가 적은 컴포넌트 &amp; 밀도 업데이트
             result = temp
             density = tempDensity
         elif len(result) == len(temp):        # 3. 컴퓨터 수도 같다면
             if temp[0] &lt; result[0]:            # - 더 작은 번호가 있는 컴포넌트 &amp; 밀도 업데이트
                 result = temp
                 density = tempDensity
     elif tempDensity &gt; density:    # 1. 비교했을 때 밀도가 높다면
         result = temp            # - 가장 밀도가 높은 컴포넌트 업데이트
         density = tempDensity    # - 밀도 정보 업데이트</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day14 ~ Day15]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day14-Day15</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day14-Day15</guid>
            <pubDate>Sun, 03 Sep 2023 14:58:16 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/6aa10da1-7d79-49ed-bb89-90fd8f3450cd/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="정석-탐색-문제">정석 탐색 문제</h4>
<p>2차원 배열을 탐색하는 것보다는 간선 탐색이 머릿속에 그림을 그리기는 훨씬 쉬웠다.
다만 입력을 어떻게 받아야 하는지 고민이 많이 되었다.
어떻게 받느냐는 각자 스타일이긴 하지만, 그에 따라 코드 구현의 난이도는 달라질테니... 8ㅅ8 공부하면서 내 걸 만들어야지.</p>
<h4 id="감만-잡고-마무리를-못함">감만 잡고 마무리를 못함</h4>
<p>그리디 문제에서 필요한 계산식은 떠올렸지만, 이 값을 어떻게 활용해야 할지, 예외사항은 없는지 금방 생각하지 못했다.
더 많은 문제를 풀어봐야겠다.</p>
<h4 id="세-번째-캐릭터-완성">세 번째 캐릭터 완성</h4>
<p><img src="https://velog.velcdn.com/images/xyz_27/post/9f218cf7-76ee-4ffc-8505-67b85da7d290/image.png" alt=""></p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
<h4 id="day-14--작은-노드">Day 14 : 작은 노드</h4>
</blockquote>
<ul>
<li>리스트의 요소값 뿐만 아니라, 위치값을 활용하여 풀이할 수 있다.</li>
<li>양방향의 경우, 시작 위치와 종료 위치 모두에 서로에 대한 요소값을 넣어줘야 한다.</li>
<li>입력받는 방식은 이런 방식도 있다는 것을 잘 기억하자.<pre><code class="language-python">for _ in range(M):
  s, e = map(int, input().split())
  graph[s].append(e)
  graph[e].append(s)</code></pre>
<pre><code>&gt;&gt;&gt; [[], [2, 4], [1, 3, 5, 6], [2], [1, 5], [2, 4], [2]]
</code></pre></li>
</ul>
<blockquote>
<h4 id="day-15--과일-구매">Day 15 : 과일 구매</h4>
</blockquote>
<ul>
<li>과일 조각당 포만감이 높은 순으로 정렬 후, 과일 가격보다 돈이 많은 경우에는 통째로 사고, 과일 가격보다 돈이 적은 경우 조각으로 산다.</li>
<li>돈이 적으므로 조각이 모자라는 예외사항은 없다.</li>
<li>모든 과일을 구매하고도 돈이 남는 경우를 대비해, 과일이 더이상 남는 경우가 없는 조건까지 추가해야 한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day11 ~ Day13]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day11-Day13</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day11-Day13</guid>
            <pubDate>Sun, 03 Sep 2023 13:30:00 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/927cee17-6105-4724-aa75-5a8b9d5a14df/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="탐색-주가-시작됐다">탐색 주가 시작됐다</h4>
<p><img src="https://velog.velcdn.com/images/xyz_27/post/60c5a46f-fd26-41e8-bfb8-991db1783c5e/image.png" alt=""></p>
<p>BFS, DFS 머리가 아프지만 프로그래밍을 처음 공부했을 때부터 접했던 부분이라 중요한 것은 알겠다. :(</p>
<h4 id="리스트를-순회하고-답을-찾는-완전-탐색은-ok">리스트를 순회하고 답을 찾는 완전 탐색은 OK</h4>
<p>Day11 문제는 지난 주 통증 문제에서 업그레이드 됐다. 가능한 답을 모두 찾고 그 중에서 최소의 답을 찾았다.
그래도 간단한 계산 문제여서 어렵지 않았다.</p>
<h4 id="너비우선탐색과-깊이우선탐색---day12-day13">너비우선탐색과 깊이우선탐색 - Day12, Day13</h4>
<p>스택과 큐, 덱은 탐색의 재료일 뿐...
다음 노드로 넘어가서 반복해서 탐색해야 하기 때문에 재귀함수나 while, for문을 잘 활용해야 한다.</p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
<h4 id="day-11-통증-2">Day 11: 통증 (2)</h4>
<p>Bp가 큰 수이므로, 먼저 나눈 후, Bp만큼 남기면서 Ap의 갯수를 구한 뒤 가장 최솟값을 찾는다.</p>
</blockquote>
<pre><code class="language-python">n = int(input())
ap, bp = map(int, input().split())
&gt;
items = []
for i in range(n//bp+1):
    if ((n%bp)+(bp*i))%ap == 0:
        items.append(n//bp - i + ((n%bp)+(bp*i))//ap)
&gt;
if not items:
    print(-1)
else:
    print(min(items))</code></pre>
<p><code>if items == []:</code>를 <code>if not items</code>로 쓸 수도 있다는 것을 알게됐다.</p>
<blockquote>
<h4 id="day-12-발전기">Day 12: 발전기</h4>
<p>DFS (깊이 우선 탐색) : 방문하는 방향으로 최대한 깊게 탐색 후, 처음으로 돌아와서 다음 방향으로 탐색
BFS (너비 우선 탐색) : 현재 위치를 기준으로 방문이 가능한 모든 위치를 탐색 후, 이전 단계에서 구한 &#39;위치들&#39;을 기준으로 다시 방문이 가능한 위치 탐색</p>
</blockquote>
<ul>
<li>재귀 DFS의 경우, 초기에 지정한 순서로 바로 이동하여 탐색
상하좌우 1이 없는 경우 이전 단계로 돌아올 수 있는 이유: for문이 아직 끝나지 않았기 때문에. 재귀를 하면 반복적으로 for문이 돌아간다.
이 경우 재귀 깊이 제한 1000번으로 인해 런타임 에러가 발생할 수 있다.</li>
<li>비재귀 DFS의 경우, 스택을 활용해서, 최근에 스택에 추가된 위치부터 탐색한다.</li>
<li>BFS의 경우, 큐를 활용해서, 먼저 큐에 추가된 위치부터 탐색한다. 즉, 시작 위치부터 가까운 모든 위치를 탐색 후, 다음 거리의 위치를 탐색한다.<blockquote>
</blockquote>
스택 또는 큐의 오른쪽에 값을 추가하는건 동일하지만, 값을 왼쪽에서 꺼내는지, 오른쪽에서 꺼내는지에 따라 탐색을 진행하는 방식이 달라진다</li>
</ul>
<blockquote>
<h4 id="day-13-발전기-2">Day 13: 발전기 (2)</h4>
<p>DFS/BFS + 리스트 완전탐색
정해코드는 M의 가능한 범위 안(range(31))에서 단지의 갯수를 탐색했지만,
나는 건물유형과 그 갯수를 튜플로 묶어 return 후 K 이상일 때 리스트에 추가했다.
그 다음 그 리스트에서 건물 유형에 따른 단지 갯수를 튜플로 묶어 다시 리스트화 한 후, (1) 단지 갯수 (2) 건물 유형을 내림차순으로 이중 정렬하여 첫번째 요소의 단지 갯수를 출력하였다.</p>
</blockquote>
<pre><code class="language-python">from collections import deque
&gt;
dy = [-1, 1, 0, 0]
dx = [0, 0, -1, 1]
&gt;
N, K = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
&gt;
&gt;
def bfs(i, j):
    global M, K, dy, dx, arr
&gt;    
    q = deque([(i, j)])
    mk = 0
&gt;    
    while q:
        y, x = q.popleft()
&gt;        
        if arr[y][x] == 0:
            continue
&gt;            
        M = arr[y][x]
        arr[y][x] = 0
        mk += 1
&gt;        
        for k in range(4):
            ny, nx = y + dy[k], x + dx[k]
&gt;            
            if ny in (-1, N) or nx in (-1, N) or arr[ny][nx] == 0:
                continue
&gt;                
            elif arr[ny][nx] == M:
                q.append((ny, nx))
&gt;    
    return (M, mk)
&gt;    
&gt;    
mlist = []
for i in range(N):
    for j in range(N):
        building, number = bfs(i, j)
        if number &gt;= K:
            mlist.append(building)
&gt;
mset = set()
for l in mlist:
    mset.add((l, mlist.count(l)))
&gt;
# mset = {(3, 2), (2, 2), (1, 1), (4, 1)}
mset = sorted(sorted(mset, key=lambda x: x[0], reverse=True), key=lambda x:x[1], reverse=True)
print(mset[0][0])</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day8 ~ Day10]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day8-Day10</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day8-Day10</guid>
            <pubDate>Fri, 25 Aug 2023 20:58:04 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/88fb4a16-6f81-44fc-bbdf-2c56528757aa/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="2차원-리스트를-활용하는-문제가-많아졌다">2차원 리스트를 활용하는 문제가 많아졌다</h4>
<p>이번 주는 2차원 리스트를 활용해서 탐색하고, 값을 바꾸는 등의 문제가 많았다.
2차원에서 위치를 찾는 것에는 큰 어려움이 없었지만, 리스트의 값을 곱하기(<code>*</code>)를 사용해서 만드는 경우 (아마도) 주소값의 문제로 이후 과정에 문제가 일어나는 것을 확인할 수 있었다.
10일차에 와서야 0으로 이루어진 2차원 리스트를 만들 때는 for문으로 만드는 것을 검색해서 알게 됐다.</p>
<h4 id="변수가-많고-그래서-예상하지-못한-케이스가-많다">변수가 많고, 그래서 예상하지 못한 케이스가 많다</h4>
<p>내가 놓친 케이스를 스스로 떠올리기가 쉽지 않다. ㅠ
연습할 때만이라도 다양한 테스트 케이스를 주어줬으면 좋겠다...</p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
</blockquote>
<h4 id="day8--통증">Day8 : 통증</h4>
<p>두 줄이면 되는 문제여서 허무했다.
지난 주 문제에서도, 이번 문제에서도 나눗셈의 몫과 나머지의 역할을 잘 이해하고 활용하는 것이 중요할 것 같다.</p>
<blockquote>
</blockquote>
<h4 id="day9--폭탄-구현하기-2">Day9 : 폭탄 구현하기 (2)</h4>
<p>2차원 리스트 탐색형 문제는 개인적으로 테두리에 0을 집어넣어서 푸는 것이 마음편하다(?).</p>
<pre><code class="language-python">ground = [[0]*(n+2)]
for _ in range(n):
    ground.append([0]+list(str(input()).split())+[0])
ground.append([0]*(n+2))</code></pre>
<p>위와 같이 값을 받을 때부터 0을 집어넣었다. 리스트에 +를 활용하는 게 편하더라.</p>
<blockquote>
</blockquote>
<h4 id="day10--gamejam">Day10 : GameJam</h4>
<p>너무 오래 걸려서 힘들었다...ㅠㅠ
board 하나만 가지고 해보려다가 값을 바꾸면서 런타임 에러가 걸려서 빈 board를 하나 더 만들었다. 이건 day9에서도 그렇게 했다.
빈 board를 만드는 코드는 아래와 같이 했다. 리스트를 곱하기보다, (학습 일기에서도 언급했듯) for문을 쓰는 게 안전하다. </p>
<pre><code class="language-python">board2 = [[0 for col in range(n+2)] for row in range(n+2)]</code></pre>
<p>입력값의 범위 조건도 중요하다.
테스트 케이스에서 한 자리 수 케이스만 제시해서 그거에 맞춰서 했더니 Fail이 떠서,
Q&amp;A에서 누군가 올려준 두 자리수 케이스를 보고서야 그 부분을 놓쳤다는 것을 알게 됐다.</br>
그리고 이번 문제는 재귀함수로 풀었는데, 그러다보니 같은 블럭 안에 있는 코드여도 코드의 순서가 중요했고,
결국 포기하고 빈 board를 만들어 사용했지만, 만약 같은 board에서 값을 바꾸며 하려면 특히나 더 코드 라인의 순서가 중요할 것 같다.
board를 하나 더 만들면 메모리를 더 쓰게 되는 것 같아서 불리할 것 같은데, 이번 문제에서 메모리를 초과하거나 그러지는 않았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day6 ~ Day7]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day6-Day7</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day6-Day7</guid>
            <pubDate>Tue, 22 Aug 2023 18:54:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/95abbe4e-babc-4cc2-a210-f418470dba65/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<p><code>귀여운 아바타가 새로 생겨났다</code></p>
<img src="https://velog.velcdn.com/images/xyz_27/post/f9b537bf-510a-4fd1-85e9-30771285b7f7/image.png">


<h4 id="난이도-상승---day6">난이도 상승 - Day6</h4>
<p><img src="https://velog.velcdn.com/images/xyz_27/post/d68e0a54-f7f9-4f2c-927b-174bff01e04e/image.png" alt="">
2주차가 되어 새로운 유형의 문제를 풀게 되었다. 풀이 전략부터 잘못된 방향으로 가서, 런타임 에러를 해결하는 데에 그치고 대부분의 문제에서 FAIL을 맞닥뜨렸다. 결국 24시간 내에 풀지 못하고 해설을 확인했다.
해설에서 힌트를 얻고, 라이브러리 사용법을 알게 되어서 내 방식대로 살짝 응용해서 풀어서 아쉬움.</p>
<h4 id="이렇게까지-해야하나---완전탐색">이렇게까지 해야하나?! - 완전탐색</h4>
<p>모든 경우의 수를 탐색해서 리스트업을 해야하는 문제들이었는데, 길이가 길어지다보니 이게 맞는지 의심이 들고, 자동화를 하는 방식이 있을텐데 내가 모르는 게 아닐까 의구심이 들었다...
다들 어떻게 생각하는 걸까</p>
<h4 id="이중-for문과-리스트-위치값-탐색-문제">이중 for문과 리스트 위치값 탐색 문제</h4>
<p>이중 for문에서 기존에 할당된 리스트의 위치값을 지정하여 수정하다보면 모든 i의 리스트가 똑같아 지는 경우가 있다. 왜 그런걸까...?</p>
<pre><code class="language-python">tmp_li = [[0]*n]*n    # 이런 식으로 리스트를 만드는 경우, 모든 i의 j 위치에 해당 값이 들어간다.
for i in range(n):
    for j in range(n):
        tmp_li[i][j] = i+j+1

tmp_li2 = [[0,0,0], [0,0,0], [0,0,0]] # 리스트를 직접 만드는 경우, 문제는 일어나지 않는다.</code></pre>
<p>굳이 리스트를 생성해서 위치에 값을 넣을 필요없이, 빈 리스트에 append하면 되는 걸 깨달아서 그렇게 문제를 풀었지만, 여전히 의문은 해결되지 않는다...</p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
<h4 id="day6--문자열-나누기">Day6 : 문자열 나누기</h4>
</blockquote>
<ul>
<li>리스트 내에 n만큼 뽑아내는 경우의 수를 구할 때는 <pre><code class="language-python">from itertools import combinations</code></pre>
</li>
<li>set에 요소를 삽입할 때는 add</li>
<li>for문을 돌리는 중에 더 높은 값으로 업데이트할 때는 <pre><code class="language-python">answer = max(answer(기존값), temp(새로운 값))</code></pre>
</li>
</ul>
<blockquote>
<h4 id="day7--구름-찾기-깃발">Day7 : 구름 찾기 깃발</h4>
</blockquote>
<ul>
<li>&quot;i, j가 0일 때, n일 때&quot; 라는 조건문을 넣기보다, 그냥 상하좌우로 0인 패딩을 넣고 range(1, n+1) 안에서 for문을 돌리는 게 더 간편하다. 물론 문제 조건에 따라 다를 수 있다.</li>
<li>조건문 두 가지를 동시에 쓰고 싶을 때, &amp;를 써서 한 줄로 쓴 것보다 다음 탭으로 내려서 if를 한 번 더 쓰는게 조금 더 실행 속도가 빨랐다. (예외는 있었으나, 어떤 케이스인지 몰라서 궁금하다.)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day2 ~ Day5]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day2-Day5</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day2-Day5</guid>
            <pubDate>Fri, 18 Aug 2023 18:24:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/9f0b7e80-0916-4932-b430-3a23743f1702/image.png" alt=""></p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="꾸준한-글-작성은-힘들다">꾸준한 글 작성은 힘들다</h4>
<p>첫 날 시작하면서 하루 한 번 꾸준히 작성하고 싶었지만, 일상이 바빠 그러지 못했다.</p>
<h4 id="24시간-내에-문제-푸는-것을-목표로-변경">24시간 내에 문제 푸는 것을 목표로 변경</h4>
<img src="https://velog.velcdn.com/images/xyz_27/post/9c987c67-18b9-4138-b24a-9bc31aa9e0ab/image.png">

<p>하나하나씩 바뀌어가는 모습이 꽤 귀엽다. 다음은 어떤 파츠가 추가될지 궁금해진다.</p>
<h4 id="블로그-작성-방식-변경">블로그 작성 방식 변경</h4>
<p>코드를 공유하고 리뷰하는 과정을 거치고 싶은데, 블로그에 문제와 해설을 공개하는 것은 챌린지에 부적합해서 앞으로는 간단한 코드 공부와 일기만 올리려고 한다.</p>
<h2 id="💡-코드-공부">💡 코드 공부</h2>
<blockquote>
<p>Day 2 : 프로젝트 매니징
정수를 시간 단위로 변환 및 연산하는 문제. 몫과 나머지를 구하는 방식을 잘 활용하여 계산식을 짜야한다.</p>
</blockquote>
<blockquote>
<p>Day 3 : 합 계산기
문자열과 정수가 혼용된 데이터를 적절하게 분리하여 계산하는 문제. 문자열 분할과 조건문을 활용하였다.</p>
</blockquote>
<blockquote>
<p>Day 4 : 완벽한 햄버거 만들기
정렬을 활용해서 주어지는 값들이 올바르게 배치되어 있는지 확인하는 문제. 오름차순 정렬 혹은 내림차순 정렬 후, 기존 리스트와 비교하였다.</p>
</blockquote>
<blockquote>
<p>Day 5 : 이진수 정렬
데이터를 조건에 맞게 변형한 후, 다중 조건에 맞추어 정렬하는 문제. 공백을 포함한 str 타입의 입력값을 리스트로 변환하고 map과 lambda 함수를 적절히 활용하여 데이터를 변형 후 정렬하였다.
<code>map(lambda x : x[2:], list)</code>와 <code>sorted(list, key = lambda x : (-x[1], -x[0]))</code>와 같은 예시로 사용하였다. 2진수 변환의 경우 bin() 함수를 활용하였고, 내림차순의 경우 key 값 앞에 &#39;-&#39;를 붙여 사용할 수 있었다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[구름톤 챌린지] Day1]]></title>
            <link>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day1</link>
            <guid>https://velog.io/@xyz_27/%EA%B5%AC%EB%A6%84%ED%86%A4-%EC%B1%8C%EB%A6%B0%EC%A7%80-Day1</guid>
            <pubDate>Mon, 14 Aug 2023 16:15:22 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/xyz_27/post/b4190ab1-7344-480c-b49f-0203198d1966/image.png" alt=""></p>
<h2 id="💡-문제">💡 문제</h2>
<blockquote>
<h4 id="운동-중독-플레이어">운동 중독 플레이어</h4>
</blockquote>
<ul>
<li>1RM 계산 프로그램 작성하기</li>
<li>계산 공식 : 1RM = W × (1 + R/30)</li>
<li>W = 한 세트에서 들어올린 무게</li>
<li>R = 반복 횟수</li>
<li>정수 W(1≤W≤1,000,000)와 R(1≤R≤100)은 공백을 두고 입력됨</li>
<li>소수점 이하의 값은 버린 뒤 출력    </li>
</ul>
<h2 id="💡-예시">💡 예시</h2>
<blockquote>
<p>입력 : <code>100 30</code>
출력 : <code>200</code></p>
</blockquote>
<h2 id="💡-답안">💡 답안</h2>
<blockquote>
<pre><code class="language-python">import math
</code></pre>
</blockquote>
<p>w, r = map(int, str(input()).split())  # 입력값을 각 변수에 할당하기</p>
<blockquote>
</blockquote>
<p>answer = math.floor(w * (1 + (r/30)))  # 계산식에 넣고 소수점 이하 버리기</p>
<blockquote>
</blockquote>
<p>print(answer)</p>
<h2 id="💡-학습-일기">💡 학습 일기</h2>
<h4 id="구름톤-챌린지-스타트">구름톤 챌린지 스타트</h4>
<p>시작은 어렵지 않아서 모든 사람들이 가볍게 시작할 수 있을 것 같았다.
챌린지를 꾸준하게 완료하는 것이 중요!! :)</p>
<h4 id="구름ide-컨테이너">구름IDE 컨테이너</h4>
<p>오늘은 코딩테스트보다 구름IDE 컨테이너를 생성하는 것이 챌린지했다.
컨테이너라는 개념도 아직 이해하지 못했고, 실행하는 방식이 주피터 노트북이나 VSCode와는 달라서 설명과 메뉴를 한참 탐색하고 난 뒤에야 기본적인 실행 방식을 익혔다.
설명은 여전히 이해하지는 못하겠다. ^*^...</p>
<ol>
<li>컨테이너 생성 및 설정<ul>
<li>컨테이너의 공개범위를 Public으로 해두었다. 학습 일기 인증을 위해 공개 전환 필수!</li>
<li>앞으로 어떻게 사용할지 몰라서 일단 익숙한 Visual Studio Code와 Jupyter Notebook도 추가 도구로 켜두었다.</li>
<li>컨테이너 설정에서 언제든 변경 가능하다.</li>
</ul>
</li>
<li>폴더 및 파일 생성<ul>
<li>파이썬 언어로 설정 후 컨테이너를 생성하면 기본적으로 index.py 파일과 README.md 파일이 생성된다.</li>
<li>새 폴더를 Day1, 새 파일을 day1.py 로 이름을 설정하고 새로 만들었다.</li>
</ul>
</li>
<li>실행<ul>
<li>코드를 실행하려면 &#39;현재 파일 실행&#39;과 &#39;실행 명령&#39;을 사용할 수 잇다.</li>
<li>&#39;현재 파일 실행&#39;의 경우 기존 방식과 유사하여 큰 어려움이 없다.</li>
<li>&#39;실행 명령 생성&#39;의 경우, 스크립트에 파일 경로를 잘 지정해줘야 한다.</li>
<li>실행 명령을 처음 생성하면 <code>${python.set.compiler} ${python.set.main.path}</code> 라는 스크립트가 기본으로 작성되어 있다.</li>
<li>이 경로는 내 컨테이너 내의 index.py의 경로로 자동 지정되어 있고, 프로그램을 작성하는 경우 index.py에서 각 코드 파일들의 실행 알고리즘이 짜여 있을텐데... 챌린지 코드 작성의 경우엔 그럴 일 없으니까 사용법이나 익힐겸 경로는 바꿔봤다. 이렇게 하니 내 day1.py 파일이 잘 실행된다.
<img src="https://velog.velcdn.com/images/xyz_27/post/d3ff6d41-44a5-4a1d-9bc1-0ac5cf448f03/image.png" alt=""></li>
</ul>
</li>
</ol>
<h4 id="내일은-광복절">내일은 광복절</h4>
<p>국경일이자 공휴일이다.. 챌린지를 언제 할 수 있을지 모르겠지만 24시간 내로 끝낼 수 있도록 해보자! 😎</p>
]]></description>
        </item>
    </channel>
</rss>