{
    "componentChunkName": "component---src-templates-blog-template-js",
    "path": "/pg-42861/",
    "result": {"data":{"cur":{"id":"b7c11137-f10f-5c41-874c-9f3bba8eaaf0","html":"<h2 id=\"문제\" style=\"position:relative;\"><a href=\"#%EB%AC%B8%EC%A0%9C\" aria-label=\"문제 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>문제</h2>\n<p><a href=\"https://programmers.co.kr/learn/courses/30/lessons/42861\">https://programmers.co.kr/learn/courses/30/lessons/42861</a></p>\n<p>n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.</p>\n<p>다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.</p>\n<hr>\n<h2 id=\"제한사항\" style=\"position:relative;\"><a href=\"#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD\" aria-label=\"제한사항 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>제한사항</h2>\n<ul>\n<li>섬의 개수 n은 1 이상 100 이하입니다.</li>\n<li>costs의 길이는 <code class=\"language-text\">((n-1) * n) / 2</code> 이하입니다.</li>\n<li>임의의 i에 대해, costs[i][0] 와 costs[i][1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i][2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다.</li>\n<li>같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.</li>\n<li>모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.</li>\n<li>연결할 수 없는 섬은 주어지지 않습니다.</li>\n</ul>\n<hr>\n<h2 id=\"입출력-예\" style=\"position:relative;\"><a href=\"#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88\" aria-label=\"입출력 예 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>입출력 예</h2>\n<table>\n<thead>\n<tr>\n<th>n</th>\n<th>costs</th>\n<th>return</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4</td>\n<td>[[0,1,1],[0,2,2],[1,2,5],[1,3,1],[2,3,8]]</td>\n<td>4</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2 id=\"-algorithm\" style=\"position:relative;\"><a href=\"#-algorithm\" aria-label=\" algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🔍 Algorithm</h2>\n<p><strong>Kruskal</strong></p>\n<h2 id=\"-logic\" style=\"position:relative;\"><a href=\"#-logic\" aria-label=\" logic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>💻 Logic</h2>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">find_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">!=</span> x<span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">union_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        a <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span>\n        b <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">&lt;</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> a\n        <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> b\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">kruskal</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        result <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">while</span> h<span class=\"token punctuation\">:</span>\n            l<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> heapq<span class=\"token punctuation\">.</span>heappop<span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">if</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                union_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n                result <span class=\"token operator\">+=</span> l\n        <span class=\"token keyword\">return</span> result</code></pre></div>\n<ul>\n<li><strong>Kruskal 알고리즘 이용해서 MST 확인하는 함수</strong><br>\n우선순위 큐를 이용해서 MST 확인\n모든 노드 방문했는지 확인</li>\n</ul>\n<hr>\n<h2 id=\"-code\" style=\"position:relative;\"><a href=\"#-code\" aria-label=\" code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🧩 Code</h2>\n<details><summary>전체 코드 확인</summary>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> heapq\n<span class=\"token keyword\">def</span> <span class=\"token function\">solution</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">,</span> costs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">def</span> <span class=\"token function\">find_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">!=</span> x<span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> parent<span class=\"token punctuation\">[</span>x<span class=\"token punctuation\">]</span>\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">union_parent</span><span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        a <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span>\n        b <span class=\"token operator\">=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>a <span class=\"token operator\">&lt;</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> a\n        <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n            parent<span class=\"token punctuation\">[</span>a<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> b\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">kruskal</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        result <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">while</span> h<span class=\"token punctuation\">:</span>\n            l<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> heapq<span class=\"token punctuation\">.</span>heappop<span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">if</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">)</span> <span class=\"token operator\">!=</span> find_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n                union_parent<span class=\"token punctuation\">(</span>parent<span class=\"token punctuation\">,</span> a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span>\n                result <span class=\"token operator\">+=</span> l\n        <span class=\"token keyword\">return</span> result\n    \n    answer<span class=\"token punctuation\">,</span> h <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>\n    parent <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> x <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>costs<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        heapq<span class=\"token punctuation\">.</span>heappush<span class=\"token punctuation\">(</span>h<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>costs<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">2</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span>costs<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> costs<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    answer <span class=\"token operator\">=</span> kruskal<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> answer</code></pre></div>\n</details>\n<hr>\n<h2 id=\"-review\" style=\"position:relative;\"><a href=\"#-review\" aria-label=\" review permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>📝 Review</h2>\n<p>Minimun Spanning Tree를 만들어야 된다고 생각해서 Kruskal 알고리즘을 떠올렸다.<br>\n얼마 전에 Kruskal 알고리즘으로 문제를 풀었어서 바로 생각해내서 풀 수 있었다.</p>\n<div class=\"table-of-contents\">\n<ul>\n<li><a href=\"#%EB%AC%B8%EC%A0%9C\">문제</a></li>\n<li><a href=\"#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD\">제한사항</a></li>\n<li><a href=\"#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88\">입출력 예</a></li>\n<li><a href=\"#-algorithm\">🔍 Algorithm</a></li>\n<li><a href=\"#-logic\">💻 Logic</a></li>\n<li><a href=\"#-code\">🧩 Code</a></li>\n<li><a href=\"#-review\">📝 Review</a></li>\n</ul>\n</div>","excerpt":"문제 https://programmers.co.kr/learn/courses/30/lessons/42861 n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요. 다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다. 제한사항 섬의 개수 n은 1 이상 100 이하입니다. costs의 길이는  이하입니다. 임의의 i에 대해, costs[i][0] 와 costs[i][1]에는 다리가 연결되는 두 섬의 번호가 들어있고, costs[i][2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다. 같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하…","frontmatter":{"date":"April 12, 2022","title":"[Programmers] 42861번: 섬 연결하기 (Python)","categories":"Algorithm","author":"JFe","emoji":"💻"},"fields":{"slug":"/pg-42861/"}},"next":{"id":"14d02f5d-8a45-5d02-a388-e0abc2a9a2a7","html":"<h2 id=\"1-공공데이터-api-준비\" style=\"position:relative;\"><a href=\"#1-%EA%B3%B5%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0-api-%EC%A4%80%EB%B9%84\" aria-label=\"1 공공데이터 api 준비 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 공공데이터 api 준비</h2>\n<p>일단 먼저 원하는 공공데이터 api를 <a href=\"https://www.data.go.kr/\">공공데이터 포털</a>에서 확인할 수 있다. 여기서 자신이 원하는 다양한 공공데이터를 찾을 수 있고, csv 형태의 파일 데이터나 api 형식으로 제공받을 수 있는데 이 포스트에서는 실제 프로젝트 진행 중에 사용했던 공공데이터 api를 기준으로 설명할 것이다.<br>\n<a href=\"https://www.data.go.kr/data/15012964/openapi.do\">국토교통부_공동주택 에너지 사용 정보</a> api로 api를 호출하면 xml 형태의 데이터를 반환해준다.</p>\n<h2 id=\"2-데이터-전처리\" style=\"position:relative;\"><a href=\"#2-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC\" aria-label=\"2 데이터 전처리 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 데이터 전처리</h2>\n<p>Filebeat가 파일을 읽어서 logstash로 보낼 때, 보통 csv 파일을 읽도록 하는 것이 편하기 때문에 Spring 환경에서 api를 호출하면서 xml 형태의 호출 결과를 csv 파일 형식으로 저장하도록 설정했다.<br>\n(<a href=\"https://www.elastic.co/guide/en/logstash/current/plugins-filters-xml.html\">Xml filter plugin</a>을 사용해서 Logstash에서 filter 설정을 하는 방법도 있다.)</p>\n<p>공공데이터 api 호출 방법은 <a href=\"https://www.data.go.kr/data/15012964/openapi.do\">국토교통부_공동주택 에너지 사용 정보</a> 하단에 샘플 코드를 제공하고 있어서 이를 활용해서 api 호출을 쉽게 할 수 있고, xml 호출 결과를 csv 파일로 변환하는 방법은 xsl 파일을 이용해서 csv 형태의 스타일로 바꿔서 파일을 저장하는 방식으로 진행했다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">void</span> <span class=\"token function\">xmlToCsv</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">String</span> xml<span class=\"token punctuation\">,</span> <span class=\"token class-name\">String</span> apiName<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token class-name\">Exception</span><span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">File</span> stylesheet <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">File</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"src/main/resources/data/\"</span> <span class=\"token operator\">+</span> apiName <span class=\"token operator\">+</span> <span class=\"token string\">\"Style.xsl\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token class-name\">DocumentBuilderFactory</span> factory <span class=\"token operator\">=</span> <span class=\"token class-name\">DocumentBuilderFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">newInstance</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">DocumentBuilder</span> builder <span class=\"token operator\">=</span> factory<span class=\"token punctuation\">.</span><span class=\"token function\">newDocumentBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Document</span> document <span class=\"token operator\">=</span> builder<span class=\"token punctuation\">.</span><span class=\"token function\">parse</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">InputSource</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">StringReader</span><span class=\"token punctuation\">(</span>xml<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token class-name\">StreamSource</span> stylesource <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">StreamSource</span><span class=\"token punctuation\">(</span>stylesheet<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Transformer</span> transformer <span class=\"token operator\">=</span> <span class=\"token class-name\">TransformerFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">newInstance</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">newTransformer</span><span class=\"token punctuation\">(</span>stylesource<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Source</span> source <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">DOMSource</span><span class=\"token punctuation\">(</span>document<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">Result</span> outputTarget <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">StreamResult</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">FileOutputStream</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"src/main/resources/data/\"</span> <span class=\"token operator\">+</span> apiName <span class=\"token operator\">+</span> <span class=\"token string\">\".csv\"</span><span class=\"token punctuation\">,</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        transformer<span class=\"token punctuation\">.</span><span class=\"token function\">transform</span><span class=\"token punctuation\">(</span>source<span class=\"token punctuation\">,</span> outputTarget<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span></code></pre></div>\n<p>[참고 : <a href=\"https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java\">https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java</a>]</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token prolog\">&lt;?xml version=\"1.0\"?></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>stylesheet</span> <span class=\"token attr-name\">version</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>1.0<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\"><span class=\"token namespace\">xmlns:</span>xsl</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>http://www.w3.org/1999/XSL/Transform<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>output</span> <span class=\"token attr-name\">method</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>text<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">omit-xml-declaration</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>yes<span class=\"token punctuation\">\"</span></span> <span class=\"token attr-name\">indent</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>no<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>template</span> <span class=\"token attr-name\">match</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>/<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\nreqDate,kaptCode,helect,hgas,hheat,hwaterCool\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>for-each</span> <span class=\"token attr-name\">select</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>//item<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token namespace\">xsl:</span>value-of</span> <span class=\"token attr-name\">select</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>concat(kaptCode, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, helect, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, hgas, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, hheat, <span class=\"token punctuation\">'</span>,<span class=\"token punctuation\">'</span>, hwaterCool, <span class=\"token punctuation\">'</span><span class=\"token entity\" title=\"&#xA;\">&amp;#xA;</span><span class=\"token punctuation\">'</span>)<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">/></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token namespace\">xsl:</span>for-each</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token namespace\">xsl:</span>template</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token namespace\">xsl:</span>stylesheet</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>위와 같은 형태의 xsl 파일을 이용해서 원하는 값들만 csv 스타일로 지정할 수 있다.<br>\n그러면 다음과 같은 xml 형식의 응답 데이터들 중 원하는 값들만 csv 파일에 저장할 수 있다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 103.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAAACXBIWXMAABYlAAAWJQFJUiTwAAACa0lEQVQ4y6WUiY7bNhCG9f6vmKKb9aG1dZHifYlfQXnXidCmMVoCQ0qcmZ//HGTX9z3zPGOMYVkW2v/1euV6uezrNE0YbdBa/1KUUk/p1nXFWov3/mkgpUSskqYTYsYFj3Nut2trsw0h4KwleEdKiRjjLl1Tto+mbCybcnf2jhg8cvzAB/fUP8GcxTqPcomfR9cMGyvnPUZrcgpYa9BK7fur0gRrcFrh3COKBiqlwIWEsIVcNrbtIV3ZKtYYslaEVLgLj/GZ10el1h/S5Vp3NmldcTHvgDGVh2mtbPXo8E9yCNk7iw+BmDMxBPIWSfmRx5bPJ49P56/QvqTttZx653DB0Y39BSHEnj9tDKtWWG9ZlcJYS0oRH/y+5hgPB3yNnDM5pZ1IN00zwzCijcUbg5gFWln0siAXgZR2X8Mq8VqT8oPlz6wPIbdJm4S+DeRhoCQorSbesrmEj1DbpBXZBla1kXM5AB6KknIhpEyyDtEPuHlGjhPLorBiwUpJKRsl5wObXxWoy6UQcyGFgrjcsOPIfBuZpxkxT6xSE7TFLQsl5X8F+wTcdsBoPettIoWHU9kruHsfu+43LdS1cMPnyaVUZD/Qv39wfj+jhCYay1Z/D/QEdDHtPVi3jXZr9DDTf79wOl2Rg8Cvmsp/AawNENRt4H6+M7R8Sr3nrdb/A3gfkdee2/nG/TrgFvkoSN5ey+ExZFg/7si3N07vF97+PDF+vyBPZ6KLrwHaBvhZlEZCnK+s58telG9/vDFfR+T7O9741wBNiPiY8doj+gmv3eERqLvUl8AeN6U1dtpwYiUo/Xzj/vbqvViUvwAEumjH43YjgAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"xml-example.png\"\n        title=\"xml-example.png\"\n        src=\"/static/f401e36cfcfc150b566dc4489bfdb353/37523/xml-example.png\"\n        srcset=\"/static/f401e36cfcfc150b566dc4489bfdb353/e9ff0/xml-example.png 180w,\n/static/f401e36cfcfc150b566dc4489bfdb353/f21e7/xml-example.png 360w,\n/static/f401e36cfcfc150b566dc4489bfdb353/37523/xml-example.png 720w,\n/static/f401e36cfcfc150b566dc4489bfdb353/302a4/xml-example.png 1080w,\n/static/f401e36cfcfc150b566dc4489bfdb353/f1c64/xml-example.png 1390w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span><br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 624px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 81.66666666666667%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACRklEQVQ4y3WTuW/bMBTGNQZIh9qe0jUZfOimqJuHJMpxUKBoUfQAOhRFlqD///4V7zlW5MQdHmjJ1A/fQXpffz/hx+Nf/Hz8i+9/nvD51yO6h08omxaV0qja8ynbt++mUQaeUCNS5SCUgzp8gfn4DZUdYXoH3Tk02qLtetTG8qje8bMeRjSmg90feG1NjyCM4AmRIY4TpEkKbXvY3vEf19fvcHV1hZubDzBuhOoH1Nrwx6mU8KMAQRQijCMEYYggCLDdbuEJWSARErSaYc+qdkEEz/N4FosF7LBHrSyqRkOZHkXZ8O9UZNis1wyi2e128NIsR5xmEFkO0++h7IBdEE7A5XLFQDPco2oUR0B5qc4hy0tsNxsGnYYVxql8Bo7Q/Qg/jGfAJay7Z0DZKJR1i1oZziyKYmy3l4BCgpQSjGzPLRPQUAG6Y5uyqGCHe4ZuZupeWT4CSQWpmStcLJecq+5GVlVUzdGydUhENoHeKCTLBKM5K4UsD3tYd2CVBCSFnLXvXwYmbFmyEsrxdSndeEDz3HJe1hxL3Rqs1+vJ7mSZmnppebyosHNHRVMpreHn09k7y/AMSNaoFH+mcLXiW0MQOjZ8xRqNzh2Q5cVZMW+AF1teHc/hqZBWdwzX/z2HDDy2TDDKaw58v1ig3z8wgNRRlnRkaC8BN5uXm8JXr6pqxEmCoizRtAoyL5CkKe7u7nB7e8ubyqqGzHNImSOTkte8KJEKgSiKEMfxNN4RICAyiTAMWTaFfdoQPb/zff/V0D6f987nH6HC+UYuar6NAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"csv-example.png\"\n        title=\"csv-example.png\"\n        src=\"/static/4852c8e7c3d091af1a38fa4440ef5157/39c09/csv-example.png\"\n        srcset=\"/static/4852c8e7c3d091af1a38fa4440ef5157/e9ff0/csv-example.png 180w,\n/static/4852c8e7c3d091af1a38fa4440ef5157/f21e7/csv-example.png 360w,\n/static/4852c8e7c3d091af1a38fa4440ef5157/39c09/csv-example.png 624w\"\n        sizes=\"(max-width: 624px) 100vw, 624px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>(reqDate의 경우는 응답 데이터에는 없지만 따로 필요하기 때문에 위 <code class=\"language-text\">xmlToCsv()</code> 메소드를 수정해서 추가했습니다.)</p>\n<hr>\n<h2 id=\"3-elasticsearch-및-kibana-실행\" style=\"position:relative;\"><a href=\"#3-elasticsearch-%EB%B0%8F-kibana-%EC%8B%A4%ED%96%89\" aria-label=\"3 elasticsearch 및 kibana 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. Elasticsearch 및 Kibana 실행</h2>\n<p>앞서 포스트에서 진행한 것처럼 Elastic Stack 전부 다 설치 완료되었다고 생각하고 같은 방법으로 실행하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">brew services start elastic/tap/elasticsearch-full\nbrew services start elastic/tap/kibana-full</code></pre></div>\n<p>위 명령어로 Elasticsearch와 Kibana를 백그라운드에서 실행해주고, 이제 Logstash 설정으로 넘어가면 된다.</p>\n<hr>\n<h2 id=\"4-logstash-설정-및-실행\" style=\"position:relative;\"><a href=\"#4-logstash-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"4 logstash 설정 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. Logstash 설정 및 실행</h2>\n<p>실행하기 전에 인덱싱하기 적절하게 필터링을 위한 설정 파일(<code class=\"language-text\">logstash-sample.conf</code>)을 수정하여 필터링 설정을 할 수 있는데 Homebrew를 통해 설치한 경우에는 다음과 같은 경로에 Logstash의 설정 파일들이 위치해 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /opt/homebrew/etc/logstash\n<span class=\"token function\">vi</span> logstash-sample.conf</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># Sample Logstash configuration for creating a simple</span>\n<span class=\"token comment\"># Beats -> Logstash -> Elasticsearch pipeline.</span>\ninput <span class=\"token punctuation\">{</span>\n  beats <span class=\"token punctuation\">{</span>\n    port <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">5044</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\noutput <span class=\"token punctuation\">{</span>\n  elasticsearch <span class=\"token punctuation\">{</span>\n    hosts <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"http://localhost:9200\"</span><span class=\"token punctuation\">]</span>\n    index <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}\"</span>\n    <span class=\"token comment\">#user => \"elastic\"</span>\n    <span class=\"token comment\">#password => \"changeme\"</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>처음 설정 파일을 열어보면 위와 같이 파일이 구성되어 있는데 여기서 <code class=\"language-text\">filter</code>를 추가하여 필터링 설정을 할 수 있다.<br>\n“message” 필드를 통해 데이터들이 들어오고 csv 형태의 파일들은 ”,“를 기준으로 데이터들이 나뉘기 때문에 이를 이용해서 값들을 나누어주면 된다.<br>\n나뉜 값들은 이름을 지정해서 새로운 필드로 추가해주면 되고, 기본으로 제공하는 필요없는 필드들은 제거해주면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># Sample Logstash configuration for creating a simple</span>\n<span class=\"token comment\"># Beats -> Logstash -> Elasticsearch pipeline.</span>\ninput <span class=\"token punctuation\">{</span>\n  beats <span class=\"token punctuation\">{</span>\n    port <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token number\">5044</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\nfilter <span class=\"token punctuation\">{</span>\n  mutate <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">split</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"message\"</span>, <span class=\"token string\">\",\"</span><span class=\"token punctuation\">]</span>\n    add_field <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n      <span class=\"token string\">\"reqDate\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][0]}\"</span>\n      <span class=\"token string\">\"kaptCode\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][1]}\"</span>\n      <span class=\"token string\">\"helect\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][2]}\"</span>\n      <span class=\"token string\">\"hgas\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][3]}\"</span>\n      <span class=\"token string\">\"hheat\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][4]}\"</span>\n      <span class=\"token string\">\"hwaterCool\"</span> <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[message][5]}\"</span>\n    <span class=\"token punctuation\">}</span>\n\n    remove_field <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"ecs\"</span>, <span class=\"token string\">\"host\"</span>, <span class=\"token string\">\"@version\"</span>, <span class=\"token string\">\"agent\"</span>, <span class=\"token string\">\"log\"</span>, <span class=\"token string\">\"tags\"</span>, <span class=\"token string\">\"input\"</span>, <span class=\"token string\">\"message\"</span><span class=\"token punctuation\">]</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\noutput <span class=\"token punctuation\">{</span>\n  elasticsearch <span class=\"token punctuation\">{</span>\n    hosts <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token punctuation\">[</span><span class=\"token string\">\"http://localhost:9200\"</span><span class=\"token punctuation\">]</span>\n    index <span class=\"token operator\">=</span><span class=\"token operator\">></span> <span class=\"token string\">\"%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}\"</span>\n    <span class=\"token comment\">#user => \"elastic\"</span>\n    <span class=\"token comment\">#password => \"changeme\"</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>이렇게 설정한 후에는 해당 디렉토리에서 다음 명령어를 통해 <strong>Logstash</strong>를 실행한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">logstash -f logstash-sample.conf</code></pre></div>\n<hr>\n<h2 id=\"5-filebeat-설정-및-실행\" style=\"position:relative;\"><a href=\"#5-filebeat-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\" aria-label=\"5 filebeat 설정 및 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. Filebeat 설정 및 실행</h2>\n<p>실행하기 전에 설정 파일(<code class=\"language-text\">filebeat.yml</code>)을 수정하여 <strong>input</strong>과 <strong>output</strong>에 대한 설정을 할 수 있다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token builtin class-name\">cd</span> /opt/homebrew/etc/filebeat\n<span class=\"token function\">vi</span> filebeat.yml</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># ============================== Filebeat inputs ===============================</span>\n\nfilebeat.inputs:\n\n<span class=\"token comment\"># Each - is an input. Most options can be set at the input level, so</span>\n<span class=\"token comment\"># you can use different inputs for various configurations.</span>\n<span class=\"token comment\"># Below are the input specific configurations.</span>\n\n<span class=\"token comment\"># filestream is an input for collecting log messages from files.</span>\n- type: filestream\n\n  <span class=\"token comment\"># Change to true to enable this input configuration.</span>\n  enabled: <span class=\"token boolean\">true</span>\n\n  <span class=\"token comment\"># Paths that should be crawled and fetched. Glob based paths.</span>\n  paths:\n    - /Users/jfe/Desktop/Carbon_Tracker/Server/carbonTracker/src/main/resources/data/aptEnergy.csv</code></pre></div>\n<p>설정 파일에서 input 부분에서 filestream 타입의 input을 허용해주기 위해 enabled: true로 바꿔주고, 읽기 원하는 데이터 파일의 경로를 지정해주면 된다.<br>\n그 다음, Filebeat -> Logstash -> Elasticsearch -> Kibana 순서로 데이터를 보내기 때문에 Elasticsearch로의 output 부분은 전부 주석 처리해주고, Logstash로의 output 부분 주석들을 해제해주면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token comment\"># ---------------------------- Elasticsearch Output ----------------------------</span>\n<span class=\"token comment\"># output.elasticsearch:</span>\n  <span class=\"token comment\"># Array of hosts to connect to.</span>\n  <span class=\"token comment\"># hosts: [\"localhost:9200\"]</span>\n\n  <span class=\"token comment\"># Protocol - either `http` (default) or `https`.</span>\n  <span class=\"token comment\">#protocol: \"https\"</span>\n\n  <span class=\"token comment\"># Authentication credentials - either API key or username/password.</span>\n  <span class=\"token comment\">#api_key: \"id:api_key\"</span>\n  <span class=\"token comment\">#username: \"elastic\"</span>\n  <span class=\"token comment\">#password: \"changeme\"</span>\n\n<span class=\"token comment\"># ------------------------------ Logstash Output -------------------------------</span>\noutput.logstash:\n  <span class=\"token comment\"># The Logstash hosts</span>\n  hosts: <span class=\"token punctuation\">[</span><span class=\"token string\">\"localhost:5044\"</span><span class=\"token punctuation\">]</span></code></pre></div>\n<p>이렇게 설정한 후에는 해당 디렉토리에서 다음 명령어를 통해 <strong>Filebeat</strong>를 실행하면 된다.</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\">filebeat -e                 <span class=\"token comment\"># 일반적으로 실행 하는 경우</span>\nfilebeat -e -c filebeat.yml <span class=\"token comment\"># -c 옵션은 configuration 파일을 특정할 때 사용 (-c 사용안하면 default는 filebeat.yml)</span></code></pre></div>\n<hr>\n<h2 id=\"6-kibana에서-데이터-확인\" style=\"position:relative;\"><a href=\"#6-kibana%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%99%95%EC%9D%B8\" aria-label=\"6 kibana에서 데이터 확인 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>6. Kibana에서 데이터 확인</h2>\n<p><a href=\"http://localhost:5601\">http://localhost:5601</a> 에 접속하여 제대로 실행되었는지 확인하고, Index Patterns로 이동해서 index pattern을 설정하면 된다.<br>\n데이터가 정상적으로 수집되고 있으면 해당 index가 보여지고, 그 index를 기준으로 pattern을 만들 수 있다.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 40.55555555555556%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAACI0lEQVQoz12Ry0tUcQCFf/9GEUUgYU9qkS2yFhIFY7SwIMvAXovIGR/RUkKitdIqhNyViZtSE2Mc853N5DiDOlLNI3PseseZe+d178x9OV80yw4cDt+BszriYsMl6urqOXbiNLVHT3Gk9iT7DxymoeEKbe523O4OPO2duD2deNq7aPN00ubuoKPrKU03mjl4qIaaI8er27Pn6hHvfVMMjo3j8/qYm19gdm6e6c8zzAeWCUYl/OubrMZkElKWhJznRzLDz22FmKQQikTx+qaZnJqp5ifvFAIgpxvEN3dJSipJKYuatzAqFaRcAVktkjVMiqaFVbJwDJuybqBldcyyyf8SpgN6egU1cAs1+IDst1YKG4/Ij3xBeTaG2usl1zNGaugrno0QLSE/98MBboaXeBmK8XgoQetgjLvvYrS8jSLMCpjyKEwLcmu3KQfPg1+g9ryhUNdH8tUs6oU+pCfDiLlx9s1O0Lq8iJgc5vJEEPHQT2P/Kmd61xD3FhDmHljZAFbIhRZqprTShLHRjPZhkXz3R+QXo+S7R1AG/dz5HsYVWuJ6cAlXxM/zlTjXBuK4BiJcfR2hsX8dYVoOtlNBTmWIRmPEE7/I5Yo4VPj9Z5vw6hqbySTWnoNtmsg7MrF4grKm49gOZV2v8tbWFrZpIEx7D8tyKJVKaJpetfHvBE1nZydFOqOQSqUpFvVqt5vOkE5nUNQslmWTUdQqp1K75AsF/gLyBwP70vVXoAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-main.png\"\n        title=\"kibana-main.png\"\n        src=\"/static/cffc3594a69348a953cc88b2eee861a2/37523/kibana-main.png\"\n        srcset=\"/static/cffc3594a69348a953cc88b2eee861a2/e9ff0/kibana-main.png 180w,\n/static/cffc3594a69348a953cc88b2eee861a2/f21e7/kibana-main.png 360w,\n/static/cffc3594a69348a953cc88b2eee861a2/37523/kibana-main.png 720w,\n/static/cffc3594a69348a953cc88b2eee861a2/302a4/kibana-main.png 1080w,\n/static/cffc3594a69348a953cc88b2eee861a2/07a9c/kibana-main.png 1440w,\n/static/cffc3594a69348a953cc88b2eee861a2/9dbdb/kibana-main.png 2622w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span><br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABw0lEQVQoz4WS227aUBBF/alVVZVbAraxccDG7n/krW0kpERVHvsZfWreGkWloglgwMbgyzle1TGlAZSoI22NdKRZ3nvGWjcIaJh93rzv8Lau865h0Gh2KrXODHSzR7OlU6ufU2u0qSvVz49Uq51Vvd3pon2+vuHyasTH0Reurm/5NLphOp2yWq1YLJeEiwVlWXJYKbCWkqTcKQcEVF0zDBND17EsC13XaTUbfL+7IwwXzOch8zBku00pCrGTEDxFEb+jiMc4YpmmJEXBNI5Z5zma41zQ7w/w/Q+43hA/CBiPf7HZpuRFQV4Isixnm2ZVF0KwjmI2yYZSSFDmy5IiLyhliWbbPTodHcfpMxi4eJ7Hj/sHJk9zwmXEKoormJQlQpZIKRFCIqSs4qt1HK5EsywbJdf1GLguvu8znjwSZyWrREUtKlf7wcPhw7e9tF7PwTS7lTsFDYKA2WzGa3UK2L/9c6iAyqHa4x6orqxKxXvJxUug58i2Q8+5qGCnwOdBqv1VO/wf0LQcjK7DcOjjecO/kY8d7k55HPtVoG3bqF9HAYfDHfD+54Qkk2y2OWlWsEwy/K9j2rcPfBuvdx87OdAe+Ae8TPPBSX0A1gAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-index-pattern.png\"\n        title=\"kibana-index-pattern.png\"\n        src=\"/static/54d099ba85bdf4915154b2cbb1c970cf/37523/kibana-index-pattern.png\"\n        srcset=\"/static/54d099ba85bdf4915154b2cbb1c970cf/e9ff0/kibana-index-pattern.png 180w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/f21e7/kibana-index-pattern.png 360w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/37523/kibana-index-pattern.png 720w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/302a4/kibana-index-pattern.png 1080w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/07a9c/kibana-index-pattern.png 1440w,\n/static/54d099ba85bdf4915154b2cbb1c970cf/60708/kibana-index-pattern.png 2872w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>생성한 index pattern에 대한 데이터들은 discover 메뉴로 가서 확인할 수 있다.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 720px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 55.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAACGklEQVQoz5WRW08TURSF59eChkDLzRB90N+ivnkBK4kSo/jAxRdIoNAiZdpaiEPbuU/ncmbOzGfOGZAXXzzJephk72/WWttYe/Gc+eYGc4+bLDVWWVx6UGN5nbX1pzRXntBorv/VYmOVuYVlHi2sMH+nxaU1misbGLdhipMW/O9TGxLIy/r7/VnAsx0LY+rNuLEcbMfHD2OiWYoQ9Q9kCXkh/61cImVJVUFRSG68lJ/jGMMPIn5bE8YThzBKyETBeGJjmn0syyJOUmZxQhwnREqzWgo6mTr0BwOSTAC1VcPzI6yxrQdELsllSffS5M3bd+wfHOK4Prbr47geE9vDmno4XkgQzjg5bTOe2mQip6wqRF5gBLOEJBXkRandVYA5vGZz6wN7e/s4XqDlej5T12fiBNheQJJmXJl9elem3q8UUOQYajiMYg1UUoNfvu6yudViMBwRhBGuH2inUzfUsCCKtRsF63QvSLOcLBNkQmCoQ8RJVgNzSVGUHJ+0aX3c5rR9hueHuNqlAgZMHB8viDSk07nA7A90skJXlmPYbog6TCEr0qygrOBqMKLV2ubg8Mcd7CHy2FadBqSZYDi6ptPtMktSDVSxjTgVJFmuncVpgZDQ6w/59HmHo6NjHde9Bzq+dngPVB22z87vgHX/xn136sJK6p13e7x89Zpvu9/rC3t1hwp2a/u4fqhjXvZMfl3f6D0pJWVZ8Qe/ayPgJZiQrQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"kibana-discover.png\"\n        title=\"kibana-discover.png\"\n        src=\"/static/954a25229ec00314a2a324ae7e59c5c2/37523/kibana-discover.png\"\n        srcset=\"/static/954a25229ec00314a2a324ae7e59c5c2/e9ff0/kibana-discover.png 180w,\n/static/954a25229ec00314a2a324ae7e59c5c2/f21e7/kibana-discover.png 360w,\n/static/954a25229ec00314a2a324ae7e59c5c2/37523/kibana-discover.png 720w,\n/static/954a25229ec00314a2a324ae7e59c5c2/302a4/kibana-discover.png 1080w,\n/static/954a25229ec00314a2a324ae7e59c5c2/07a9c/kibana-discover.png 1440w,\n/static/954a25229ec00314a2a324ae7e59c5c2/93ba6/kibana-discover.png 2874w\"\n        sizes=\"(max-width: 720px) 100vw, 720px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<hr>\n<p>공공데이터 api를 연동해서 얻은 데이터를 Filebeat -> Logstash -> Elasticsearch -> Kibana 순서로 수집하는 방법에 대해서 간단하게만 포스팅했는데, 그래서 데이터 전처리도 아직 완벽하게 하지 않았고 Kibana 사용 방법도 아직 제대로 알지는 못해서 프로젝트를 더 진행하면서 추후에 프로젝트 진행 과정과 회고와 함께 추가로 포스팅하겠습니다. (종프 화이팅,,)</p>\n<hr>\n<h2 id=\"-reference\" style=\"position:relative;\"><a href=\"#-reference\" aria-label=\" reference permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>📎 Reference</h2>\n<p><a href=\"https://www.data.go.kr/data/15012964/openapi.do\">https://www.data.go.kr/data/15012964/openapi.do</a><br>\n<a href=\"https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java\">https://stackoverflow.com/questions/21413978/convert-an-xml-file-to-csv-file-using-java</a><br>\n<a href=\"https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-1/\">https://taetaetae.github.io/posts/make-dashboards-from-elasticstack-1/</a><br>\n<a href=\"http://trandent.com/article/etc/detail/323366\">http://trandent.com/article/etc/detail/323366</a></p>\n<div class=\"table-of-contents\">\n<ul>\n<li><a href=\"#1-%EA%B3%B5%EA%B3%B5%EB%8D%B0%EC%9D%B4%ED%84%B0-api-%EC%A4%80%EB%B9%84\">1. 공공데이터 api 준비</a></li>\n<li><a href=\"#2-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A0%84%EC%B2%98%EB%A6%AC\">2. 데이터 전처리</a></li>\n<li><a href=\"#3-elasticsearch-%EB%B0%8F-kibana-%EC%8B%A4%ED%96%89\">3. Elasticsearch 및 Kibana 실행</a></li>\n<li><a href=\"#4-logstash-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\">4. Logstash 설정 및 실행</a></li>\n<li><a href=\"#5-filebeat-%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%8B%A4%ED%96%89\">5. Filebeat 설정 및 실행</a></li>\n<li><a href=\"#6-kibana%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%99%95%EC%9D%B8\">6. Kibana에서 데이터 확인</a></li>\n<li><a href=\"#-reference\">📎 Reference</a></li>\n</ul>\n</div>","frontmatter":{"date":"April 09, 2022","title":"[Elastic] Elastic Stack + 공공데이터 api 활용","categories":"Database","author":"JFe","emoji":"🏢"},"fields":{"slug":"/elastic-open-data-api/"}},"prev":{"id":"85e77e03-4abc-573d-a59b-79c4c8065c69","html":"<h2 id=\"2019-카카오-개발자-겨울-인턴십\" style=\"position:relative;\"><a href=\"#2019-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD\" aria-label=\"2019 카카오 개발자 겨울 인턴십 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>[2019 카카오 개발자 겨울 인턴십]</h2>\n<h2 id=\"문제\" style=\"position:relative;\"><a href=\"#%EB%AC%B8%EC%A0%9C\" aria-label=\"문제 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>문제</h2>\n<p><a href=\"https://programmers.co.kr/learn/courses/30/lessons/64061\">https://programmers.co.kr/learn/courses/30/lessons/64061</a></p>\n<p>게임개발자인 “죠르디”는 크레인 인형뽑기 기계를 모바일 게임으로 만들려고 합니다.<br>\n“죠르디”는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsSAAALEgHS3X78AAADfElEQVQ4y6WV2W4jRRSG8xYRCM0k8dJ7ddvtpdtL2nY2Dx4nxPHWbmfDEKIhKBIQMROxXGTECCQkBBIX3CPxCjwDD/WhKtuBgZkL4OLoHJ36+6//1Kk6vWJYDhnDYtCJ2KyWyOgWMmdY9sL/O1uxbJs3Hnr8fLNK0knx1oaLzOmm898I05qgHaW5uwn5ZGZj28aC7NUKdfP1yuXaSkoT7O9l8EuCzq5GqWCQ1f8HoW45ZHUL2zaxHRvNmJPJxVeZofCmipd+GauSNcOiFFTw/JIithyhAKYtFGDpl7HEV2qbCC9Ppb55n6/Wo7nCdFan0z2gHjWRsQTKj2zhKaC+KGW5STqr0RuMKIdVRpNE5S3HZZxM/yR81OkSNbdUIucXFcDL+Qg3hyM8HJFTGzhunnTK4qg3pBhUGIxilXdzPsPx5GVCqVCeg5cvKCWOVOqV0IS/KFvg+h7auU/nIqZcCBmM4znWzf2TsBY1yWiGWkxlLXTTIjq6pLjdQ9N1NFNQDT0uP3MZXI0o+pV7Qqly8BLh4y6N1vb8wMMqnXaLYjlguF+jvRVg2J4qX57v+nqGfn+kGilVSQGyqmGc/F1hgwdrWZq7Ib//VmW/W+XFkxpX44AHaQvTtNBFnlL3mHfiE0rlgP4ovm/WMJ4sXspCYb3RRNNM3FrI2SyiVi3TCHwqxRyaJbBsoa5WbTdhPJ1RLJWVqqXCcXI8J5SNiLZ2eP75F3z16TOaUcivP7XY3Q15fnvH+fSU6WjM93dfky8U+OXHgC9vz3FyIcNxrEjkrRjFyZxQNmJrr83Hl9dcxe9RaJX57luXt/dCbj64Ynp0RK9zyNPZR7hhkW9eCG5vpoh8yCieKDLh5RhNpsvhoNPe67I92WT10KIRBTyb1QnKBd7UPNayLrmWxVrikhF5VlM+j3sx5SCkP5KEnrpio3i6VKiz097n6nqHgyc2UavID9d1wpLDzviCYPuQ/QOL5GkevVjgUfIh47OZaso4maj3L1xBcnxPaNOI8lwkGU4PH3LSX+fkaJ2TwTrvTjTO4gwn/TXOe2ucDjaYJRqzqcC0PaZDl/eTNWXJwCOjO6xI1nTWwPEKeH6ZVNakUm+iWy75QqBMtzxq0RYbGYPaZgvdnA+JjGapUSdNxnJKrSxHkmnPTSbl+5VeTh5pMraFe+/nOOcvvwp7MQ8d/gBoYJdIZzdHEgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"crane_game_101.png\"\n        title=\"crane_game_101.png\"\n        src=\"/static/85f3edaab791c9ecf6f0a2ee2318c1d3/0b533/crane_game_101.png\"\n        srcset=\"/static/85f3edaab791c9ecf6f0a2ee2318c1d3/e9ff0/crane_game_101.png 180w,\n/static/85f3edaab791c9ecf6f0a2ee2318c1d3/f21e7/crane_game_101.png 360w,\n/static/85f3edaab791c9ecf6f0a2ee2318c1d3/0b533/crane_game_101.png 500w\"\n        sizes=\"(max-width: 500px) 100vw, 500px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>게임 화면은 “1 x 1” 크기의 칸들로 이루어진 “N x N” 크기의 정사각 격자이며 위쪽에는 크레인이 있고 오른쪽에는 바구니가 있습니다. (위 그림은 “5 x 5” 크기의 예시입니다). 각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다. 모든 인형은 “1 x 1” 크기의 격자 한 칸을 차지하며 격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다. 게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다. 집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다. 다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 500px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsSAAALEgHS3X78AAADfUlEQVQ4y6WUyW4jVRSG8xYtECJO7HLNg8tTlR27PKSdwXHSHsoux24naUuNQhpYoEhNFtAoiGnBKLFgj8Qr8Aw81IfudZyoRbMAFkfn1H//+9d/T9U9G7ppo+gmcTeiXi2haCYC003rLv+72DAti7c2PX69fsSsm+adbReBaYb93wQzqsN+lOH2OuTjpYVl6Xdib3aoGf/sXKxtpFWH4z2FfMmh21EpFXSy2v8Q1EybrGZiWQaWbaHqKzGx+KbQJd+Q9Tqva3lkVTcpBRW8fEkKm7YjCYblSMI6r2vBr+zUcTyfSq1+j1dr0cphJqvR7Z1Qi5qIWhDFJsvx7sXWLsRzWlEZxGPKlSqT05nETdslmc0fBA+6PaJmWwK5fFES3Fwe281JYdvxZF6/bBBP5KniZCpxwR0np68LCoeiD55fkE7EZtv1ZAvEswixWVF1+qPxSnAylbh48d8Ed6KmJIvFbcWQLhXNQdEf+igwVTPoD2MpOJpMJea4OeLXBI96NFq7q4aHVbr7LYrlgOFhQKdZRLc8uUm43kyrDMaJFJxMZ2RNB93J3ffzwWE9YjOVpdkJ+POPKse9Kl9f1XkxDXg3Y2IYJprjUz6a82S6oBSE9IcjSo+HlPdG8kOJk9w5PKbR3kXXLXK1CufPInaqAY3Ap1LMoZoOpuXIX6vamZHMl/IE8Tih0DgkaPeYJFN003lwWG80SGVU2s0qv//SotMJ+eLmlov5GfNJwg+3X+IXCvz2c8CnNxc4fkg8mlJfeNiXRYbjGYZlrwQPj3pUam0ymzr5VpnvvvU43Au5fu8F8+GQQbfPy+UHuGGRb75yuLme4/ohw/EpoycWByOHQfIUYzUcNPb2enTPd0klPo0o5JNljaBc4G3VI5V1ybVMUjMXxfF5lM5zNJgShBVOhjFPjgYMezGDOFn1UFE1OvvHXH24S+/SJGoV+emjGmHJ5nHynGC3z/GJyeylj1YscDC7YnqxpByEDOKYHz9/xfevPmM8vRe0aEQ+z2cKZ/1NFqMtFsMtFvEWz05VzqcKi1GKi0GKs3ib5UxlOXcwbI/Z2OHy6TbvL9KcjlyymsOG+GEzWR3bK+Dly6SzBpVaE8108QuBDM302InabCs6O/UWmrEaEopqklEtGaIWU2pjPZLEFxIhQHF3RRbXToSoLce9zyve3QS6i9UQsfkLYryXSvH22aQAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"crane_game_102.png\"\n        title=\"crane_game_102.png\"\n        src=\"/static/ba3ff32daf32719c2af0f7e697036f99/0b533/crane_game_102.png\"\n        srcset=\"/static/ba3ff32daf32719c2af0f7e697036f99/e9ff0/crane_game_102.png 180w,\n/static/ba3ff32daf32719c2af0f7e697036f99/f21e7/crane_game_102.png 360w,\n/static/ba3ff32daf32719c2af0f7e697036f99/0b533/crane_game_102.png 500w\"\n        sizes=\"(max-width: 500px) 100vw, 500px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n    </span></p>\n<p>만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다. 위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형 두 개가 없어집니다.</p>\n<p><img src=\"/bb66573d0de119e32fbca8f773cc9ee6/crane_game_103.gif\" alt=\"crane_game_103.gif\"></p>\n<p>크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는 아무런 일도 일어나지 않습니다. 또한 바구니는 모든 인형이 들어갈 수 있을 만큼 충분히 크다고 가정합니다. (그림에서는 화면표시 제약으로 5칸만으로 표현하였음)</p>\n<p>게임 화면의 격자의 상태가 담긴 2차원 배열 board와 인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때, 크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.</p>\n<hr>\n<h2 id=\"제한사항\" style=\"position:relative;\"><a href=\"#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD\" aria-label=\"제한사항 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>제한사항</h2>\n<ul>\n<li>board 배열은 2차원 배열로 크기는 “5 x 5” 이상 “30 x 30” 이하입니다.</li>\n<li>board의 각 칸에는 0 이상 100 이하인 정수가 담겨있습니다.\n<ul>\n<li>0은 빈 칸을 나타냅니다.</li>\n<li>1 ~ 100의 각 숫자는 각기 다른 인형의 모양을 의미하며 같은 숫자는 같은 모양의 인형을 나타냅니다.</li>\n</ul>\n</li>\n<li>moves 배열의 크기는 1 이상 1,000 이하입니다.</li>\n<li>moves 배열 각 원소들의 값은 1 이상이며 board 배열의 가로 크기 이하인 자연수입니다.</li>\n</ul>\n<hr>\n<h2 id=\"입출력-예\" style=\"position:relative;\"><a href=\"#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88\" aria-label=\"입출력 예 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>입출력 예</h2>\n<table>\n<thead>\n<tr>\n<th>board</th>\n<th>moves</th>\n<th>return</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]]</td>\n<td>[1,5,3,5,1,2,1,4]</td>\n<td>4</td>\n</tr>\n</tbody>\n</table>\n<hr>\n<h2 id=\"-algorithm\" style=\"position:relative;\"><a href=\"#-algorithm\" aria-label=\" algorithm permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🔍 Algorithm</h2>\n<p><strong>Stack</strong></p>\n<h2 id=\"-logic\" style=\"position:relative;\"><a href=\"#-logic\" aria-label=\" logic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>💻 Logic</h2>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> moves<span class=\"token punctuation\">:</span>     <span class=\"token comment\"># moves 배열 반복</span>\n    <span class=\"token keyword\">for</span> j <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>board<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">if</span> board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>      <span class=\"token comment\"># 0이 아닌 값 나올 때까지 반복, continue 이용해서 깊이 깊어지지 않도록</span>\n            <span class=\"token keyword\">continue</span>\n        <span class=\"token keyword\">if</span> bucket <span class=\"token keyword\">and</span> bucket<span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>  <span class=\"token comment\"># stack의 top과 값이 같으면 append 하지 않고 pop한 뒤, answer 값 +2 증가</span>\n            board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n            bucket<span class=\"token punctuation\">.</span>pop<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            answer <span class=\"token operator\">+=</span> <span class=\"token number\">2</span>\n            <span class=\"token keyword\">break</span>\n        <span class=\"token comment\"># top과 값이 다르면 append</span>\n        bucket<span class=\"token punctuation\">.</span>append<span class=\"token punctuation\">(</span>board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n        board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">break</span></code></pre></div>\n<ul>\n<li><code class=\"language-text\">if board[j][i-1] == 0:</code><br>\n0이 아닌 값 나올 때까지 반복<br>\n0이 아닐 때로 하게 되면 코드 깊이가 깊어져서 continue를 이용해서 깔끔하게 만들었다.</li>\n<li><code class=\"language-text\">if bucket and bucket[-1] == board[j][i-1]:</code><br>\nstack의 top과 값이 같으면 append 하지 않고, top 값을 pop<br>\nstack의 top은 <code class=\"language-text\">bucket[-1]</code>처럼 접근 가능<br>\n<code class=\"language-text\">bucket.pop()</code> 부분은 <code class=\"language-text\">bucket = bucket[:-1]</code>처럼 슬라이싱으로도 구현 가능하다.</li>\n</ul>\n<hr>\n<h2 id=\"-code\" style=\"position:relative;\"><a href=\"#-code\" aria-label=\" code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>🧩 Code</h2>\n<details><summary>전체 코드 확인</summary>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">solution</span><span class=\"token punctuation\">(</span>board<span class=\"token punctuation\">,</span> moves<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    answer<span class=\"token punctuation\">,</span> bucket <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> moves<span class=\"token punctuation\">:</span>     <span class=\"token comment\"># moves 배열 반복</span>\n        <span class=\"token keyword\">for</span> j <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>board<span class=\"token punctuation\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">if</span> board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>      <span class=\"token comment\"># 0이 아닌 값 나올 때까지 반복, continue 이용해서 깊이 깊어지지 않도록</span>\n                <span class=\"token keyword\">continue</span>\n            <span class=\"token keyword\">if</span> bucket <span class=\"token keyword\">and</span> bucket<span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">==</span> board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">:</span>  <span class=\"token comment\"># stack의 top과 값이 같으면 append 하지 않고 pop한 뒤, answer 값 +2 증가</span>\n                board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n                bucket<span class=\"token punctuation\">.</span>pop<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                answer <span class=\"token operator\">+=</span> <span class=\"token number\">2</span>\n                <span class=\"token keyword\">break</span>\n            <span class=\"token comment\"># top과 값이 다르면 append</span>\n            bucket<span class=\"token punctuation\">.</span>append<span class=\"token punctuation\">(</span>board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n            board<span class=\"token punctuation\">[</span>j<span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span>i<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n            <span class=\"token keyword\">break</span>\n    <span class=\"token keyword\">return</span> answer</code></pre></div>\n</details>\n<hr>\n<h2 id=\"-review\" style=\"position:relative;\"><a href=\"#-review\" aria-label=\" review permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>📝 Review</h2>\n<p>문제 해결 방법 자체는 빨리 찾아내서 어떻게 하면 코드를 더 예쁘게, 빠르게 돌아가도록 할 수 있을지에 대해 고민했다.</p>\n<div class=\"table-of-contents\">\n<ul>\n<li><a href=\"#2019-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EA%B0%9C%EB%B0%9C%EC%9E%90-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD\">[2019 카카오 개발자 겨울 인턴십]</a></li>\n<li><a href=\"#%EB%AC%B8%EC%A0%9C\">문제</a></li>\n<li><a href=\"#%EC%A0%9C%ED%95%9C%EC%82%AC%ED%95%AD\">제한사항</a></li>\n<li><a href=\"#%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%98%88\">입출력 예</a></li>\n<li><a href=\"#-algorithm\">🔍 Algorithm</a></li>\n<li><a href=\"#-logic\">💻 Logic</a></li>\n<li><a href=\"#-code\">🧩 Code</a></li>\n<li><a href=\"#-review\">📝 Review</a></li>\n</ul>\n</div>","frontmatter":{"date":"April 16, 2022","title":"[Programmers] 64061번: 크레인 인형뽑기 게임 (Python)","categories":"Algorithm","author":"JFe","emoji":"💻"},"fields":{"slug":"/pg-64061/"}},"site":{"siteMetadata":{"siteUrl":"https://jfelog.netlify.app","comments":{"utterances":{"repo":"Go-Jaecheol/Jfe_Blog"}}}}},"pageContext":{"slug":"/pg-42861/","nextSlug":"/elastic-open-data-api/","prevSlug":"/pg-64061/"}},
    "staticQueryHashes": ["1073350324","1956554647","2938748437"]}