<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>구르는 중</title>
    <link>https://coding-maggot.tistory.com/</link>
    <description>구르는 재주 연마 중</description>
    <language>ko</language>
    <pubDate>Tue, 26 May 2026 10:36:46 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>코딩굼벵이</managingEditor>
    <image>
      <title>구르는 중</title>
      <url>https://tistory1.daumcdn.net/tistory/4435151/attach/306fd13bbc7c472787627db1b9796ef5</url>
      <link>https://coding-maggot.tistory.com</link>
    </image>
    <item>
      <title>[Gitlab][Linux] error: gpg failed to sign the data fatal: failed to write commit object 해결 방법</title>
      <link>https://coding-maggot.tistory.com/117</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;[ git commit, push하면 gpg 에러로 실패할 때 해결 방법 ]&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 PAT만 써서 git commit, push를 하고 있었는데,&lt;br /&gt;어느 시점부터 commit에 gpg key sign이 돼야 한다고 뜨더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- git log&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;2025-07-18&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;13:37:12.717&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;[info]&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;gt; git push origin main:main [5357ms]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;2025-07-18&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #6a9955;&quot;&gt;13:37:12.717&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;[info]&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;remote: GitLab: Commit must be signed with a GPG key&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;To&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;https://gitlab.&amp;lt;repo-path&amp;gt;.git&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp;! [remote rejected] main -&amp;gt; main (pre-receive hook declined)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;error:&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;failed to push some refs to&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;'https://gitlab.&amp;lt;repo-path&amp;gt;.git'&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gpg 서명을 쓰기 싫어서 git config에서 commit.gpgsign을 false로 껐더니, &lt;br /&gt;이번엔 verified 된 email로 push commit을 해야 한다고 에러가 떴다.&lt;/p&gt;
&lt;pre id=&quot;code_1752816471312&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;remote: GitLab: You cannot push commits for 'kangyj@&amp;lt;company&amp;gt;.com'. You can only push commits if the committer email is one of your own verified emails.
To https://gitlab.&amp;lt;company-repo-path&amp;gt;.git
 ! [remote rejected] main -&amp;gt; main (pre-receive hook declined)
error: failed to push some refs to 'https://gitlab.&amp;lt;company-repo-path&amp;gt;.git'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 이메일 verified인데..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnSkGT/btsPn5Sxixv/LswkLGzuLn3hdHRQTHiVW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnSkGT/btsPn5Sxixv/LswkLGzuLn3hdHRQTHiVW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnSkGT/btsPn5Sxixv/LswkLGzuLn3hdHRQTHiVW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnSkGT%2FbtsPn5Sxixv%2FLswkLGzuLn3hdHRQTHiVW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;504&quot; height=&quot;231&quot; data-origin-width=&quot;504&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 gpg key를 생성해서 commit 해보니 다음 에러가 떴다.&lt;/p&gt;
&lt;pre id=&quot;code_1752817442766&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;gt; git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -
error: gpg failed to sign the data
fatal: failed to write commit object&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 현재 gitlab이 gpg key로 서명한 commit만 push가 가능하게 된 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 찾은 해결방법은 아래와 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[environment]&lt;br /&gt;OS : Ubuntu 22.04&lt;br /&gt;git --version : 2.34.1&lt;br /&gt;gpg --version : gpg 2.2.27&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. gpg key 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752816614612&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gpg --full-generate-key&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;348&quot; data-start=&quot;266&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;266&quot;&gt;권장 옵션:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;266&quot;&gt;RSA and RSA&lt;/li&gt;
&lt;li data-end=&quot;311&quot; data-start=&quot;295&quot;&gt;Key size: 4096&lt;/li&gt;
&lt;li data-end=&quot;330&quot; data-start=&quot;314&quot;&gt;Expire: 0 (영구)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Name/email 입력&lt;/li&gt;
&lt;li data-end=&quot;348&quot; data-start=&quot;333&quot;&gt;passphrase 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 입력한 passphrase를 기억해뒀다가 서명할 때 뜨는 창에 입력해야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. gpg id 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752816640461&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gpg --list-secret-keys --keyid-format LONG &amp;lt;email&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 결과 예시&lt;/p&gt;
&lt;pre id=&quot;code_1752816897225&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/home/yourname/.gnupg/secring.gpg
---------------------------------------
sec   4096R/ABCDEF1234567890 2023-01-01 [SC]
uid                          Your Name &amp;lt;your@email.com&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 ABCDEF1234567890 자리에 있는 게 gpg id.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. gpg key 등록&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gitlab 프로필 &amp;gt; preference &amp;gt; gpg keys 에서 아래 command 결과 (-----BEGIN ~ -----END 줄까지) 붙여넣기&lt;/p&gt;
&lt;pre id=&quot;code_1752816690471&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gpg --armor --export &amp;lt;gpg id&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. ~/.gitconfig에 아래 내용 포함&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752817040480&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[user]
        signingkey = &amp;lt;gpg id&amp;gt;
        email = &amp;lt;your_email&amp;gt;
        name = &amp;lt;your_name&amp;gt;
[commit]
        gpgsign = true
[gpg]
        program = gpg&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(git.config --global user.signingkey &amp;lt;gpg id&amp;gt; 같은 식으로 등록해도 됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5. ~/.bashrc 에 아래 줄 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752817101310&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export GPG_TTY=$(tty)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;source ~/.bashrc 로 적용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6. 서명 잘 되는지 테스트&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752817191975&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;echo &quot;test&quot; | gpg --clearsign&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 되면 commit -&amp;gt; push가 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;+ 생성한 gpg key를 &lt;/b&gt;&lt;b&gt;다른 환경에서도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;사용하고 싶을 때&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. gpg key 내보내기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752817925540&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gpg --export ABCDEF1234567890 &amp;gt; ~/public.key
gpg --export-secret-key ABCDEF1234567890 &amp;gt; ~/private.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ABCDEF1234567890 에 gpg --list-keys에서 나온 key id를 넣으면 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. gpg key를 옮길 환경으로 보내기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;pre id=&quot;code_1752818019667&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;scp ~/public.key root@&amp;lt;ip&amp;gt;:/root/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. gpg key 가져오기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752818076767&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gpg --import ~/public.key
gpg --import ~/private.key&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. 서명 잘 되는지 테스트&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1752818099535&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;echo &quot;test&quot; | gpg --clearsign&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;잘 되면 마찬가지로 commit -&amp;gt; push가 가능해진다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 환경에서도 ~/.gitconfig, ~/.bashrc 설정하는 것 잊지 말기!&lt;/p&gt;</description>
      <category>기타</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/117</guid>
      <comments>https://coding-maggot.tistory.com/117#entry117comment</comments>
      <pubDate>Fri, 18 Jul 2025 14:59:45 +0900</pubDate>
    </item>
    <item>
      <title>[Ubuntu] nvm으로 node version update &amp;amp; node version 유지</title>
      <link>https://coding-maggot.tistory.com/116</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;실행 환경: Ubuntu 22.04.3 LTS&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. nvm 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 통해 nvm 설치 or update 가능&lt;br /&gt;(curl, wget은 &lt;i&gt;sudo apt-get curl wget &lt;/i&gt;으로 설치 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- curl&lt;/p&gt;
&lt;pre id=&quot;code_1709614687402&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- wget&lt;/p&gt;
&lt;pre id=&quot;code_1709614716470&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nvm 설치 후 적용 방법&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;현재 터미널 종료 후 새로운 터미널 시작&lt;/li&gt;
&lt;li&gt;현재 터미널에서 아래 코드 입력&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709615302745&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 2가지 중 하나를 수행한 후 nvm --version을 확인해서 정상 설치 여부를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;244&quot; data-origin-height=&quot;29&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRQYW6/btsFuIMr9N8/a0uahsrpoHRJrjjQ71s3g0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRQYW6/btsFuIMr9N8/a0uahsrpoHRJrjjQ71s3g0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRQYW6/btsFuIMr9N8/a0uahsrpoHRJrjjQ71s3g0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRQYW6%2FbtsFuIMr9N8%2Fa0uahsrpoHRJrjjQ71s3g0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;454&quot; height=&quot;54&quot; data-origin-width=&quot;244&quot; data-origin-height=&quot;29&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. node version update&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nvm을 설치하면 node도 자동으로 설치되어 버전 확인이 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;147&quot; data-origin-height=&quot;30&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edjib9/btsFwBfdkwn/kHR2EHKPLqXLPirD8RWz31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edjib9/btsFwBfdkwn/kHR2EHKPLqXLPirD8RWz31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edjib9/btsFwBfdkwn/kHR2EHKPLqXLPirD8RWz31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fedjib9%2FbtsFwBfdkwn%2FkHR2EHKPLqXLPirD8RWz31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;52&quot; data-origin-width=&quot;147&quot; data-origin-height=&quot;30&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치되어있는 node version을 조회하는 커맨드는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1709615865093&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm ls&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;247&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8vbNh/btsFyNzvzcT/HVRMs3m0uvhakKweAVKGn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8vbNh/btsFyNzvzcT/HVRMs3m0uvhakKweAVKGn1/img.png&quot; data-alt=&quot;18.19.1을 설치해 사용하고 있던 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8vbNh/btsFyNzvzcT/HVRMs3m0uvhakKweAVKGn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8vbNh%2FbtsFyNzvzcT%2FHVRMs3m0uvhakKweAVKGn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;247&quot; height=&quot;284&quot; data-origin-width=&quot;247&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;18.19.1을 설치해 사용하고 있던 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가능한 node version 목록은 아래 커맨드로 확인할 수 있다. (v0.1.14부터 조회됨)&lt;/p&gt;
&lt;pre id=&quot;code_1709615572549&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm ls-remote&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lUZr4/btsFyghzqwU/KKX1FMnkChvcla89jKGEwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lUZr4/btsFyghzqwU/KKX1FMnkChvcla89jKGEwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lUZr4/btsFyghzqwU/KKX1FMnkChvcla89jKGEwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlUZr4%2FbtsFyghzqwU%2FKKX1FMnkChvcla89jKGEwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;253&quot; height=&quot;646&quot; data-origin-width=&quot;253&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 원하는 버전을 선택해 다음 커맨드 중 하나로 설치할 수 있다. 이미 깔려있는 node v18.19.1을 예시로 사용해보겠다.&lt;/p&gt;
&lt;pre id=&quot;code_1709616032174&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm install Hydrogen
nvm install v18.19.1
nvm install 18.19.1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;241&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VIvD1/btsFsbBCIlq/kj8VcLVwVk1TQFkcbA6AWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VIvD1/btsFsbBCIlq/kj8VcLVwVk1TQFkcbA6AWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VIvD1/btsFsbBCIlq/kj8VcLVwVk1TQFkcbA6AWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVIvD1%2FbtsFsbBCIlq%2Fkj8VcLVwVk1TQFkcbA6AWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;351&quot; height=&quot;131&quot; data-origin-width=&quot;241&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 node -v로 node version이 업데이트 됐는지 확인해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;137&quot; data-origin-height=&quot;28&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhsW6R/btsFzfP3C1b/zaZKTyh9rXVKCC4qs5yx2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhsW6R/btsFzfP3C1b/zaZKTyh9rXVKCC4qs5yx2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhsW6R/btsFzfP3C1b/zaZKTyh9rXVKCC4qs5yx2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhsW6R%2FbtsFzfP3C1b%2FzaZKTyh9rXVKCC4qs5yx2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;235&quot; height=&quot;48&quot; data-origin-width=&quot;137&quot; data-origin-height=&quot;28&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 설치해두었던 다른 버전으로 변경하고 싶으면 다음 커맨드를 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정 버전 사용&lt;/p&gt;
&lt;pre id=&quot;code_1709616291879&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm use 18.19.1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기본으로 설정된 버전 사용&lt;/p&gt;
&lt;pre id=&quot;code_1709616316032&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm use node&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. node version 유지하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용중이던 터미널이 종료되면 이후 새로운 터미널을 시작했을 때 노드 버전이 다시 기본 설정 버전으로 돌아가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 커맨드를 통해 기본 노드 버전을 바꿔주면 터미널 종료 후 새로운 터미널에서도 기본으로 설정해둔 버전을 추가 설정 없이 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1709616401156&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nvm alias default v18.19.1&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5xpOJ/btsFscgfgzh/7ji6BEaPIyG5ZJJStPT0O1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5xpOJ/btsFscgfgzh/7ji6BEaPIyG5ZJJStPT0O1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5xpOJ/btsFscgfgzh/7ji6BEaPIyG5ZJJStPT0O1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5xpOJ%2FbtsFscgfgzh%2F7ji6BEaPIyG5ZJJStPT0O1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;164&quot; data-origin-width=&quot;261&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/116</guid>
      <comments>https://coding-maggot.tistory.com/116#entry116comment</comments>
      <pubDate>Tue, 5 Mar 2024 14:34:36 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] 대표적으로 사용하는 암호화 알고리즘 (feat. CryptoJS)</title>
      <link>https://coding-maggot.tistory.com/115</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;CryptoJS: Javascript 기반의 암/복호화가 가능한 여러 알고리즘을 간편하게 제공하는 라이브러리&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화 방식은 크게 양방향, 단방향 암호화로 나눌 수 있다.&lt;br /&gt;이 두 방식의 차이점은 암호문을 복호화해 원문을 알아낼 수 있는지 여부이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;crypto-js가 제공하는 암호화 방식에는 ⑴ 대칭키, ⑵ 비대칭키, ⑶ 해싱(hashing)이 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;양방향&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;암호화된 암호문을 복호화할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 대칭키(symmetric encryption)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 암/복호화 시 같은 키값을 이용한다.&lt;br /&gt;ex) DES, 3-DES, AES(128bit, 256bit), SEED, ARIA&lt;br /&gt;현재 가장 보편적인 암호화 방식은 현 미국 표준방식인 aes다(DES는 너무 오래돼서 취약점이 발견됨).&lt;br /&gt;128~256 비트 키를 적용할 수 있어 보안성이 뛰어나고, 공개 알고리즘이라 누구나 사용할 수 있다.&lt;br /&gt;단, 송신 측에서 수신 측에 암호키를 전달하는 '키 배송 과정'에서 키를 탈취하면 아무리 뛰어난 암호화 알고리즘을 사용했더라도 평문이 털리게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 비대칭키(asymmetric encryption)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 암/복호화 시 다른 키값을 이용한다. A로 암호화한 암호문을 B로만 복호화할 수 있는 식이다.&lt;br /&gt;ex) RSA, ECC, DSS, Rabin, ElGamal&lt;br /&gt;문제점:&amp;nbsp;암/복호화가&amp;nbsp;대칭형&amp;nbsp;암호에&amp;nbsp;비해&amp;nbsp;현저리&amp;nbsp;느리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 비대칭형 암호를 이용해 대칭형 암호의 키를 배송하고, 실제 암호문은 대칭형 암호를 사용하는 식으로 상호보완적으로 이용하는 것이 일반적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;단방향&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;암호화된 암호문은 절대 복호화가 불가능하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3.&amp;nbsp;hashing:&amp;nbsp;&lt;/b&gt;암호화는 가능하지만 복호화는 불가능하다. 비밀번호 등에 이용한다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 170px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;hash&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;year&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;coll.res.&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;size(bits)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.783%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;design&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;broken?&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 68px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 68px; text-align: center;&quot;&gt;&lt;b&gt;MD4&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA-0(SHA)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;MD5&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA-1&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 68px; text-align: center;&quot;&gt;1990&lt;br /&gt;1993&lt;br /&gt;1993&lt;br /&gt;1995&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 68px; text-align: center;&quot;&gt;64&lt;br /&gt;80&lt;br /&gt;64&lt;br /&gt;80&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 68px; text-align: center;&quot;&gt;128&lt;br /&gt;160&lt;br /&gt;128&lt;br /&gt;160&lt;/td&gt;
&lt;td style=&quot;width: 16.783%; height: 68px; text-align: center;&quot;&gt;32-bit ARX DM&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 68px; text-align: center;&quot;&gt;1995&lt;br /&gt;1997&lt;br /&gt;2004&lt;br /&gt;2005&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 51px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 51px; text-align: center;&quot;&gt;&lt;b&gt;SHA-256 (SHA-2)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA-384 (SHA-2)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA-512 (SHA-2)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 51px; text-align: center;&quot;&gt;2002&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 51px; text-align: center;&quot;&gt;128&lt;br /&gt;192&lt;br /&gt;256&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 51px; text-align: center;&quot;&gt;256&lt;br /&gt;384&lt;br /&gt;512&lt;/td&gt;
&lt;td style=&quot;width: 16.783%; height: 51px; text-align: center;&quot;&gt;32-bit ARX DM&lt;br /&gt;64-bit ARX DM&lt;br /&gt;64-bit ARX DM&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 51px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;SHA-224 (SHA-2)&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA-512/224&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA-512/256&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;2008&lt;br /&gt;2012&lt;br /&gt;2012&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;112&lt;br /&gt;112&lt;br /&gt;128&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 17px; text-align: center;&quot;&gt;224&lt;br /&gt;224&lt;br /&gt;256&lt;/td&gt;
&lt;td style=&quot;width: 16.783%; height: 17px; text-align: center;&quot;&gt;32-bit ARX DM&lt;br /&gt;64-bit ARX DM&lt;br /&gt;64-bit ARX DM&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;SHA3-224&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA3-256&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA3-384&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHA3-512&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHAKE128&lt;/b&gt;&lt;br /&gt;&lt;b&gt;SHAKE256&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;2013&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;112&lt;br /&gt;128&lt;br /&gt;192&lt;br /&gt;256&lt;br /&gt;&amp;le;128&lt;br /&gt;&amp;le;256&lt;/td&gt;
&lt;td style=&quot;width: 16.5504%; height: 17px; text-align: center;&quot;&gt;224&lt;br /&gt;256&lt;br /&gt;384&lt;br /&gt;512&lt;br /&gt;any&lt;br /&gt;any&lt;/td&gt;
&lt;td style=&quot;width: 16.783%; height: 17px; text-align: center;&quot;&gt;64-bit Keccak sponge&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;그 외: pbkdf2, bcrypt, scrypt, &lt;span&gt;hmac&lt;/span&gt;&amp;nbsp;등&lt;br /&gt;md4, md5, sha-0, sha-1은 이미 보안성을 잃은 알고리즘으로, 단시간 내에 충돌값을 찾아낼 수 있다(비둘기 집의 원리).&lt;br /&gt;그렇기에 현재는 sha-256 이상, 가능하면 sha-3을 쓰는것이 좋다. sha-2도 sha-1을 변형한 함수이기 때문에 공격당할 가능성이 있기 때문에 안전하다고 보기는 어렵기는 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, sha-2는 속도가 워낙 빨라 초당 대략 6억번 수행이 가능하다. 이 때문에 무차별대입공격(Brute Force)과 각 평문에 대한 해시값이 알려진 Rainbow Table에 의해 어느정도 공략이 가능하다. 완벽한 공략까지는 약 137억년의 시간이 걸린다고 하니 복잡한 암호를 사용하면 위험도가 낮겠지만, 보안이 완벽하다고 보긴 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sha-3은 sha-2와 디자인이 완전히 다르기에 비교적 호평을 받고 있다.&lt;br /&gt;그러나 sha-3은 그 당시 정치적인 이유로 128bit, 256bit 등을 맞추는 등 과도하게 설계되어서 필요 이상의 비용이 들기 때문에, shake128과 256을 쓰길 추천하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** CryptoJS에서는 아직 SHA3 까지만 제공하고 있는 상태이며, SHAKE128과 256은 아직 구현 중에 있는 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** CryptoJS.SHA3의 기본값은 512bits 며, 224, 256, 384, 512 중 하나의 해시 길이를 설정해 출력할 수 있도록 구현되어 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수는 양방향 암호화와 달리 복호화가 가능한 키가 배송 중 탈취당할 확률은 없다.&lt;br /&gt;&lt;span&gt;하지만 입력된 값이 같으면 언제나 같은 결과를 나타내기 때문에,&lt;br /&gt;&lt;/span&gt;&lt;span&gt;무차별 대입공격을 기반으로 원문과 매치되는 해시값의 Rainbow Table을 만들어 공격이 성공하거나&lt;br /&gt;비둘기 집의 원리처럼 수많은 경우의 수를 일정 bit에 몰아넣다보면 언젠가는 충돌이 발견될 가능성이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;또한 아직 지구상의 계산값(현속도로는 다 공략하는데 137억광년이 걸린다고...)으로는 SHA-256을 사용해도 크게 상관이 없다며 사용을 권장하지만, 기술의 발전으로 계산속도가 더 빨라지면 공략될 가능성이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;암호학적 해시 함수의 단점을 보완하는 방법&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 키 스트레칭(key stretching)&lt;/b&gt;&lt;br /&gt;해시 암호화를 여러번 반복해서 무차별 대입공격을 방지할 수 있다.&lt;br /&gt;이 때 반복 횟수는 암호화 시 키를 생성하는 비용을 증가시켜 공격의 난이도를 높인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 솔팅(salting)&lt;/b&gt;&lt;br /&gt;실제 암호의 앞이나 뒤에 솔트된 데이터와 원본 패스워드를 넣어 해시값을 만든다. rainbow table 공격을 방지할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 사용한 강력한 해시 암호화 알고리즘들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. pbkdf2&lt;/b&gt; - crypto-js 에서도 제공&lt;/p&gt;
&lt;pre id=&quot;code_1671454585906&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import CryptoJS from &quot;crypto-js&quot;;

const salt = CryptoJS.lib.WordArray.random(128 / 8);
const key128Bits = CryptoJS.PBKDF2(&quot;Secret Passphrase&quot;, salt, {keySize: 128 / 32});
const key256Bits = CryptoJS.PBKDF2(&quot;Secret Passphrase&quot;, salt, {keySize: 256 / 32});
const key512Bits = CryptoJS.PBKDF2(&quot;Secret Passphrase&quot;, salt, {keySize: 512 / 32});
const key512Bits1000Iterations = CryptoJS.PBKDF2(&quot;Secret Passphrase&quot;, salt, {
  keySize: 512 / 32,
  iterations: 1000
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 함수의 컨테이너 역할을 한다. &lt;br /&gt;salt 적용 후 키 스트레칭 횟수의 지정이 가능하다. 가볍고 구현하기 쉬워 가장 많이 사용되는 함수 중 하나다. &lt;br /&gt;NIST(미국표준기술)에서 승인된 알고리즘이며, 미국 정부 시스템에서도 사용중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. bcrypt &lt;/b&gt;- bcryptjs로 제공&lt;/p&gt;
&lt;pre id=&quot;code_1671454840973&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import bcrypt from 'bcryptjs';

const bcryptHash = bcrypt.hashSync(pwd, bcrypt.genSaltSync(10));
bcrypt.compareSync(inputText, bcryptHash) 	// true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패스워드 저장을 목적으로 만들어졌다. 아직까지 가장 강력한 해시 메커니즘으로 알려져있다.&lt;br /&gt;사용법도 쉽고 hash값과 원문이 매칭되는지 확인하는 함수를 제공해 사용성이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. scrypt&lt;/b&gt; - scrypt-js로 제공&lt;/p&gt;
&lt;pre id=&quot;code_1671454855497&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import scrypt from 'scrypt-js';

const password = new buffer.SlowBuffer(&quot;anyPassword&quot;.normalize('NFKC'));
const salt = new buffer.SlowBuffer(&quot;someSalt&quot;.normalize('NFKC'));
const N = 1024, r = 8, p = 1, dkLen = 32;

// 암호화
const keyPromise = scrypt.scrypt(password, salt, N, r, p, dkLen, updateInterface);
// 매칭 여부 확인
const key = scrypt.syncScrypt(password, salt, N, r, p, dkLen);&lt;/code&gt;&lt;/pre&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1671513573641&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import scrypt from 'scrypt-js';

const N = 1024, r = 8, p = 1, dkLen = 32;
const scryptPwd = scrypt(
    Buffer.from(inputText), 
    Buffer.from(JSON.parse(salt.toString())),
    N, r, p, dkLen
);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 강력하지만 많은 메모리와 CPU를 요구하며, OpenSSL 1.1이상 제공 시스템에서만 작동한다. &lt;br /&gt;여러 언어 라이브러리로 제공되고 있다.&lt;br /&gt;promise를 사용해 scrypt pbkdf를 비동기적으로 계산한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 사용해보니 password와 salt 에 ArrayLike&amp;lt;number&amp;gt;가 전달되어야 했다. 이 부분은 추후에 좀 더 알아보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** 여러 해시함수를 제공하는 CryptoJS를 사용하는 것도 좋지만, bscrypt나 scrypt를 사용하는 것도 괜찮을 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;** 아직 scrypt는 실행해보지 못했다. buffer에 대해 좀 더 공부하고 다시 시도해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HMAC 예제: &lt;a href=&quot;https://defineall.tistory.com/701&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://defineall.tistory.com/701&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고글&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://k0102575.github.io/articles/2020-03/hash&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://k0102575.github.io/articles/2020-03/hash&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jusungpark.tistory.com/34&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jusungpark.tistory.com/34&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://crypto.stackexchange.com/questions/68307/what-is-the-difference-between-sha-3-and-sha-256&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://crypto.stackexchange.com/questions/68307/what-is-the-difference-between-sha-3-and-sha-256&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nukw0n-dev.tistory.com/12&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nukw0n-dev.tistory.com/12&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-bcrypt-%EB%AA%A8%EB%93%88-%EC%9B%90%EB%A6%AC-%EC%82%AC%EC%9A%A9%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-bcrypt-%EB%AA%A8%EB%93%88-%EC%9B%90%EB%A6%AC-%EC%82%AC%EC%9A%A9%EB%B2%95&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cryptojs docs : &lt;a href=&quot;https://cryptojs.gitbook.io/docs/#pbkdf2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://cryptojs.gitbook.io/docs/#pbkdf2&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bcryptjs npm : &lt;a href=&quot;https://www.npmjs.com/package/bcryptjs/v/2.4.3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.npmjs.com/package/bcryptjs/v/2.4.3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scryptjs npm : &lt;a href=&quot;https://www.npmjs.com/package/scrypt-js&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.npmjs.com/package/scrypt-js&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;scrypt 예제: &lt;a href=&quot;https://javascript.hotexamples.com/examples/scrypt/js/-/javascript-js-class-examples.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://javascript.hotexamples.com/examples/scrypt/js/-/javascript-js-class-examples.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/115</guid>
      <comments>https://coding-maggot.tistory.com/115#entry115comment</comments>
      <pubDate>Tue, 20 Dec 2022 11:25:50 +0900</pubDate>
    </item>
    <item>
      <title>[Solana Testnet] Validator 실행 시 주요 파일 &amp;amp; 커맨드</title>
      <link>https://coding-maggot.tistory.com/114</link>
      <description>&lt;p data-renderer-start-pos=&quot;1&quot; data-ke-size=&quot;size16&quot;&gt;Solana Validator를 돌리면서 구성했던 파일들을 백업차원으로 적어두려 한다.&lt;br /&gt;현재는 안 돌아가고 있지만 그 때는 돌아갔으니, 공식 공지를 숙지하고 디스코드 커뮤니티에서 질문을 통해 trouble shooting 하면 다시 돌릴 수 있을 것이다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;validator-실행-방법&quot; data-renderer-start-pos=&quot;1&quot; data-ke-size=&quot;size23&quot;&gt;validator 실행 방법&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-renderer-start-pos=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;아래 실행 파일들과 시스템 파일들을 작성하고 시스템 파일을 구동하면 백그라운드에서 계속 돌아간다.&lt;/p&gt;
&lt;p data-renderer-start-pos=&quot;18&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;시스템-구동-command&quot; data-renderer-start-pos=&quot;73&quot; data-ke-size=&quot;size20&quot;&gt;시스템 구동 command&lt;/h4&gt;
&lt;pre id=&quot;code_1663567190189&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 서버 재부팅 시 자동 시작
sudo systemctl enable --now systuner.service &amp;amp;&amp;amp; sudo systemctl enable --now validator.service \
  &amp;amp;&amp;amp; sudo systemctl enable --now watchtower.service
  
// 시스템 데몬 종료
sudo systemctl stop validator.service

// 시스템 정상 작동 확인
systemctl status validator.service&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;validator-모니터링-관련-command&quot; data-renderer-start-pos=&quot;364&quot; data-ke-size=&quot;size20&quot;&gt;validator 모니터링 관련 command&lt;/h4&gt;
&lt;pre id=&quot;code_1663567231684&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 밸리데이터 동작여부 확인
solana-validator --ledger ~/ledger monitor

// 슬롯 모니터링
solana catchup ~/validator-keypair.json --our-localhost

// 밸리데이터 현 상태 확인
solana validators | grep &amp;lt;validator address&amp;gt;

// 투표활동 확인
solana vote-account ~/vote-account-keypair.json

// 현재 슬롯 확인
curl http://localhost:8899 -X POST -H &quot;Content-Type: application/json&quot; -d '
  {&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1, &quot;method&quot;:&quot;getSlot&quot;}
'
// 에러, 리더슬롯배정 확인
grep --ignore-case --extended-regexp -w 'ERROR' ~/log/validator.log
grep --ignore-case --extended-regexp -w 'My next leader' ~/log/validator.log

// 스테이킹 계정 상태 조회
solana stake-account ~/validator-stake-keypair.json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;/home/sol-실행-파일&quot; data-renderer-start-pos=&quot;1038&quot; data-ke-size=&quot;size20&quot;&gt;/home/sol 실행 파일&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;start-validator.sh&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567309138&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
exec solana-validator \
    --entrypoint entrypoint.testnet.solana.com:8001 \
    --entrypoint entrypoint2.testnet.solana.com:8001 \
    --entrypoint entrypoint3.testnet.solana.com:8001 \
    --known-validator 5D1fNXzvv5NjV1ysLjirC4WY92RNsVH18vjmcszZd8on \
    --known-validator dDzy5SR3AXdYWVqbDEkVFdvSPCtS9ihF5kJkHCtXoFs \
    --known-validator Ft5fbkqNa76vnsjYNwjDZUXoTWpP7VYm3mtsaQckQADN \
    --known-validator eoKpUABi59aT4rR9HGS3LcMecfut9x7zJyodWWP43YQ \
    --known-validator 9QxCLckBiJc783jnMvXZubK4wH86Eqqvashtrwvcsgkv \
    --known-validator eoKpUABi59aT4rR9HGS3LcMecfut9x7zJyodWWP43YQ \
    --known-validator 82k4RGZAJxtXvW3hzgmHB2q4oDHzgwMR2cGXup324gsJ \
    --known-validator Bszp6hDL19ymPZ8efp9venQYb4ae2rRmEtVp4aG6k8nx \
    --known-validator 376e8QLx9qSkjFn7mK2kp3wBwvziKuMqiB3iAbK5Payx \
    --known-validator 8Apz17FY7vts5PUEP28apzqQBVgg6McbetFJqb45ew8F \
    --expected-genesis-hash 4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY \
    --dynamic-port-range 8000-8020 \
    --rpc-port 8899 \
    --only-known-rpc \
    --wal-recovery-mode skip_any_corrupted_record \
    --identity ~/validator-keypair.json \
    --vote-account ~/vote-account-keypair.json \
    --log ~/log/validator.log \
    --accounts /mnt/ramdisk/solana-accounts \
    --ledger ~/ledger \
    --limit-ledger-size 50000000 \
    --private-rpc \
    --no-port-check \
    --incremental-snapshots \
    --incremental-snapshot-interval-slots 200 \
    --minimal-snapshot-download-speed 1 \
    --maximum-local-snapshot-age 3000 \
    --full-rpc-api&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;known-validator는 신뢰할 수 있는 밸리데이터 목록. 테스트넷 재부팅할 때 추가한 밸리데이터들은 지워야할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;watchtower.sh&lt;br /&gt;validator 정상 작동 여부를 슬랙으로 5분마다 보내는 실행 파일.&lt;br /&gt;validator가 꺼져있으면 꺼져있다고 보내고, 켜져있으면 watchtower가 에러를 슬랙으로 보내게끔 구성했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567356100&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
while [ true ]; do
        if [ ! `ps -ef | grep solana-watchtower | grep -v grep | awk '{print $2}'` ]; then
                # watchtower 꺼져있고 validator 켜져있으면 watchtower 켜고 슬랙 보내기
                if [ `ps -ef | grep solana-validator | grep -v grep | awk '{print $2}'` ]; then
                        nohup solana-watchtower \
                                --validator-identity E6ALR99bKvV45JiwKJtgCyDe7EZdAfYPhWaSd3Lw4d2c \
                                &amp;gt;&amp;gt; /home/sol/watchtower.log &amp;amp;
                        message=&quot;watchtower가 켜졌습니다.&quot;
                        curl -X POST --data-urlencode &quot;payload={\&quot;channel\&quot;: \&quot;#testnet-validator\&quot;, \&quot;username\&quot;: \&quot;Watchtower\&quot;, \&quot;text\&quot;: \&quot;${message}\&quot;, \&quot;icon_emoji\&quot;: \&quot;:tokyo_tower:\&quot;}&quot; https://hooks.slack.com/services/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
                # watchtower 꺼져있고 validator 꺼져있으면 밸리데이터 꺼져있다고 5분마다 슬랙 보내기
                else
                    message=&quot;validator가 꺼져있습니다. validator를 켜주세요.&quot;
                        curl -X POST --data-urlencode &quot;payload={\&quot;channel\&quot;: \&quot;#testnet-validator\&quot;, \&quot;username\&quot;: \&quot;Validator_is_Off\&quot;, \&quot;text\&quot;: \&quot;${message}\&quot;, \&quot;icon_emoji\&quot;: \&quot;:internet-problems:\&quot;}&quot; https://hooks.slack.com/services/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
                    sleep 300
                fi
        elif [ `ps -ef | grep solana-watchtower | grep -v grep | awk '{print $2}'` ]; then
                # watchtower 켜져있고 validator 꺼져있으면 watchtower 끄고 watchtower 껐다고 슬랙 보내기
                if [ ! `ps -ef | grep solana-validator | grep -v grep | awk '{print $2}'` ]; then
                        kill `ps -ef | grep solana-watchtower | grep -v grep | awk '{print $2}'`
                        message=&quot;watchtower가 꺼졌습니다.&quot;
                        curl -X POST --data-urlencode &quot;payload={\&quot;channel\&quot;: \&quot;#testnet-validator\&quot;, \&quot;username\&quot;: \&quot;Watchtower\&quot;, \&quot;text\&quot;: \&quot;${message}\&quot;, \&quot;icon_emoji\&quot;: \&quot;:tokyo_tower:\&quot;}&quot; https://hooks.slack.com/services/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
                fi
        fi
done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;airdrop.sh&lt;br /&gt;테스트넷이라 필요할 때마다 에어드랍 100번을 돌리는 코드를 만들어두었다. 여타 테스트넷이 그렇듯이 에어드랍량 제한이 있어 100번을 한번에 전부 받아오진 못하고 중간부터 실패 처리 되더라.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567556396&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
for i in $(seq 1 100)
do
        solana airdrop 1 -k ~/validator-stake-keypair.json
        sleep 30
done&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;/etc/systemd/system-실행-파일&quot; data-renderer-start-pos=&quot;5078&quot; data-ke-size=&quot;size20&quot;&gt;/etc/systemd/system 시스템 파일&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;systuner.service&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567624980&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Unit]
Description=Solana System Tuner
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=1
LogRateLimitIntervalSec=0
ExecStart=/home/solana/.local/share/solana/install/active_release/bin/solana-sys-tuner --user solana

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;validator.service&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567847557&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Unit]
Description=Solana Validator
After=network.target
Wants=systuner.service
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=1
LimitNOFILE=1000000
LogRateLimitIntervalSec=0
User=sol
Environment=PATH=/bin:/usr/bin:/home/solana/.local/share/solana/install/active_release/bin
Environment=SOLANA_METRICS_CONFIG=host=https://metrics.solana.com:8086,db=tds,u=testnet_write,p=c4fa841aa918bf8274e3e2a44d77568d9861b3ea
ExecStart=/home/solana/start-validator.sh

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;watchtower.service&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567957174&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[Unit]
Description=Solana Watchtower

[Service]
Type=simple
User=sol
Environment=PATH=/bin:/usr/bin:/home/solana/.local/share/solana/install/active_release/bin
Environment=SOLANA_METRICS_CONFIG=host=https://metrics.solana.com:8086,db=tds,u=testnet_write,p=c4fa841aa918bf8274e3e2a44d77568d9861b3ea
Environment=SLACK_WEBHOOK=https://hooks.slack.com/services/&amp;lt;슬랙 웹훅&amp;gt;
ExecStart=/home/solana/watchtower.sh

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;/etc/logrotate.d-시스템&quot; data-renderer-start-pos=&quot;6448&quot; data-ke-size=&quot;size20&quot;&gt;/etc/logrotate.d 시스템 파일&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;solana&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #172b4d;&quot;&gt;로그 파일이 하루에 하나씩 생기고, 일주일 지난 파일은 없어지게 하는 코드다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1663567984267&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/home/solana/log/validator.log {
  su sol sol
  daily
  rotate 7
  missingok
  postrotate
    systemctl kill -s USR1 validator.service
  endscript
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적용 command&lt;/p&gt;
&lt;pre id=&quot;code_1663568030949&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo systemctl restart logrotate&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Solana/Validator - 실행 (devnet &amp;amp; testnet)</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/114</guid>
      <comments>https://coding-maggot.tistory.com/114#entry114comment</comments>
      <pubDate>Mon, 19 Sep 2022 15:14:14 +0900</pubDate>
    </item>
    <item>
      <title>[Github] Mac OS에서 Github에 프로젝트 올리기</title>
      <link>https://coding-maggot.tistory.com/113</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;진행했던 프로젝트의 백업 용도로 깃허브에 올리려는데, 필요한 명령어들을 순서에 맞게 쳐야하는 부분이 좀 있었어서 정리할 겸 올려본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 백업하려는 폴더 위치에서 터미널을 열어 Git 설치여부 확인&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;git --version&lt;/code&gt;을 입력했을 때 깔려있다면 다음과 같이 뜰 것이다. 사실 Mac OS는 기본적으로 가장 낮은 버전의 깃이 깔려있다고 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBDCrw/btrK4Ufwzq0/EO4bGAg25YUE4DwyxwdOzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBDCrw/btrK4Ufwzq0/EO4bGAg25YUE4DwyxwdOzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBDCrw/btrK4Ufwzq0/EO4bGAg25YUE4DwyxwdOzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBDCrw%2FbtrK4Ufwzq0%2FEO4bGAg25YUE4DwyxwdOzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;349&quot; height=&quot;28&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;40&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 깃허브에서 프로젝트를 올릴 레포지토리 생성&lt;/b&gt;&lt;/h4&gt;
&lt;figure id=&quot;og_1661926856423&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub: Where the world builds software&quot; data-og-description=&quot;GitHub is where over 83 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and feat...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;http://www.github.com&quot; data-og-url=&quot;https://github.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/MdezN/hyPEIf7JVH/wzqac1l99yaL8RyGi3x4nK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/0L5T3/hyPC90Irsl/CIji7mKsYk3VfwDjKW6MjK/img.png?width=2496&amp;amp;height=1480&amp;amp;face=0_0_2496_1480,https://scrap.kakaocdn.net/dn/ebjBUU/hyPC72S1EQ/BCvwmJCYT1KLqCGKN1xdk0/img.jpg?width=1238&amp;amp;height=1404&amp;amp;face=0_0_1238_1404&quot;&gt;&lt;a href=&quot;http://www.github.com&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://www.github.com&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/MdezN/hyPEIf7JVH/wzqac1l99yaL8RyGi3x4nK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/0L5T3/hyPC90Irsl/CIji7mKsYk3VfwDjKW6MjK/img.png?width=2496&amp;amp;height=1480&amp;amp;face=0_0_2496_1480,https://scrap.kakaocdn.net/dn/ebjBUU/hyPC72S1EQ/BCvwmJCYT1KLqCGKN1xdk0/img.jpg?width=1238&amp;amp;height=1404&amp;amp;face=0_0_1238_1404');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub: Where the world builds software&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;GitHub is where over 83 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and feat...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브에서 로그인 후, 오른쪽 상단의 레포지토리를 들어가 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lfvHD/btrKZd2BN2l/Ukjs1vxebYHhqU9g5Iprxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lfvHD/btrKZd2BN2l/Ukjs1vxebYHhqU9g5Iprxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lfvHD/btrKZd2BN2l/Ukjs1vxebYHhqU9g5Iprxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlfvHD%2FbtrKZd2BN2l%2FUkjs1vxebYHhqU9g5Iprxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;268&quot; height=&quot;287&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JMxOd/btrK4T8PkBa/rTpowXefX9au7bmZiKaAA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JMxOd/btrK4T8PkBa/rTpowXefX9au7bmZiKaAA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JMxOd/btrK4T8PkBa/rTpowXefX9au7bmZiKaAA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJMxOd%2FbtrK4T8PkBa%2FrTpowXefX9au7bmZiKaAA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;293&quot; height=&quot;138&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;1387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nj5x8/btrK2mjCRG2/vn8ZUAxT3pzN5dFP2sxnTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nj5x8/btrK2mjCRG2/vn8ZUAxT3pzN5dFP2sxnTK/img.png&quot; data-alt=&quot;나는 비공개 할거라 private으로 했다. README는 필요 시 추가하면 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nj5x8/btrK2mjCRG2/vn8ZUAxT3pzN5dFP2sxnTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNj5x8%2FbtrK2mjCRG2%2Fvn8ZUAxT3pzN5dFP2sxnTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;582&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;1387&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;나는 비공개 할거라 private으로 했다. README는 필요 시 추가하면 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 깃 초기설정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 저장소에 올릴 때마다 정보를 입력하기 싫다면, 깃허브 계정을 설정해주는 것이 좋다. 터미널에서 다음을 입력하자.&lt;/p&gt;
&lt;pre class=&quot;verilog&quot;&gt;&lt;code&gt;git config --global user.name &quot;yourName&quot;    // 아무 이름이나 적어도 되지만, 깃허브 이름과 통일하는게 좋음
git config --global user.email &quot;yourEmail@gmail.com&quot;    // 깃허브 이메일&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 깃허브 레포지토리와 로컬저장소 연결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 깃허브의 레포지토리와 데스크탑의 저장소를 연결해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 프로젝트의 터미널 창에서 `git remote -v`를 쳐보자. 연동한 주소가 없으면 아무것도 뜨지 않고, 연동된 주소가 있을 경우 밑에 뭐가 뜰 것이다. 연동된 주소가 있다면 다른 곳에 연동할 수 없으므로 기존주소를 삭제해서 연결을 끊고 새주소를 올려야 한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;// 입력
git remote -v
// 연동된 주소가 있을 경우의 출력
origin &amp;lt;연동된 깃주소&amp;gt; (fetch)
origin &amp;lt;연동된 깃주소&amp;gt; (push)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 기존 연결을 끊으려면 &lt;code&gt;git remote remove origin&lt;/code&gt;을 입력하면 된다. &lt;code&gt;git remote -v&lt;/code&gt;를 다시 쳐서 잘 삭제됐는지 확인해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZKxD1/btrK2tb2FDB/zNgCAGmoWmIwatKlalo4rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZKxD1/btrK2tb2FDB/zNgCAGmoWmIwatKlalo4rk/img.png&quot; data-alt=&quot;삭제 완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZKxD1/btrK2tb2FDB/zNgCAGmoWmIwatKlalo4rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZKxD1%2FbtrK2tb2FDB%2FzNgCAGmoWmIwatKlalo4rk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;244&quot; height=&quot;57&quot; data-origin-width=&quot;394&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;삭제 완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결된 주소가 없으면, 깃허브에서 레포지토리 주소를 복사해서 터미널에 다음을 입력하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2215&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BsVfc/btrK4DecyPv/WuNzol0DV1rdbYevNq4CKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BsVfc/btrK4DecyPv/WuNzol0DV1rdbYevNq4CKK/img.png&quot; data-alt=&quot;우측 상자를 누르면 복사됨&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BsVfc/btrK4DecyPv/WuNzol0DV1rdbYevNq4CKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBsVfc%2FbtrK4DecyPv%2FWuNzol0DV1rdbYevNq4CKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;597&quot; height=&quot;136&quot; data-origin-width=&quot;2215&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;우측 상자를 누르면 복사됨&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;git remote add origin &amp;lt;깃 주소&amp;gt;
git remote -v&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;add&lt;/code&gt; 한 뒤 &lt;code&gt;remote -v&lt;/code&gt;를 했을 때 origin 주소가 뜬다면 잘 연결이 된 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;60&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sl6YM/btrK4C7rJCO/kV6nYoidKOtQvvRkllkU0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sl6YM/btrK4C7rJCO/kV6nYoidKOtQvvRkllkU0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sl6YM/btrK4C7rJCO/kV6nYoidKOtQvvRkllkU0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsl6YM%2FbtrK4C7rJCO%2FkV6nYoidKOtQvvRkllkU0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;453&quot; height=&quot;30&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;60&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. 깃허브 레포지토리에 프로젝트 올리기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 &lt;code&gt;git add .&lt;/code&gt;로 현재 폴더의 모든 파일을 스테이징에 1차로 등록한다.&lt;br /&gt;&lt;code&gt;git add &amp;lt;파일 및 폴더&amp;gt;&lt;/code&gt; 명령어로 파일 또는 폴더를 지정해서 올릴 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 프로젝트를 처음 생성해서 커밋내역이 없을 경우, 스테이징에 등록된 파일 및 폴더들을 &lt;code&gt;git commit -m &amp;lt;메시지&amp;gt;&lt;/code&gt;로 최초 커밋을 해줘야 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;git push origin &amp;lt;올릴 브랜치&amp;gt;&lt;/code&gt;로 소스코드를 push 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7gNnB/btrK1gKUr0P/fACnEkTdkjt538ElRtrKUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7gNnB/btrK1gKUr0P/fACnEkTdkjt538ElRtrKUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7gNnB/btrK1gKUr0P/fACnEkTdkjt538ElRtrKUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7gNnB%2FbtrK1gKUr0P%2FfACnEkTdkjt538ElRtrKUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;499&quot; height=&quot;184&quot; data-origin-width=&quot;1065&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 깃허브 레포지토리를 새로고침하면 코드가 올라가 있는 것을 확인할 수 있다. 끝!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/113</guid>
      <comments>https://coding-maggot.tistory.com/113#entry113comment</comments>
      <pubDate>Wed, 31 Aug 2022 15:23:55 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 에라토스테네스의 체 기초 문제풀이 - 1978, 1929, 6588, 4673</title>
      <link>https://coding-maggot.tistory.com/112</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1978 소수 찾기&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 수 N개&amp;nbsp;중에서&amp;nbsp;소수가 몇 개인지 찾아서 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 줄에 수의 개수 N이 주어진다. N은 100이하이다. 다음으로 N개의 수가 주어지는데 수는 1,000 이하의 자연수이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 수들 중 소수의 개수를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1000까지의 모든 숫자에 대해 소수인지를 미리 판별해놓고 입력이 들어왔을 때 소수면 카운트해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1661481476318&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define MAX 1001

int a[MAX];

int main() {
    //1은 소수가 아니므로 따로 판별
    a[1]++;
    int n, tmp, result=0;
    scanf(&quot;%d&quot;, &amp;amp;n);
    for(int i=2; i&amp;lt;MAX; i++) {
        for(int j=i+i; j&amp;lt;MAX; j+=i) {
            if(a[j]==1) continue;
            else a[j]++;
        }
    }

    for(int i=0; i&amp;lt;n; i++) {
        scanf(&quot;%d&quot;, &amp;amp;tmp);
        if(!a[tmp]) result++;
    }
    printf(&quot;%d&quot;, result);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1929 소수 구하기&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;M이상 N이하의 소수를 모두 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 자연수 M과 N이 빈 칸을 사이에 두고 주어진다. (1 &amp;le; M &amp;le; N &amp;le; 1,000,000)&amp;nbsp;M이상 N이하의 소수가 하나 이상 있는 입력만 주어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 줄에 하나씩, 증가하는 순서대로 소수를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;m, n 범위를 입력받고, n까지의 숫자에 대해 미리 소수 판별을 해놓은 후 m부터 n까지의 소수를 출력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1661483103103&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define MAX 1000001

int a[MAX];

int main() {
    a[1]=1;
    int m, n;
    scanf(&quot;%d %d&quot;, &amp;amp;m, &amp;amp;n);
    for(int i=2; i&amp;lt;=n; i++) {
        for(int j=i+i; j&amp;lt;=n; j+=i) {
            if(a[j]==1) continue;
            else a[j]=1;
        }
    }
    for(int i=m; i&amp;lt;=n; i++) {
        if(!a[i]) printf(&quot;%d\n&quot;, i);
    }


    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6588 골드바흐의 추측&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1742년, 독일의 아마추어 수학가 크리스티안 골드바흐는 레온하르트 오일러에게 다음과 같은 추측을 제안하는 편지를 보냈다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;4보다 큰 모든 짝수는 두 홀수 소수의 합으로 나타낼 수 있다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 8은 3 + 5로 나타낼 수 있고, 3과 5는 모두 홀수인 소수이다. 또, 20 = 3 + 17 = 7 + 13, 42 = 5 + 37 = 11 + 31 = 13 + 29 = 19 + 23 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 추측은 아직도 해결되지 않은 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백만 이하의 모든 짝수에 대해서, 이 추측을 검증하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;입력&lt;/h2&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력은 하나 또는 그 이상의 테스트 케이스로 이루어져 있다. 테스트 케이스의 개수는 100,000개를 넘지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 테스트 케이스는 짝수 정수 n 하나로 이루어져 있다. (6 &amp;le; n &amp;le; 1000000)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력의 마지막 줄에는 0이 하나 주어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;출력&lt;/h2&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 테스트 케이스에 대해서, n = a + b 형태로 출력한다. 이때, a와 b는 홀수 소수이다. 숫자와 연산자는 공백 하나로 구분되어져 있다. 만약, n을 만들 수 있는 방법이 여러 가지라면, b-a가 가장 큰 것을 출력한다. 또, 두 홀수 소수의 합으로 n을 나타낼 수 없는 경우에는 &quot;Goldbach's conjecture is wrong.&quot;을 출력한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 범위까지의 소수 판별을 미리 해놓고, 홀수 포문을 돌며 소수들로 주어진 수를 만들 수 있는지 확인해서 출력한다.&lt;/p&gt;
&lt;pre id=&quot;code_1661754416329&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define MAX 1000001

int a[MAX];

int main() {
    // 홀수 소수만 0을 가지고 있게
    a[1]=1, a[2]=1;
    int n;
    for(int i=2; i&amp;lt;MAX; i++) {
        for(int j=i+i; j&amp;lt;MAX; j+=i) {
            if(a[j]==1) continue;
            else a[j]=1;
        }
    }
    while(1) {
        scanf(&quot;%d&quot;, &amp;amp;n);
        if(n==0) break;
        bool find = false;
        for(int i=3; i&amp;lt;=n/2; i+=2) {
            if(a[i]==0 &amp;amp;&amp;amp; a[n-i]==0) {
                printf(&quot;%d = %d + %d\n&quot;, n, i, n-i);
                find = true;
                break;
            }
        }
        if (!find) printf(&quot;Goldbach's conjecture is wrong.\n&quot;);
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4673 셀프 넘버&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;셀프 넘버는 1949년 인도 수학자 D.R. Kaprekar가 이름 붙였다. 양의 정수 n에 대해서 d(n)을 n과 n의 각 자리수를 더하는 함수라고 정의하자. 예를 들어, d(75) = 75+7+5 = 87이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양의 정수 n이 주어졌을 때, 이 수를 시작해서 n, d(n), d(d(n)), d(d(d(n))), ...과 같은 무한 수열을 만들 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 33으로 시작한다면 다음 수는 33 + 3 + 3 = 39이고, 그 다음 수는 39 + 3 + 9 = 51, 다음 수는 51 + 5 + 1 = 57이다. 이런식으로 다음과 같은 수열을 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n을 d(n)의 생성자라고 한다. 위의 수열에서 33은 39의 생성자이고, 39는 51의 생성자, 51은 57의 생성자이다. 생성자가 한 개보다 많은 경우도 있다. 예를 들어, 101은 생성자가 2개(91과 100) 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자가 없는 숫자를 셀프 넘버라고 한다. 100보다 작은 셀프 넘버는 총 13개가 있다. 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10000보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 출력하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;입력은 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10,000보다 작거나 같은 셀프 넘버를 한 줄에 하나씩 증가하는 순서로 출력한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;내 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10000까지 생성자가 있는 숫자들을 지우고 출력한다.&lt;br /&gt;생성자로 구한 숫자가 이미 체크한 숫자일 때는 그냥 넘어가도록 if문을 걸어도 되겠지만, 이미 생성자로 숫자를 구한 후이기 때문에 배열을 확인하는 시간과 숫자를 배열에 넣는 시간이 크게 차이가 나지 않을 것 같아 따로 넘어가는 코드를 넣지 않았다.&lt;/p&gt;
&lt;pre id=&quot;code_1661756609780&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define MAX 10001

int a[MAX];

int main() {
    for (int i=1; i&amp;lt;MAX; i++) {
        int tmp=i, sum=i;
        while(tmp != 0) {
            sum += tmp%10;
            tmp /= 10;
        }
        if(sum&amp;gt;MAX) continue;
        a[sum]=1;
    }
    for(int i=1; i&amp;lt;MAX; i++) {
        if (a[i]==1) continue;
        else printf(&quot;%d\n&quot;, i);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다른사람 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성자에서 구한 숫자가 다음 생성자로 이어질 수 있도록 수열을 구성했다.&lt;br /&gt;(그런데 이중포문을 돌면서 소요시간이 좀 더 많아지는 것 같다. 이런 아이디어도 있구나 하고 넘어가려고 한다.)&lt;/p&gt;
&lt;pre id=&quot;code_1661762148976&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#define MAX 10001

using namespace std;

int a[MAX];
int d[MAX];

int getNext(int x) {
    int tmp=x, sum=x;
    while(tmp != 0) {
        sum += tmp%10;
        tmp /= 10;
    }
    return sum;
}

int main() {
    for(int i=1; i&amp;lt;MAX; i++) {
        for(int j=getNext(i); j&amp;lt;MAX; j=getNext(j)) {
            if(a[j]==1) continue;
            else a[j]=1;
        }
    }
    for(int i=1; i&amp;lt;MAX; i++) {
        if(a[i]==0) printf(&quot;%d\n&quot;, i);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>[C_C++]코딩테스트 연습/[백준] 일반 문제</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/112</guid>
      <comments>https://coding-maggot.tistory.com/112#entry112comment</comments>
      <pubDate>Mon, 29 Aug 2022 17:36:12 +0900</pubDate>
    </item>
    <item>
      <title>[그리디 문제풀기] Google Code Jam 2018 - Qualification Round (문제 B) (C/C++)</title>
      <link>https://coding-maggot.tistory.com/111</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 B: 트리플 버블 정렬(Trouble Sort)&lt;/h3&gt;
&lt;figure id=&quot;og_1661413466411&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Code Jam - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Put your coding skills to the test as you work your way through multiple rounds of algorithmic coding puzzles for the title of Code Jam Champ and 15,000 USD.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/00000000000079cb&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/00000000000079cb&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/xu5mB/hyPzlGGteL/Cr9FecaRVRsdmesRXJX1XK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/00000000000079cb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/00000000000079cb&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/xu5mB/hyPzlGGteL/Cr9FecaRVRsdmesRXJX1XK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Code Jam - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Put your coding skills to the test as you work your way through multiple rounds of algorithmic coding puzzles for the title of Code Jam Champ and 15,000 USD.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2442&quot; data-origin-height=&quot;1366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT7DMp/btrKysdQOjz/pQ9axUlm3M0Y3sy1v1nBo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT7DMp/btrKysdQOjz/pQ9axUlm3M0Y3sy1v1nBo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT7DMp/btrKysdQOjz/pQ9axUlm3M0Y3sy1v1nBo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT7DMp%2FbtrKysdQOjz%2FpQ9axUlm3M0Y3sy1v1nBo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2442&quot; height=&quot;1366&quot; data-origin-width=&quot;2442&quot; data-origin-height=&quot;1366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2420&quot; data-origin-height=&quot;1412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SIRTQ/btrKxP1i6w9/OlNdCV9qtb4qcTdbZBxmZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SIRTQ/btrKxP1i6w9/OlNdCV9qtb4qcTdbZBxmZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SIRTQ/btrKxP1i6w9/OlNdCV9qtb4qcTdbZBxmZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSIRTQ%2FbtrKxP1i6w9%2FOlNdCV9qtb4qcTdbZBxmZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2420&quot; height=&quot;1412&quot; data-origin-width=&quot;2420&quot; data-origin-height=&quot;1412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;간략한 문제 해석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 버블 정렬 알고리즘은 앞뒤의 두 원소를 비교해 크기가 더 작은 것이 앞으로 오도록 순서를 정렬하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제에서는 인접한 두 원소가 아니라, 가운데에 어떤 원소를 기준으로 양옆의 원소를 비교해 크기가 작은 것이 앞으로 오도록 정렬하는 '트러블(Triple + Bubble) 알고리즘'을 사용한다. 이 방법을 사용했을 때 주어진 배열을 정상적으로 정렬할 수 있다면 'OK'를, 없다면 처음으로 정렬이 아니게 되는 인덱스가 몇인지를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시로 5 6 8 4 3은 다음과 같이 정렬을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5 6 8 4 3&lt;br /&gt;5 &lt;b&gt;4&lt;/b&gt; 8 &lt;b&gt;6&lt;/b&gt; 3&lt;br /&gt;5 4 &lt;b&gt;3&lt;/b&gt; 6 &lt;b&gt;8&lt;/b&gt;&lt;br /&gt;&lt;b&gt;3&lt;/b&gt; 4 &lt;b&gt;5&lt;/b&gt; 6 8&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; 정상적으로 정렬됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 8 9 7을 돌리면 다음과 같이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8 9 7&lt;br /&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;7&lt;/b&gt; 9 &lt;b&gt;8&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 정렬을 다 수행했음에도 불구하고 크기에 맞게 정렬되지 않았기 때문에 정상적으로 정렬할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;틀린 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제에서 주어진 트리플 버블 정렬 코드를 넣고 정렬된 배열인 v를 차례로 돌면서 검사하면 Test Set 2에서 시간초과가 발생한다.&lt;/p&gt;
&lt;pre id=&quot;code_1661414177038&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int main() {
    int t, n, tmp, i=0;
    vector&amp;lt;int&amp;gt; v;
    scanf(&quot;%d&quot;, &amp;amp;t);
    for(int j=1; j&amp;lt;=t; j++) {
        scanf(&quot;%d&quot;, &amp;amp;n);
        v.clear();
        for(i=0; i&amp;lt;n; i++) {
            scanf(&quot;%d&quot;, &amp;amp;tmp);
            v.push_back(tmp);
        }
        // 트러블 정렬
        bool done = false;
        while(!done) {
            done = true;
            for(i=0; i&amp;lt;v.size()-2; i++) {
                if (v[i] &amp;gt; v[i+2]) {
                    done = false;
                    tmp = v[i];
                    v[i] = v[i+2];
                    v[i+2] = tmp;
                }
            }
        }
        // 정상적인 정렬인지
        for(i=0; i&amp;lt;v.size()-1; i++) {
            if(v[i] &amp;gt; v[i+1]) {
                done = false;
                break;
            }
        }
        if(done) printf(&quot;Case #%d: OK\n&quot;, j);
        else printf(&quot;Case #%d: %d\n&quot;, j, i);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elawkI/btrKAjtDBVE/jkWp17vjHzDQPX2ZfoT1j0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elawkI/btrKAjtDBVE/jkWp17vjHzDQPX2ZfoT1j0/img.png&quot; data-alt=&quot;Test set 2 에서 시간초과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elawkI/btrKAjtDBVE/jkWp17vjHzDQPX2ZfoT1j0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelawkI%2FbtrKAjtDBVE%2FjkWp17vjHzDQPX2ZfoT1j0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;497&quot; height=&quot;37&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Test set 2 에서 시간초과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;핵심 알고리즘&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 해결하기 위해서는 홀수와 짝수를 구분해 처리하면 된다. &lt;span style=&quot;color: #ee2323;&quot;&gt;홀수와 짝수는 서로 정렬에 관여할 수 없다&lt;/span&gt;는 점이 핵심이다.&lt;br /&gt;&lt;u&gt;홀수는 홀수끼리, 짝수는 짝수끼리 정렬해서 최종적으로 문자열이 오름차순 정렬을 이루고 있는지 확인&lt;/u&gt;하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도 O(N^2)의 버블 정렬이 아닌 C++ STL에서 제공하는 힙구조에 가까운 정렬을 각각 한번씩 해주면 되기 때문에 훨씬 빨라진다.&lt;/p&gt;
&lt;pre id=&quot;code_1661418938115&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

vector&amp;lt;int&amp;gt; odd;
vector&amp;lt;int&amp;gt; even;

int main() {
    int t, n, tmp;
    scanf(&quot;%d&quot;, &amp;amp;t);
    for(int i=1; i&amp;lt;=t; i++) {
        odd.clear();
        even.clear();
        printf(&quot;Case #%d: &quot;, i);
        scanf(&quot;%d&quot;, &amp;amp;n);
        for(int j=0; j&amp;lt;n; j++) {
            scanf(&quot;%d&quot;, &amp;amp;tmp);
            if(j%2 == 0) {
                odd.push_back(tmp);
            } else {
                even.push_back(tmp);
            }
        }
        sort(odd.begin(), odd.end());
        sort(even.begin(), even.end());
        int now = 0;
        bool sorted = true;
        for(int j=0; j&amp;lt;n; j++) {
            if(j%2 == 0) {  // 홀수번째일 때
                if(odd[j/2] &amp;lt; now) {    // 앞에 있는 수가 더 크면 now의 인덱스 뱉기
                    printf(&quot;%d\n&quot;, j-1);
                    sorted = false;
                    break;
                } else {    // 뒤에 있는 수가 더 크면 다음 배열 보러 넘어감
                    now = odd[j/2];
                }
            } else {    // 짝수번째일 때
                if(even[j/2] &amp;lt; now) {
                    printf(&quot;%d\n&quot;, j-1);
                    sorted = false;
                    break;
                } else {
                    now = even[j/2];
                }
            }
        }
        if(sorted) printf(&quot;OK\n&quot;);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;84&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HJHD5/btrKwUWdfli/2XhZ4Df3CqId2nFo76U2Pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HJHD5/btrKwUWdfli/2XhZ4Df3CqId2nFo76U2Pk/img.png&quot; data-alt=&quot;Test set 둘 다 통과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HJHD5/btrKwUWdfli/2XhZ4Df3CqId2nFo76U2Pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHJHD5%2FbtrKwUWdfli%2F2XhZ4Df3CqId2nFo76U2Pk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;46&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;84&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Test set 둘 다 통과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고글&lt;/p&gt;
&lt;figure id=&quot;og_1661419383348&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;37. 구글 코드 잼(Google Code Jam) 2018에서 살펴보는 기초 그리디 문제&quot; data-og-description=&quot;구글 코드 잼(Google Code Jam)은 구글이 주최하는 알고리즘 대회로 세계적으로 가장 유명한 알고리즘 ...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://blog.naver.com/ndb796/221247631646&quot; data-og-url=&quot;https://blog.naver.com/ndb796/221247631646&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eD2VuT/hyPzkHV3pk/FieSUubDqHh2vVmzaQiG50/img.png?width=743&amp;amp;height=565&amp;amp;face=0_0_743_565,https://scrap.kakaocdn.net/dn/t6n13/hyPzkOIrQV/RfrUFGFm3bxiKcd26vFUtk/img.png?width=80&amp;amp;height=82&amp;amp;face=0_0_80_82,https://scrap.kakaocdn.net/dn/vCwKT/hyPzpbnxNi/FdMQCsnkmo5tFzpSVHw2D1/img.png?width=80&amp;amp;height=61&amp;amp;face=0_0_80_61&quot;&gt;&lt;a href=&quot;https://blog.naver.com/ndb796/221247631646&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.naver.com/ndb796/221247631646&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eD2VuT/hyPzkHV3pk/FieSUubDqHh2vVmzaQiG50/img.png?width=743&amp;amp;height=565&amp;amp;face=0_0_743_565,https://scrap.kakaocdn.net/dn/t6n13/hyPzkOIrQV/RfrUFGFm3bxiKcd26vFUtk/img.png?width=80&amp;amp;height=82&amp;amp;face=0_0_80_82,https://scrap.kakaocdn.net/dn/vCwKT/hyPzpbnxNi/FdMQCsnkmo5tFzpSVHw2D1/img.png?width=80&amp;amp;height=61&amp;amp;face=0_0_80_61');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;37. 구글 코드 잼(Google Code Jam) 2018에서 살펴보는 기초 그리디 문제&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;구글 코드 잼(Google Code Jam)은 구글이 주최하는 알고리즘 대회로 세계적으로 가장 유명한 알고리즘 ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[C_C++]코딩테스트 연습/기타</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/111</guid>
      <comments>https://coding-maggot.tistory.com/111#entry111comment</comments>
      <pubDate>Thu, 25 Aug 2022 18:24:05 +0900</pubDate>
    </item>
    <item>
      <title>[C++] 프로그래머스 - 체육복 (그리디)</title>
      <link>https://coding-maggot.tistory.com/110</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;그리디의 대표 문제 중 하나인 체육복이다.&lt;/p&gt;
&lt;figure id=&quot;og_1661391631673&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42862?language=cpp&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b56YvQ/hyPzmE48Y2/amqHqmtOINXoR55R2Xlys0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/jrVDt/hyPzj9qPGt/Brj9cxWqURKrv4TvzLG1lK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42862?language=cpp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42862?language=cpp&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b56YvQ/hyPzmE48Y2/amqHqmtOINXoR55R2Xlys0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/jrVDt/hyPzj9qPGt/Brj9cxWqURKrv4TvzLG1lK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QxD5r/btrKvESCwi5/xovP049RIM7suRTVXP6hF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QxD5r/btrKvESCwi5/xovP049RIM7suRTVXP6hF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QxD5r/btrKvESCwi5/xovP049RIM7suRTVXP6hF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQxD5r%2FbtrKvESCwi5%2FxovP049RIM7suRTVXP6hF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2274&quot; height=&quot;1532&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 학생 n(2~30)명 중 체육복을 도난당한 학생들(lost)이 있다. 체육복이 없는 학생의 앞뒤 번호 중 여벌을 가져온 학생(reserve)이 있으면 체육복을 빌린다. 도난은 1개씩만 당하며, 여벌을 가져온 학생도 도난 당해서 여벌이 없어졌을 수 있다. 이렇게 빌려서 수업을 들을 수 있는 학생 수의 최대값을 반환하면 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;내 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학생수만큼 각 번호에 1을 담은 배열을 두고, 도난을 당했으면 1을 빼고 여벌을 가져왔으면 1을 더해준다.&lt;br /&gt;lost를 정렬한 다음, 도난당한 학생의 앞번호가 여벌을 가져왔으면 빌리고, 뒷번호만 가져왔으면 뒷번호에게 빌린다.&lt;br /&gt;다 빌린 다음 배열에 0이 아닌 값(1,2)이 들어있는 학생수만큼 세서 반환했다.&lt;/p&gt;
&lt;pre id=&quot;code_1661394339396&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

int stu[31];

int solution(int n, vector&amp;lt;int&amp;gt; lost, vector&amp;lt;int&amp;gt; reserve) {
    int answer=0;
    for(int i=1; i&amp;lt;=n; i++) {
        stu[i]++;
    }
    sort(lost.begin(), lost.end());
    for(int i=0; i&amp;lt;lost.size(); i++) {
        if(lost[i]) stu[lost[i]]--;
    }
    for(int i=0; i&amp;lt;reserve.size(); i++) {
        if(reserve[i]) stu[reserve[i]]++;
    }
    for(int i=0; i&amp;lt;lost.size(); i++) {
        if(!stu[lost[i]]) {
            if(stu[lost[i]-1]==2) {
                stu[lost[i]-1]--, stu[lost[i]]++;
            } else if(stu[lost[i]+1]==2) {
                stu[lost[i]+1]--, stu[lost[i]]++;
            }
        }
    }

    for(int i=1; i&amp;lt;=n; i++) {
        if(stu[i]) answer++;
    }

    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;다른 사람 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;푸는 방식은 비슷한데, 학생수만큼 배열에 1을 넣는 과정 없이 lost 번호의 배열에 -1, reserve 번호의 배열에 1을 넣었다.&lt;br /&gt;그리고 정렬 후 lost 배열을 검사했던 나와 달리, 정렬하는 과정 없이 그냥 모든 학생을 검사해 체육복을 빌리는 과정을 수행했다.&lt;/p&gt;
&lt;pre id=&quot;code_1661395079061&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;
int student[35];
int solution(int n, vector&amp;lt;int&amp;gt; lost, vector&amp;lt;int&amp;gt; reserve) {
    int answer = 0;
    for(int i : reserve) student[i] += 1;
    for(int i : lost) student[i] += -1;
    for(int i = 1; i &amp;lt;= n; i++) {
        if(student[i] == -1) {
            if(student[i-1] == 1) 
                student[i-1] = student[i] = 0;
            else if(student[i+1] == 1) 
                student[i] = student[i+1] = 0;
        }
    }
    for(int i  = 1; i &amp;lt;=n; i++)
        if(student[i] != -1) answer++;

    return answer;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>[C_C++]코딩테스트 연습/[프로그래머스] level 1</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/110</guid>
      <comments>https://coding-maggot.tistory.com/110#entry110comment</comments>
      <pubDate>Thu, 25 Aug 2022 11:40:32 +0900</pubDate>
    </item>
    <item>
      <title>[그리디 문제풀기] Google Code Jam 2018 - Qualification Round (문제 A) (C/C++)</title>
      <link>https://coding-maggot.tistory.com/109</link>
      <description>&lt;figure id=&quot;og_1661304428161&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Code Jam - Google&amp;rsquo;s Coding Competitions&quot; data-og-description=&quot;Put your coding skills to the test as you work your way through multiple rounds of algorithmic coding puzzles for the title of Code Jam Champ and 15,000 USD.&quot; data-og-host=&quot;codingcompetitions.withgoogle.com&quot; data-og-source-url=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/0000000000007966&quot; data-og-url=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/0000000000007966&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beuBK6/hyPyLlidhi/gEXZc1p8q4e2SiqD5cigkK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/0000000000007966&quot; data-source-url=&quot;https://codingcompetitions.withgoogle.com/codejam/round/00000000000000cb/0000000000007966&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beuBK6/hyPyLlidhi/gEXZc1p8q4e2SiqD5cigkK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Code Jam - Google&amp;rsquo;s Coding Competitions&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Put your coding skills to the test as you work your way through multiple rounds of algorithmic coding puzzles for the title of Code Jam Champ and 15,000 USD.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;codingcompetitions.withgoogle.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 A: 다시 우주를 구하기 (Saving The Universe Again)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr; 문제 캡처&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2426&quot; data-origin-height=&quot;1372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YdRMj/btrKrLw8CF2/xAGDXQsoSaG4ctl2zIYyDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YdRMj/btrKrLw8CF2/xAGDXQsoSaG4ctl2zIYyDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YdRMj/btrKrLw8CF2/xAGDXQsoSaG4ctl2zIYyDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYdRMj%2FbtrKrLw8CF2%2FxAGDXQsoSaG4ctl2zIYyDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2426&quot; height=&quot;1372&quot; data-origin-width=&quot;2426&quot; data-origin-height=&quot;1372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2440&quot; data-origin-height=&quot;1174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bET6ud/btrKp45lKaN/UhmRfG1uVbBqsBsrjuaRu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bET6ud/btrKp45lKaN/UhmRfG1uVbBqsBsrjuaRu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bET6ud/btrKp45lKaN/UhmRfG1uVbBqsBsrjuaRu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbET6ud%2FbtrKp45lKaN%2FUhmRfG1uVbBqsBsrjuaRu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2440&quot; height=&quot;1174&quot; data-origin-width=&quot;2440&quot; data-origin-height=&quot;1174&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;642&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/di6xa6/btrKsEEyfTA/jcbudWy4yLxkCxDknZl1m0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/di6xa6/btrKsEEyfTA/jcbudWy4yLxkCxDknZl1m0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/di6xa6/btrKsEEyfTA/jcbudWy4yLxkCxDknZl1m0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdi6xa6%2FbtrKsEEyfTA%2FjcbudWy4yLxkCxDknZl1m0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;393&quot; height=&quot;293&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;642&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;간략한 문제 해설&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공격(Shoot)과 기 모으기(Charge)가 있다고 했을 때,&lt;br /&gt;&lt;u&gt;Charge 시 데미지가 2배&lt;/u&gt;가 되어 공격력이 높아지고, Shoot 시 높아진 공격력으로 맞게 된다. 초기 데미지는 1이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 'CS'의 총 데미지는 2, 'SCCSSC'의 총 데미지는 1+4+4 = 9가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 맞는 데미지를 낮추기 위해 &lt;u&gt;인접한 C와 S를 바꿀 수 있고&lt;/u&gt;, 실드가 버틸 수 있는 한계치 D가 주어진다.&lt;br /&gt;그러므로 C와 S를 최소한으로 바꾸어서 D와 같거나 더 낮은 데미지를 만들어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력에서 한계치 D와 공격패턴이 주어지므로, 데미지를 D와 같거나 더 작게 만드는 최소한의 패턴 변경수를 출력하면 된다. &lt;br /&gt;만약 패턴을 바꿔도 그런 경우를 만들 수 없다면 'IMPOSSIBLE'을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;핵심 알고리즘&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 각 S에서의 데미지를 저장하고, &lt;span style=&quot;color: #ee2323;&quot;&gt;총 교체 가능 횟수만큼 제일 큰 숫자를 2로 나누면 된다.&lt;/span&gt;&lt;br /&gt;각 S에서 보면 왼쪽에 있는 C의 개수만큼 자리를 바꿀 수 있으므로, 총 교체 가능 횟수는 각 S의 교체 가능횟수의 합이 된다.&lt;br /&gt;총 교체 가능 횟수가 소진될 때까지 데미지를 나누고, D와 같거나 작아지는 순간에 교체한 횟수를 출력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) 6 SCCSSC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데미지&lt;br /&gt;SCCSSC&lt;br /&gt;1&amp;nbsp; &amp;nbsp; &amp;nbsp; 44&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;교체가능횟수&lt;br /&gt;SCCSSC&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 22&lt;br /&gt;(∵ 총 교체가능횟수 4)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데미지 정렬 &amp;rarr; 144&lt;br /&gt;가장 큰 숫자 2로 나누기 &amp;rarr; 1번 나누고 정렬하면 124 (총합 7) &amp;rarr; 2번 나누고 정렬하면 122 (총합 5 =&amp;gt; 2 출력 후 종료)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 적용해 코드를 짜면 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;내 코드&lt;/h4&gt;
&lt;pre id=&quot;code_1661309025614&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

int main()
{
    int t, d;
    string p;
    scanf(&quot;%d&quot;, &amp;amp;t);
    for(int i=1; i&amp;lt;=t; i++) {
        cin &amp;gt;&amp;gt; d &amp;gt;&amp;gt; p;
        int cntC = 0, counts = 0, damage = 1;
        vector&amp;lt;int&amp;gt; shoot;
        int len = p.length();
        // 각 S마다 왼쪽에 있는 C의 개수만큼 교체 가능
        for(int j=0; j&amp;lt;len; j++) {
            if (p[j]=='C') {
                damage *= 2;
                cntC++;
            } else {
                shoot.push_back(damage);
                counts += cntC;
            }
        }
        // 데미지 총합이 D와 같거나 작아질때까지
        // 교체가능횟수 소진될 때까지 shoot에 들어있는 가장 큰 damage를 2로 나누기
        int vlen = shoot.size(), sum = 0;
        for(int j=0; j&amp;lt;vlen; j++) {
            sum += shoot[j];
        }
        int changed = 0;
        while(counts-- &amp;amp;&amp;amp; sum &amp;gt; d) {
            sort(shoot.begin(), shoot.end());
            shoot[vlen-1] /= 2;
            sum -= shoot[vlen-1];
            changed++;
        }
        if (sum &amp;gt; d) printf(&quot;Case #%d: IMPOSSIBLE\n&quot;, i);
        else printf(&quot;Case #%d: %d\n&quot;, i, changed);
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;다른 사람 코드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정렬을 내림차순으로 정렬해 앞에서 꺼내썼다.&lt;/p&gt;
&lt;pre id=&quot;code_1661314960210&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;algorithm&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

vector&amp;lt;int&amp;gt; shoot;

bool compare(int a, int b) {
    return a &amp;gt; b;
}

int main() {
    int tc, t = 0;
    cin &amp;gt;&amp;gt; tc;
    while(t++ != tc) {
        cout &amp;lt;&amp;lt; &quot;Case #&quot; &amp;lt;&amp;lt; t &amp;lt;&amp;lt; &quot;: &quot;;
        int d, counts = 1, damageSum = 0, cnt = 0, damage = 1;
        string p;
        cin &amp;gt;&amp;gt; d &amp;gt;&amp;gt; p;
        shoot.clear();
        for(int i=0; i&amp;lt;p.size(); i++) {
            if(p[i] == 'C') {
                damage *= 2, cnt++;
            } else {
                counts += cnt, damageSum += damage;
                shoot.push_back(damage);
            }
        }
        bool find = false;
        int i=0;
        while(counts--) {
            if(damageSum &amp;lt;= d) {
                find = true;
                cout &amp;lt;&amp;lt; i &amp;lt;&amp;lt; '\n';
                break;
            }
            sort(shoot.begin(), shoot.end(), compare);
            damageSum -= shoot[0] / 2;
            shoot[0] /= 2;
            i++;
        }
        if(!find) cout &amp;lt;&amp;lt; &quot;IMPOSSIBLE&quot; &amp;lt;&amp;lt; '\n';
    }
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[C_C++]코딩테스트 연습/기타</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/109</guid>
      <comments>https://coding-maggot.tistory.com/109#entry109comment</comments>
      <pubDate>Thu, 25 Aug 2022 10:37:33 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 그리디 기초 문제풀이 ③ - 2437, 1783, 1969, 2812 (C/C++)</title>
      <link>https://coding-maggot.tistory.com/108</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;2437 저울&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 양팔 저울을 이용하여 물건의 무게를 측정하려고 한다. 이 저울의 양 팔의 끝에는 물건이나 추를 올려놓는 접시가 달려 있고, 양팔의 길이는 같다. 또한, 저울의 한쪽에는 저울추들만 놓을 수 있고, 다른 쪽에는 무게를 측정하려는 물건만 올려놓을 수 있다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/44Ic4/btrKdQ6eiyc/imJvwKE7W8XhVdNpJm3dK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/44Ic4/btrKdQ6eiyc/imJvwKE7W8XhVdNpJm3dK1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/44Ic4/btrKdQ6eiyc/imJvwKE7W8XhVdNpJm3dK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F44Ic4%2FbtrKdQ6eiyc%2FimJvwKE7W8XhVdNpJm3dK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;282&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;무게가 양의 정수인 N개의 저울추가 주어질 때, 이 추들을 사용하여 측정할 수 없는 양의 정수 무게 중 최솟값을 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 무게가 각각 3, 1, 6, 2, 7, 30, 1인 7개의 저울추가 주어졌을 때, 이 추들로 측정할 수 없는 양의 정수 무게 중 최솟값은 21이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 째 줄에는 저울추의 개수를 나타내는 양의 정수 N이 주어진다. N은 1 이상 1,000 이하이다. 둘째 줄에는 저울추의 무게를 나타내는 N개의 양의 정수가 빈칸을 사이에 두고 주어진다. 각 추의 무게는 1이상 1,000,000 이하이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 주어진 추들로 측정할 수 없는 양의 정수 무게 중 최솟값을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저울추들을 정렬한 뒤 하나씩 더해나가면서 빈 공간이 있는지 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 아이디어는 측정 가능한 구간이 끊기지 않아야 한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;case 1)&lt;/b&gt; [1, 7] 구간이 측정 가능한 상황에 4kg 무게의 저울추가 추가로 주어지면, [1+4, 7+4]의 구간이 측정 가능해짐. &lt;br /&gt;이는 [5, 11] 구간으로 기존의 구간과 합쳐져 [1, 11] 구간이 측정 가능해짐.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;b&gt;case 2)&lt;/b&gt; [1, 7] 구간이 측정 가능한 상황에 10kg 무게의 저울추가 추가로 주어지면, [11, 17] 구간이 추가로 측정 가능해짐.&lt;br /&gt;즉 측정 가능 구간이 끊겼으므로 측정 불가한 무게의 최소값은 8kg&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이처럼 다음 저울추의 무게가 측정 가능한 구간보다 작거나 같으면 끊기지 않고, 더 크면 끊긴다는 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정렬한 뒤 첫번째 저울추는 1이어야 하고, 두번째 저울추는 2와 같거나 작아야 한다.&lt;br /&gt;첫번째, 두번째 저울추가 둘 다 1이면 측정 가능한 구간은 1~2고, 두번째 저울추가 2면 1~3이 된다.&lt;br /&gt;그러므로 다음 검사할 저울추 무게는 첫번째 저울추 + 두번째 저울추 + 1이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 다음 저울추의 무게가 측정 가능한 구간의 최대값보다 작거나 같으면 끊기지 않고 검사가 가능하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 다음에 검사할 저울추 무게는 측정 가능한 구간 + 비교한 저울추 무게(a[i]) + 1 이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 아이디어는 측정 가능한 부분이 끊기지 위해서, 그 앞에서 측정 가능한 부분이 끊기지 않았다는 가정 하에&lt;br /&gt;'다음 저울추의 무게'가 '측정가능한 구간 + 1'보다 작거나 같아야 한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661060725361&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;algorithm&amp;gt;

using namespace std;

int a[1001];
int n, target = 1;

int main() {
    scanf(&quot;%d&quot;, &amp;amp;n);
    for(int i=0; i&amp;lt;n; i++) {
        scanf(&quot;%d&quot;, &amp;amp;a[i]);
    }
    sort(a, a+n);
    for(int i=0; i&amp;lt;n; i++) {
        if(target &amp;lt; a[i]) break;
        target += a[i];
    }
    printf(&quot;%d&quot;, target);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제를 기준으로, 3 1 6 2 7 30 1을 정렬해 1 1 2 3 6 7 30 인 상태에서 1부터 만들 수 있는 수인지 검사해보자.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;target = 1일 때: a[0]이 1보다 크면 만들 수 없다. target에 a[0]을 더해 다음을 검사한다. (만들 수 있는 구간: 1~1)&lt;br /&gt;target = 2일 때: a[1]이 2보다 크면 만들 수 없다. target에 a[1]을 더해 다음을 검사한다. (만들 수 있는 구간: 1~2)&lt;br /&gt;target = 3일 때: a[2]이 3보다 크면 만들 수 없다. target에 a[2]을 더해 다음을 검사한다. (만들 수 있는 구간: 1~4)&lt;br /&gt;target = 5일 때: a[3]이 5보다 크면 만들 수 없다. target에 a[3]을 더해 다음을 검사한다. (만들 수 있는 구간 : 1~7)&lt;br /&gt;target = 8일 때: a[4]이 8보다 크면 만들 수 없다. target에 a[4]을 더해 다음을 검사한다. (만들 수 있는 구간 : 1~13)&lt;br /&gt;target = 14일 때: a[5]이 14보다 크면 만들 수 없다. target에 a[5]을 더해 다음을 검사한다. (만들 수 있는 구간 : 1~20)&lt;br /&gt;target = 21일 때: a[6]이 21보다 크면 만들 수 없다. a[6]이 target보다 작으므로 target을 반환하고 종료한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1783 병든 나이트&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;병든 나이트가 N &amp;times;&amp;nbsp;M 크기 체스판의 가장 왼쪽아래 칸에 위치해 있다. 병든 나이트는 건강한 보통 체스의 나이트와 다르게 4가지로만 움직일 수 있다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2칸 위로, 1칸 오른쪽&lt;/li&gt;
&lt;li&gt;1칸 위로, 2칸 오른쪽&lt;/li&gt;
&lt;li&gt;1칸 아래로, 2칸 오른쪽&lt;/li&gt;
&lt;li&gt;2칸 아래로, 1칸 오른쪽&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;병든 나이트는 여행을 시작하려고 하고, 여행을 하면서 방문한 칸의 수를 최대로 하려고 한다.&amp;nbsp;병든 나이트의 이동 횟수가 4번보다 적지 않다면,&amp;nbsp;이동 방법을 모두 한 번씩 사용해야&amp;nbsp;한다. 이동 횟수가 4번보다 적은 경우(방문한 칸이 5개 미만)에는 이동 방법에 대한 제약이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체스판의 크기가 주어졌을 때, 병든 나이트가 여행에서 방문할 수 있는 칸의 최대 개수를 구해보자.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 체스판의 세로 길이 N와 가로 길이 M이 주어진다. N과 M은 2,000,000,000보다 작거나 같은 자연수이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;병든 나이트가 여행에서 방문할 수 있는 칸의 개수중 최댓값을 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이동횟수가 4 이상이면 모든 방법을 한번씩 사용해야 하고, 이동횟수가 3 이하면 이동방법 사용 횟수에 제약이 없음을 유의해 케이스를 분류한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;i) 높이 n == 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가로 m이 몇이든 시작지점 하나밖에 방문하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ii) 높이 n == 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2, 3 방법으로 오른쪽으로 2칸씩만 이동할 수 있다. (1, 3, 5, 7, ...)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가로가 7 이하일 때는 (m+1)/2 방문 가능&lt;br /&gt;가로가 8 이상일 때는 3번 이동, 즉 4개 방문이 최대&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ii) 높이 n == 3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2,3을 사용하는 것보다 1,4를 이용해 가는 것이 더 많은 지점을 방문할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가로 4까지는 m&lt;br /&gt;가로 5~6이면 최대 4&lt;br /&gt;가로 7부터는 2,3을 한번씩만 사용하고 나머지는 1,4로 이동하면 되므로 m-2&lt;/p&gt;
&lt;pre id=&quot;code_1661063439382&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

int n, m;

int main() {
    scanf(&quot;%d %d&quot;, &amp;amp;n ,&amp;amp;m);
    if(n == 1) printf(&quot;1&quot;);
    else if(n == 2) {
        printf(&quot;%d&quot;, min((m+1)/2, 4));
    }
    else {
        if (m &amp;gt;=7) printf(&quot;%d&quot;, m-2);
        else printf(&quot;%d&quot;, min(m, 4));
    }

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1969 DNA&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DNA란 어떤 유전물질을 구성하는 분자이다. 이 DNA는 서로 다른 4가지의 뉴클레오티드로 이루어져 있다(Adenine, Thymine, Guanine, Cytosine). 우리는 어떤 DNA의 물질을 표현할 때, 이 DNA를 이루는 뉴클레오티드의 첫글자를 따서 표현한다. 만약에 Thymine-Adenine-Adenine-Cytosine-Thymine-Guanine-Cytosine-Cytosine-Guanine-Adenine-Thymine로 이루어진 DNA가 있다고 하면, &amp;ldquo;TAACTGCCGAT&amp;rdquo;로 표현할 수 있다. 그리고 Hamming Distance란 길이가 같은 두 DNA가 있을 때, 각 위치의 뉴클오티드 문자가 다른 것의 개수이다. 만약에 &amp;ldquo;AGCAT&quot;와 &amp;rdquo;GGAAT&quot;는 첫 번째 글자와 세 번째 글자가 다르므로 Hamming Distance는 2이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 할 일은 다음과 같다. N개의 길이 M인 DNA s1, s2, ..., sn가 주어져 있을 때 Hamming Distance의 합이 가장 작은 DNA s를 구하는 것이다. 즉, s와 s1의 Hamming Distance + s와 s2의 Hamming Distance + s와 s3의 Hamming Distance ... 의 합이 최소가 된다는 의미이다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 줄에 DNA의 수 N과 문자열의 길이 M이 주어진다. 그리고 둘째 줄부터 N+1번째 줄까지 N개의 DNA가 주어진다. N은 1,000보다 작거나 같은 자연수이고, M은 50보다 작거나 같은 자연수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 Hamming Distance의 합이 가장 작은 DNA 를 출력하고, 둘째 줄에는 그 Hamming Distance의 합을 출력하시오. 그러한 DNA가 여러 개 있을 때에는 사전순으로 가장 앞서는 것을 출력한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 많이 등장한 문자를 세서 문자열로 만들어준다. n에 대한 포문을 돌며 각 자리를 검사할 때 전체 횟수(n)에서 등장한 횟수를 빼면 그 자리에 대한 hamming distance가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 min을 갱신할 때 min 보다 작을 때만 갱신하게 해주어서, 사전순으로 가장 앞서는 것이 등록되게끔 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1661067907345&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;string&amp;gt;

using namespace std;

int n, m, dist;
string s;
string a[1001];

int main() {
    scanf(&quot;%d %d&quot;, &amp;amp;n, &amp;amp;m);
    for(int i=0; i&amp;lt;n; i++) {
        cin &amp;gt;&amp;gt; a[i];
    }
    for(int i=0; i&amp;lt;m; i++) {
        int cnt[4] = {0, };
        for(int j=0; j&amp;lt;n; j++) {
            if(a[j][i] == 'A') cnt[0]++;
            if(a[j][i] == 'C') cnt[1]++;
            if(a[j][i] == 'G') cnt[2]++;
            if(a[j][i] == 'T') cnt[3]++;
        }
        int idx=0, min=1001;
        for(int j=0; j&amp;lt;4; j++) {
            if (min &amp;gt; n - cnt[j]) {
                min = n - cnt[j];
                idx = j;
            }
        }
        if(idx == 0) s += 'A';
        if(idx == 1) s += 'C';
        if(idx == 2) s += 'G';
        if(idx == 3) s += 'T';
        dist += min;
    }
    cout &amp;lt;&amp;lt; s &amp;lt;&amp;lt; endl &amp;lt;&amp;lt; dist;

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2812 크게 만들기&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_description&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N자리 숫자가 주어졌을 때, 여기서 숫자 K개를 지워서 얻을 수 있는 가장 큰 수를 구하는 프로그램을 작성하시오.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_input&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째 줄에 N과 K가 주어진다. (1 &amp;le; K &amp;lt; N &amp;le; 500,000)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째 줄에 N자리 숫자가 주어진다. 이 수는 0으로 시작하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력&lt;/h3&gt;
&lt;/div&gt;
&lt;div id=&quot;problem_output&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력으로 주어진 숫자에서 K개를 지웠을 때 얻을 수 있는 가장 큰 수를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 앞자리 수가 클수록 큰 수이므로 &lt;b&gt;앞에 있는 수보다 뒤에 들어오는 수가 더 크면 앞에 있는 수를 지워주면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 포문을 다 돌았는데 지울 수가 남아있다면 이미 내림차순이 되어 있는 상태이므로 뒤에서부터 지워준다.&lt;/p&gt;
&lt;pre id=&quot;code_1661070064400&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;vector&amp;gt;

using namespace std;

int n, k;   // 길이, 지워야하는 개수
string a;
vector&amp;lt;char&amp;gt; result;

int main() {
    scanf(&quot;%d %d&quot;, &amp;amp;n, &amp;amp;k);
    cin &amp;gt;&amp;gt; a;
    for(int i=0; i&amp;lt;n; i++) {
        while(k &amp;gt; 0 &amp;amp;&amp;amp; !result.empty() &amp;amp;&amp;amp; result.back() &amp;lt; a[i]) {
            result.pop_back();
            k--;
        }
        result.push_back(a[i]);
    }
    while(k--) result.pop_back();
    
    for(int i=0; i&amp;lt;result.size(); i++) cout &amp;lt;&amp;lt; result[i];

    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>[C_C++]코딩테스트 연습/[백준] 일반 문제</category>
      <author>코딩굼벵이</author>
      <guid isPermaLink="true">https://coding-maggot.tistory.com/108</guid>
      <comments>https://coding-maggot.tistory.com/108#entry108comment</comments>
      <pubDate>Wed, 24 Aug 2022 10:18:37 +0900</pubDate>
    </item>
  </channel>
</rss>