<?xml version="1.0" encoding="utf-8"?><rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>nu50218 blog</title><link>https://nu50218.dev/</link><description>nu50218のブログです</description><generator>Hugo 0.108.0 https://gohugo.io/</generator><language>ja</language><managingEditor>blog@nu50218.dev (nu50218)</managingEditor><webMaster>blog@nu50218.dev (nu50218)</webMaster><copyright>© nu50218 2020~</copyright><lastBuildDate>Fri, 03 Jan 2025 11:39:42 +0000</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://nu50218.dev/rss.xml"/><item><title>平均次数が小さいグラフには大きい独立集合が存在する</title><link>https://nu50218.dev/posts/avgdeg-independet-set/</link><guid isPermaLink="true">https://nu50218.dev/posts/avgdeg-independet-set/</guid><pubDate>Sun, 03 Sep 2023 12:06:22 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>単純無向グラフ $G = (V, E)$ に対し、頂点と辺の個数を $n, m$ 、平均次数を $\Delta$ で表します。
このとき、グラフ $G$ にはサイズ $\Omega(n / \Delta)$ の独立集合が存在します。
そして、そのような独立集合を線形時間、すなわち $O(n + m)$ 時間で計算できます。
今回はそのアルゴリズムを紹介します。&lt;/p>
&lt;h2 id="用語の定義">用語の定義&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>平均次数&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>頂点 $v$ に対して「$v$ を端点に持つ辺の個数」を $v$ の次数と呼び、 $\mathrm{deg}(v)$ で表します。
平均次数とはその平均、すなわち、以下の値です。
$$
\Delta = \frac{\sum_{v \in V} \mathrm{deg}(v)}{n}.
$$&lt;/p>
&lt;ul>
&lt;li>&lt;strong>独立集合&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>独立集合とは、頂点集合 $I \subseteq V$ であって、隣接する2点を含まないものです。
すなわち、 $I$ に含まれる任意の2頂点 $u, v$ について、辺 $\{u, v\} \not\in E$ であるものです。&lt;/p>
&lt;h2 id="線形時間アルゴリズム">線形時間アルゴリズム&lt;/h2>
&lt;p>以下のアルゴリズムは、サイズ $\Omega(n / \Delta)$ の独立集合を出力します。&lt;/p>
&lt;ol>
&lt;li>$S$ を空集合とする。&lt;/li>
&lt;li>次数が $2\Delta$ 以下の頂点すべての集合を $Q$ とする。&lt;/li>
&lt;li>$Q$ が空になるまで、以下を繰り返す。
&lt;ol>
&lt;li>$Q$ から任意に頂点 $v$ を一つ削除し、 $S$ へ加える。&lt;/li>
&lt;li>$Q$ から $v$ に隣接する頂点すべてを削除する。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>$S$ を出力する。&lt;/li>
&lt;/ol>
&lt;h3 id="線形時間で動作するか">線形時間で動作するか？&lt;/h3>
&lt;p>データの持ち方に少し工夫が必要です。
$S, Q$ それぞれ、「頂点 $v$ が属するか？」のビット値の配列で表現します。
以下の部分では、 $Q$ を表現する配列の先頭から順に見ていき、 $Q$ に属する頂点を見つけるごとにその頂点を $v$ として処理していけばよいです。&lt;/p>
&lt;blockquote>
&lt;ol start="3">
&lt;li>$Q$ が空になるまで、以下を繰り返す。
&lt;ol>
&lt;li>$Q$ から任意に頂点 $v$ を一つ削除し、 $S$ へ加える。&lt;/li>
&lt;li>$Q$ から $v$ に隣接する頂点すべてを削除する。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ol>
&lt;/blockquote>
&lt;h3 id="正当性の証明">正当性の証明&lt;/h3>
&lt;p>上記のアルゴリズムが独立集合を出力することはあきらかです。
したがって、出力する $S$ のサイズが $\Omega(n / \Delta)$ であることを示します。&lt;/p>
&lt;p>まず、 $Q$ のサイズが $\lceil n / 2 \rceil$ 以上であることを背理法で示します。&lt;/p>
&lt;p>&lt;strong>証明：&lt;/strong>
次数が $2\Delta$ より大きい頂点が $\lceil n / 2 \rceil$ 個あると仮定します。
このとき、以下のとおり矛盾が生じます。
$$
\Delta = \frac{\sum_{v \in V} \mathrm{deg}(v)}{n} \geq \frac{(2\Delta + 1) \cdot \lceil n / 2 \rceil}{n} \geq \frac{(\Delta + 1/2) \cdot n}{n} &amp;gt; \Delta.
$$&lt;/p>
&lt;p>一方で、 $v \in Q$ について、「 $v$ とその隣接頂点」の個数は高々 $2 \Delta + 1$ 個です。
すなわち、アルゴリズムの3の各ループでは高々 $2 \Delta + 1$ 個の頂点しか $Q$ から削除されません。
したがってアルゴリズムの3は少なくとも $\lceil n / 2 \rceil / (2 \Delta + 1) = \Omega(n / \Delta)$ 回繰り返され、 $S$ のサイズも $\Omega(n / \Delta)$ です。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/math/">math</category><category domain="https://nu50218.dev/tags/algorithm/">algorithm</category></item><item><title>依存先が商の形をしたDPの高速化</title><link>https://nu50218.dev/posts/quotient-shaped-dp-sparsify/</link><guid isPermaLink="true">https://nu50218.dev/posts/quotient-shaped-dp-sparsify/</guid><pubDate>Sat, 11 Mar 2023 06:55:19 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>出たコンテストで初めて見るタイプのDPがあって頑張って理解したのでゆるく証明します。&lt;/p>
&lt;p>簡単に言うと、以下の形のDPに対して $\mathrm{dp} (n, k)$ を $O(n k^{\frac{3}{4}})$ 時間で求められるという主張です。&lt;/p>
&lt;p>$$
\mathrm{dp} (i+1, j) = \max_{1 \leq d \leq j} \left\{ \bigcirc \cdot \mathrm{dp} \left(i, \left\lceil \frac{j}{d} \right\rceil \right) \right\}.
$$&lt;/p>
&lt;p>ここで、 $\bigcirc$ は状態 $(i, \lceil j / d \rceil )$ から $(i+1, j)$ への遷移に対して最適な $d$ が $O(1)$ 時間で計算できるような値です（ $d$ について単調性があるなど）。&lt;/p>
&lt;h2 id="ゆるい証明">ゆるい証明&lt;/h2>
&lt;p>コールグラフ的なものを考えて説明します。
すなわち、状態 $(i, j)$ を頂点として、上記の式の$\mathrm{dp}(i, j)$ の計算で $\mathrm{dp} (i&amp;rsquo;, j&amp;rsquo;)$ の値を用いるとき $(i, j)$ から $(i&amp;rsquo;, j&amp;rsquo;)$ へ辺を貼ったグラフ $G$ を考えます。
グラフ $G$ において、 $(n, k)$ から到達可能な頂点集合、すなわち $\mathrm{dp} (n, k)$ の計算の際に用いられる引数の集合を $V_{n,k}$ とします。&lt;/p>
&lt;p>天下り的ですが、実はこのとき以下の2つの主張が成り立ちます。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>$\{j \mid (i, j) \in V_{n,k}\} = \{\lceil k / d \rceil \mid 1 \leq d \leq k \}$&lt;/p>
&lt;/li>
&lt;li>
&lt;p>重複する辺を除いたとき、$|E(G[V_{n,k}])| = O(n k^{\frac{3}{4}})$&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>1つ目は、 $\mathrm{dp}(n, k)$ を計算する際に状態 $(i, j) \in \{1, 2, \dots, n\} \times \{1, 2, \dots, k\}$ に対してテーブルを埋める必要はなく、 $j$ が $k$ の商であるもののみ埋めればよいことを意味します。
$k$ の商は$O(\sqrt{k})$個ですから、各 $i$ に対して $O(\sqrt{k})$ 個の状態しかありません。&lt;/p>
&lt;p>また、下記の仮定より、$\mathrm{dp}(i + 1, j)$ は $\mathrm{dp}(i, \ast)$ の行を全てチェックすると $O(\sqrt{k})$ 時間で計算できますが、これだと計算量は $O(n \sqrt{k} \cdot \sqrt{k}) = O(nk)$ 時間となってしまいます。&lt;/p>
&lt;blockquote>
&lt;p>$\bigcirc$ は状態 $\left(i, \lceil j / d \rceil \right)$ から $(i+1, j)$ への遷移に対して最適な $d$ が $O(1)$ 時間で計算できる&lt;/p>
&lt;/blockquote>
&lt;p>実は $\mathrm{dp}(i + 1, j)$ の計算をする際に、 $j&amp;rsquo;$ を $j$ の商として $\mathrm{dp}(i, j&amp;rsquo;)$ のみチェックするだけで、$O(n k^{\frac{3}{4}})$ 時間になるというのが、2つ目の主張です。&lt;/p>
&lt;h3 id="主張1の証明">主張1の証明&lt;/h3>
&lt;p>任意の $\lceil k / d \rceil$ と $1 \leq d&amp;rsquo; \leq \lceil k / d \rceil$ について以下が成り立つことを示せば十分です。
$$
\left\lceil \frac{\left\lceil \frac{k}{d} \right\rceil}{d&amp;rsquo;} \right\rceil = \left\lceil \frac{k}{d d&amp;rsquo;} \right\rceil.
$$&lt;/p>
&lt;p>$\lceil k / d \rceil = k / d$ のときは明らかですから、 $k = ad + b \ (b \in [1, d-1])$ とします。上述の式に代入すると、それぞれ
$$
\left\lceil \frac{a+1}{d&amp;rsquo;} \right\rceil, \left\lceil \frac{a + \frac{b}{d}}{d&amp;rsquo;} \right\rceil
$$
となります。
ここで、$0 &amp;lt; b/d &amp;lt; 1$ですから、
$$
\left\lceil \frac{a + \frac{b}{d}}{d&amp;rsquo;} \right\rceil = \left\lceil \frac{a + 1}{d&amp;rsquo;} \right\rceil
$$
と評価できます。&lt;/p>
&lt;h3 id="主張2の証明">主張2の証明？&lt;/h3>
&lt;blockquote>
&lt;p>$\mathrm{dp}(i + 1, j)$ の計算をする際に、 $j&amp;rsquo;$ を $j$ の商として $\mathrm{dp}(i, j&amp;rsquo;)$ のみチェックするだけで、$O(n k^{\frac{3}{4}})$ 時間になるというのが、2つ目の主張です。&lt;/p>
&lt;/blockquote>
&lt;p>計算量を&lt;del>ちゃんと&lt;/del>あいまいに評価します。
$\mathrm{dp}(i, \ast)$ から $\mathrm{dp}(i + 1, \ast)$ を計算する計算量が $O(k^{\frac{3}{4}})$ になっていることを確認すれば十分です。&lt;/p>
&lt;p>上記の計算量は、こんな感じで評価できるらしいです。ただし、 $Q(x)$ で $x$ の商全体の集合を表します。
$$
\sum_{x \in Q(k)} |Q(x)| \simeq \sum_{\sqrt{k} \geq x \in Q(k)} \left( Q(x) + Q \left(\left\lceil \frac{k}{x} \right\rceil \right) \right)
= \sum_{\sqrt{k} \geq x \in Q(k)} O\left(\sqrt{\frac{k}{x}}\right) = O(k^{\frac{3}{4}}).
$$&lt;/p>
&lt;p>積分すると、$O(k^{\frac{3}{4}})$になるそうです。&lt;/p>
&lt;blockquote>
&lt;p>$$
\sum_{r\in R}\sqrt{r}\leq \sum_{i=1}^{\sqrt{k}}(\sqrt{i}+\sqrt{\frac{k}{i}}) \leq 2\sum_{i=1}^{\sqrt{k}}\sqrt{\frac{k}{i}} \leq 2\int_{0}^{\sqrt{k}} \sqrt{\frac{k}{x}}\text{d}x =4\sqrt{kx}\bigm|_0^{\sqrt{k}}=4k^{\frac{3}{4}}
$$
引用元: &lt;a href="https://codeforces.com/blog/entry/113672?#comment-1011533">https://codeforces.com/blog/entry/113672?#comment-1011533&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h2 id="応用例">応用例&lt;/h2>
&lt;h3 id="問題">問題&lt;/h3>
&lt;p>Codeforces の &lt;a href="https://codeforces.com/contest/1801/problem/F">Another n-dimensional chocolate bar&lt;/a> という問題です。
本質部分だけ抜き出すと、次の問題です。&lt;/p>
&lt;p>$n$ 個の正の整数からなる列 $a = (a_1, a_2, \dots, a_n)$ と正の整数 $k$ が与えられる。$n$ 個の正の整数からなる列 $b = (b_1, b_2, \dots, b_n)$ で $b_1 b_2 \dots b_n \geq k$ を満たすものに対する以下の式の最大値を求めたい。
$$
\left\lfloor \frac{a_1}{b_1} \right\rfloor \left\lfloor \frac{a_2}{b_2} \right\rfloor \dots \left\lfloor \frac{a_n}{b_n} \right\rfloor.
$$&lt;/p>
&lt;p>ただし、 $n \leq 100$, $k \leq 10^9$, $a_1 a_2 \dots a_n \geq k$ を満たす。&lt;/p>
&lt;h3 id="解法">解法&lt;/h3>
&lt;p>$\mathrm{dp}(i, j)$ を、$i$ 番目まで見て $b_i$ の積が $j$ 以上のものの最大値とします。
すなわち、$i$ 個の正の整数からなる列 $b = (b_1, b_2, \dots, b_i)$ の列で $b_1 b_2 \dots b_i \geq j$
を満たすものに対する以下の式の最大値とします。
$$
\left\lfloor \frac{a_1}{b_1} \right\rfloor \left\lfloor \frac{a_2}{b_2} \right\rfloor \dots \left\lfloor \frac{a_i}{b_i} \right\rfloor.
$$
答えは明らかに $\mathrm{dp}(n, k)$ です。&lt;/p>
&lt;p>さて、 $\mathrm{dp}(i + 1, j)$ の計算を考えます。&lt;/p>
&lt;p>$b_{i+1} = d$ と固定した場合の最大値は、どのように計算できるでしょうか。
$b_1 b_2 \dots b_{i+1} \geq j$の条件を満たすためには、 $b_1 b_2 \dots b_i$ の整数性から $b_1 b_2 \dots b_i \geq \left\lceil j / b_{i+1} \right\rceil$ が必要十分となります。
一方で、 $\mathrm{dp}(i, j)$ は $j$ について単調減少ですから、最大値は以下の値となります。
$$
\left\lfloor \frac{a_{i+1}}{d} \right\rfloor \cdot \mathrm{dp} \left(i, \left\lceil \frac{j}{d} \right\rceil \right).
$$&lt;/p>
&lt;p>以上から、$\mathrm{dp}(i + 1, j)$ は以下のとおり計算できます。
$$
\mathrm{dp} (i+1, j) = \max_{1 \leq d \leq j} \left\{ \left\lfloor \frac{a_{i+1}}{d} \right\rfloor \cdot \mathrm{dp} \left(i, \left\lceil \frac{j}{d} \right\rceil \right) \right\}.
$$&lt;/p>
&lt;p>そして、$\lfloor a_{i+1} / d \rfloor$ が $d$ について単調非増加であることから、 $\lceil j / d \rceil$ が同じ値となる $d$ については最小のものだけ計算すれば十分です。
そして、そのような $d$ は商の列挙時に同時に求められます（参照: &lt;a href="https://codeforces.com/contest/1801/submission/196619025">touristのコード&lt;/a>）。
したがって、今回紹介した手法で $O(n k^{\frac{3}{4}})$ 時間で $\mathrm{dp}(n, k)$ が計算でき、TLに間に合います。&lt;/p></description><category domain="https://nu50218.dev/categories/kyopro/">kyopro</category><category domain="https://nu50218.dev/tags/math/">math</category><category domain="https://nu50218.dev/tags/codeforces/">codeforces</category><category domain="https://nu50218.dev/tags/algorithm/">algorithm</category></item><item><title>017 - Crossing Segments（★7）の別解</title><link>https://nu50218.dev/posts/atcoder-typical90_q/</link><guid isPermaLink="true">https://nu50218.dev/posts/atcoder-typical90_q/</guid><pubDate>Mon, 02 Jan 2023 07:31:11 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>競プロ典型90問「017 - Crossing Segments（★7）」の別解になります。
本質的には同じことをやっていたらすみません。&lt;/p>
&lt;h2 id="問題">問題&lt;/h2>
&lt;h3 id="問題文">問題文&lt;/h3>
&lt;blockquote>
&lt;p>演習上に $N$ 個の点があり、時計回りに $1,2,\dots,N$ と番号づけられています。
また、 $M$ 本の線分があり、線分 $i$ は点 $L_i$ と 点 $R_i$ を結んでいます。&lt;/p>
&lt;p>線分 $s, t$ が端点以外で交わるような、 $(s, t) \ (1 \leq s &amp;lt; t \leq M)$ の組の数を求めてください。&lt;/p>
&lt;/blockquote>
&lt;p>&lt;a href="https://atcoder.jp/contests/typical90/tasks/typical90_q">https://atcoder.jp/contests/typical90/tasks/typical90_q&lt;/a> より引用&lt;/p>
&lt;h3 id="制約">制約&lt;/h3>
&lt;ul>
&lt;li>$N, M \leq 3 \times 10^5$&lt;/li>
&lt;/ul>
&lt;h2 id="別解">別解&lt;/h2>
&lt;h3 id="考察">考察&lt;/h3>
&lt;p>円周を $N$ 頂点の重みなし無向サイクルだとみなします。
そして、「線分 $i$ の幅」 を $\min(R_i - L_i, N - (R_i - L_i))$ で定義します。
これは、円周を $N$ 頂点のサイクルとみなしたとき、頂点 $L_i$ から $R_i$ の最短経路上のパスの数に等しいです。&lt;/p>
&lt;p>さて、幅が最小の線分 $i$ を考えます。
線分 $j$ が線分 $i$ と端点以外で交わるとき、以下が成り立ちます。&lt;/p>
&lt;ul>
&lt;li>「頂点 $L_i$ から $R_i$ の最短経路」上（$L_i, R_i$を除く）に線分 $j$ の端点が存在する。&lt;/li>
&lt;/ul>
&lt;p>一方で、幅の最小性より、以下も成り立ちます。&lt;/p>
&lt;ul>
&lt;li>「頂点 $L_i$ から $R_i$ の最短経路」上（$L_i, R_i$を除く）に端点を持つ線分について、もう片方の端点は「頂点 $L_i$ から $R_i$ の最短経路でない方のシンプルパス」上（$L_i, R_i$を除く）にある。&lt;/li>
&lt;/ul>
&lt;p>上述の２つの事実から、少し考えると、以下の２つの個数が等しいことがわかります。&lt;/p>
&lt;ul>
&lt;li>線分 $i$ と端点以外で交わる線分の個数。&lt;/li>
&lt;li>「頂点 $L_i$ から $R_i$ の最短経路」上にある端点の個数。&lt;/li>
&lt;/ul>
&lt;h3 id="解法">解法&lt;/h3>
&lt;p>以上の考察を用いると、次の方法で正しい答えが得られることがわかります。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>$\mathrm{ans}$ を $0$ とする。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>以下を線分が無くなるまで繰り返す。&lt;/p>
&lt;ol>
&lt;li>幅が最小の線分を１つ選び、 $i$ とする。&lt;/li>
&lt;li>「頂点 $L_i$ から $R_i$ の最短経路」上にある端点の個数を、 $\mathrm{ans}$ に加える。&lt;/li>
&lt;li>線分 $i$ を削除する。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>
&lt;p>$\mathrm{ans}$ を出力する。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>上記は、セグメントツリーを使うことで、 $\Theta(M (\log M + \log N))$ 時間で計算することができます。&lt;/p>
&lt;h3 id="ソースコード">ソースコード&lt;/h3>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;bits/stdc++.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;atcoder/segtree.hpp&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">struct&lt;/span> &lt;span class="nc">line&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">width&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">op&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">e&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">int&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">M&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cin&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">N&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">M&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">line&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">lines&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">int&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">M&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="o">++&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cin&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">L&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">L&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">R&lt;/span>&lt;span class="o">--&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">width1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">R&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">int&lt;/span> &lt;span class="n">width2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">L&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">N&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">width1&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="n">width2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lines&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="n">width1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lines&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">push_back&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="n">width2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">lines&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">begin&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">lines&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">end&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="p">[](&lt;/span>&lt;span class="n">line&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">line&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">width&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">width&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">atcoder&lt;/span>&lt;span class="o">::&lt;/span>&lt;span class="n">segtree&lt;/span>&lt;span class="o">&amp;lt;&lt;/span>&lt;span class="kt">int&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">op&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">e&lt;/span>&lt;span class="o">&amp;gt;&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">lines&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">long&lt;/span> &lt;span class="kt">long&lt;/span> &lt;span class="n">ans&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="k">auto&lt;/span>&lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">lines&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ans&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">prod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ans&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">prod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ans&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">prod&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">R&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">L&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">st&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">R&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">ans&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="n">endl&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>提出: &lt;a href="https://atcoder.jp/contests/typical90/submissions/37691943">https://atcoder.jp/contests/typical90/submissions/37691943&lt;/a>&lt;/p></description><category domain="https://nu50218.dev/categories/kyopro/">kyopro</category><category domain="https://nu50218.dev/tags/atcoder/">atcoder</category></item><item><title>コンパイラによる整数除算最適化の証明</title><link>https://nu50218.dev/posts/integer-division-by-multiplication/</link><guid isPermaLink="true">https://nu50218.dev/posts/integer-division-by-multiplication/</guid><pubDate>Tue, 20 Dec 2022 05:24:24 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>一般的に、CPUにおける整数の除算（割り算）は遅いです。&lt;/p>
&lt;p>そのため、コンパイル時定数で割る処理を書くと、コンパイラが「乗算とビットシフト」を用いた高速な処理へ変換します。&lt;/p>
&lt;p>この記事では、その具体的な変換方法と正当性を示します。&lt;/p>
&lt;h2 id="はじめに">はじめに&lt;/h2>
&lt;p>この記事では上記のような最適化の存在を知っていることを前提とします。
知らない場合は、2や3で割る場合についての以下の記事を先に読むことをおすすめします。&lt;/p>
&lt;p>&lt;a href="https://qiita.com/saka1_p/items/6400e5cedea0b3c286c9">2で割ることと3で割ること - Qiita&lt;/a>&lt;/p>
&lt;h2 id="概要">概要&lt;/h2>
&lt;h3 id="3で割るとき">3で割るとき&lt;/h3>
&lt;p>たとえば、以下の定数 $3$ で割って返す関数は、&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span>&lt;span class="cpf">&amp;lt;stdint.h&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">const&lt;/span> &lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">d&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nf">div_by_d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">d&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>x86_64 gcc 12.2&lt;/code> では次のとおり最適化されます。
&lt;a href="https://godbolt.org/z/WK6xz7Gab">こちらのサイト&lt;/a>で実際に $d$ を変えて試すことができます。&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-x86asm" data-lang="x86asm">div_by_d(unsigned int):
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov eax, DWORD PTR [rbp-4]
mov edx, eax
mov eax, 2863311531
imul rax, rdx
shr rax, 32
shr eax
pop rbp
ret
&lt;/code>&lt;/pre>&lt;p>上記のアセンブリでは、C++で記述すると次のような処理に変換されています。
64ビットで $x$ を扱い、 $2863311531$ をかけて $33$ ビット右へシフトしています。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nf">div_by_d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">2863311531&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">33&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>そして実は、任意の $d (\neq 0)$ に対して上記のような形に最適化できます。
すなわち、任意の $d (\neq 0)$ に対して、次のような形に最適化できる $m, l$ が存在します。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nf">div_by_d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">32&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">l&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="記事の内容">記事の内容&lt;/h3>
&lt;p>以下ではまず、実際に $d$ に対して $m, l$ を得るアルゴリズムと、その正当性を示します。&lt;/p>
&lt;p>また、上記のコードのとおりにプログラムを書くと、 $m$ の値によってはオーバーフローすることがあります。
これを回避する方法も示します。&lt;/p>
&lt;p>これらは元論文&lt;sup id="fnref:1">&lt;a href="https://nu50218.dev/posts/integer-division-by-multiplication/#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>を参考に、簡潔な形で整理したものになります。&lt;/p>
&lt;h2 id="m-l-を得るアルゴリズム">$m, l$ を得るアルゴリズム&lt;/h2>
&lt;p>次のとおりです。&lt;/p>
&lt;p>$$
l = \lceil \log_2 (d) \rceil, \ m = \left\lceil \frac{2^{32 + l}}{d} \right\rceil.
$$&lt;/p>
&lt;p>どちらもシンプルなアルゴリズムで十分高速（$O(\log d)$ 時間）に求まります。&lt;/p>
&lt;h2 id="正当性">正当性&lt;/h2>
&lt;p>上記の $m, l$ で正しく計算できることを示します。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nf">div_by_d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">32&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">l&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>上記の関数の返り値は、数式で表すと $\left\lfloor mx / 2^{32+l} \right\rfloor$ です。
これが元の &lt;code>x / d&lt;/code> に一致していること、すなわち次の式を示せば十分です。&lt;/p>
&lt;p>$$
\begin{align}
\left\lfloor \frac{mx}{2^{32+l}} \right\rfloor = \left\lfloor \frac{x}{d} \right\rfloor.
\end{align}
$$&lt;/p>
&lt;p>まず、$m \geq 2^{32 + l} / d$ ですから、次のとおり評価できます。&lt;/p>
&lt;p>$$
\begin{align*}
\left\lfloor \frac{mx}{2^{32+l}} \right\rfloor
&amp;amp;\geq \left\lfloor \frac{x}{2^{32+l}} \cdot \frac{2^{32+l}}{d} \right\rfloor \\
&amp;amp;= \left\lfloor \frac{x}{d} \right\rfloor.
\end{align*}
$$&lt;/p>
&lt;p>一方で、 $x = q d + r \ (0 \leq r &amp;lt; d)$ とすると、次のとおり評価できます。&lt;/p>
&lt;p>$$
\begin{align*}
\frac{mx}{2^{32+l}} - \left\lfloor \frac{x}{d} \right\rfloor
&amp;amp;= \left\lceil \frac{2^{32 + l}}{d} \right\rceil \frac{x}{2^{32+l}} - q \\
&amp;amp;\leq \left( \frac{2^{32 + l}}{d} + 1\right) \frac{x}{2^{32+l}} - q \\
&amp;amp;= \frac{x}{d} + \frac{x}{2^{32+l}} - q \\
&amp;amp;= \frac{x}{d} + \frac{x}{2^{32 + \lceil \log_2 (d) \rceil}} - \frac{x-r}{d} \\
&amp;amp;= \frac{r}{d} + \frac{x}{2^{32 + \lceil \log_2 (d) \rceil}} \\
&amp;amp;\leq \frac{d - 1}{d} + \frac{x}{2^{32} \cdot d} \\
&amp;amp;\leq \frac{1}{d} \left( d - 1 + \frac{2^{32} - 1}{2^{32}} \right) \\
&amp;amp;&amp;lt; 1.
\end{align*}
$$&lt;/p>
&lt;p>以上より、(1)式が示せました。&lt;/p>
&lt;h2 id="オーバーフローを避ける方法">オーバーフローを避ける方法&lt;/h2>
&lt;p>以上より、以下の計算を期待通り行うことができれば、 $d$ で割った値が得られます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nf">div_by_d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="mi">32&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">l&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>一方で、 $m$ は次のとおり $2^{32}$ を超える可能性があります。
そのような場合、 $x$ が大きいと $64$ ビットにおさまらずオーバーフローしてしまいます。&lt;/p>
&lt;p>$$
\begin{align*}
m &amp;amp;= \left\lceil \frac{2^{32 + l}}{d} \right\rceil \\
&amp;amp;= \left\lceil \frac{2^{32 + \lceil \log_2 (d) \rceil}}{d} \right\rceil \\
&amp;amp;\leq \left\lceil \frac{2^{33} \cdot d}{d} \right\rceil \\
&amp;amp;= 2^{33}.
\end{align*}
$$&lt;/p>
&lt;p>したがって、$m$ が $2^{32}$ 以上となる場合、以下のように分割して計算します。&lt;/p>
&lt;p>$$
\begin{align*}
mx = (m - 2^{32}) x + 2^{32} x.
\end{align*}
$$&lt;/p>
&lt;p>$(m - 2^{32}) \leq 2^{33} - 2^{32} = 2^{32}$ですから、$(m - 2^{32}) x, 2^{32} x$ はそれぞれオーバーフローせずに計算できます。&lt;/p>
&lt;p>そして、以下の理由により、$(m - 2^{32}) x, 2^{32} x$ をそれぞれ $32$ ビット右にシフトしてから計算しても、値が変わらないことがわかります。&lt;/p>
&lt;ul>
&lt;li>$mx$ の上位 $32 - l$ ビットにのみ興味がある&lt;/li>
&lt;li>$2^{32} x$ の下位 $32$ ビットが $0$ である&lt;/li>
&lt;/ul>
&lt;p>したがって、以下のように計算することで、オーバーフローを避けることができます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">uint32_t&lt;/span> &lt;span class="nf">div_by_d&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kt">uint32_t&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kt">uint64_t&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">*=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kt">uint64_t&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">32&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">+=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span> &lt;span class="o">&amp;gt;&amp;gt;=&lt;/span> &lt;span class="n">l&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="補足">補足&lt;/h2>
&lt;h3 id="最適化の気持ち">最適化の気持ち&lt;/h3>
&lt;p>実数の除算で $x / d$ という計算を考えます。
これは、$(1 / d)$ をコンパイル時に計算しておくことで、 $x \cdot (1 / d)$ と乗算に変換できます。&lt;/p>
&lt;p>実態としては、これを $m, l$ と追加の$32$ビットを用いて近似計算しています。
具体的には、&lt;/p>
&lt;p>$$
\frac{m}{2^{32+l}} = \frac{1}{d} + \varepsilon
$$&lt;/p>
&lt;p>となるように $(1 / d)$ を固定小数点数として近似します。
このとき、 $x$ に $m$ をかけて$32 + l$ ビット右シフトすることで、&lt;/p>
&lt;p>$$
\left\lfloor \frac{mx}{2^{32+l}} \right\rfloor = \left\lfloor \frac{x}{d} + \varepsilon x \right\rfloor
$$&lt;/p>
&lt;p>が得られます。
上手に $m, l$ を選んであげることで、誤差の $\varepsilon x$ が $x &amp;lt; 2^{32}$ において十分小さくなり、$\left\lfloor x / d \right\rfloor$ が得られます。
証明では、これを示していたのでした。&lt;/p>
&lt;h3 id="n-ビット整数での除算">$N$ ビット整数での除算&lt;/h3>
&lt;p>今回の証明において、$32$ ビットを $N$ ビットとしても問題ありません。
したがって、たとえば $64$ ビットの整数同士で演算したい場合は、 $128$ ビット用いることで同様に計算できます。&lt;/p>
&lt;h3 id="d-が特殊な場合">$d$ が特殊な場合&lt;/h3>
&lt;p>先述の記事にも書かれていますが、$d = 2^k$ の場合は右に$k$シフトさせるとさらに高速になります。
また、それ以外の場合でも、より高速にする手法が色々あるようです。&lt;/p>
&lt;h3 id="符号付きの場合">符号付きの場合&lt;/h3>
&lt;p>符号付きの場合も同様な手法が適用できるようですが、符号なしを理解して満足してしまったので勉強していません。
気になる方は元論文&lt;sup id="fnref1:1">&lt;a href="https://nu50218.dev/posts/integer-division-by-multiplication/#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>を参照ください。&lt;/p>
&lt;div class="footnotes" role="doc-endnotes">
&lt;hr>
&lt;ol>
&lt;li id="fn:1">
&lt;p>Torbjörn Granlund and Peter L. Montgomery. 1994. Division by invariant integers using multiplication. SIGPLAN Not. 29, 6 (June 1994), 61–72. &lt;a href="https://doi.org/10.1145/773473.178249">https://doi.org/10.1145/773473.178249&lt;/a>&amp;#160;&lt;a href="https://nu50218.dev/posts/integer-division-by-multiplication/#fnref:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&amp;#160;&lt;a href="https://nu50218.dev/posts/integer-division-by-multiplication/#fnref1:1" class="footnote-backref" role="doc-backlink">&amp;#x21a9;&amp;#xfe0e;&lt;/a>&lt;/p>
&lt;/li>
&lt;/ol>
&lt;/div></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/math/">math</category><category domain="https://nu50218.dev/tags/algorithm/">algorithm</category></item><item><title>VSCodeのRemote-SSH先でcodeコマンドにパスを通す</title><link>https://nu50218.dev/posts/vscode-remote-cli-bashrc/</link><guid isPermaLink="true">https://nu50218.dev/posts/vscode-remote-cli-bashrc/</guid><pubDate>Fri, 02 Sep 2022 08:18:24 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>Remote-SSHで接続したとき、&lt;code>code&lt;/code>コマンドが&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">~/.vscode-server/bin/&amp;lt;hash&amp;gt;/bin/remote-cli/code
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>へ自動的に置かれます。&lt;/p>
&lt;p>ドキュメントによればVSCodeのintegrated terminalで開くと勝手にパスが通っているらしいですが、何故か通っていませんでした。
なので、&lt;code>~/.bashrc&lt;/code>にパスを通すコマンドを追記しました。
またこれになりそうなので、メモとして書いておきます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="o">[&lt;/span> -n &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$VSCODE_IPC_HOOK_CLI&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="o">]&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="k">then&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">VSCODE_HASH_SUFFIX&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">BROWSER&lt;/span>&lt;span class="p">#/home/ubuntu/.vscode-server/bin/&lt;/span>&lt;span class="si">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nv">VSCODE_HASH&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="nv">VSCODE_HASH_SUFFIX&lt;/span>&lt;span class="p">%/bin/helpers/browser.sh&lt;/span>&lt;span class="si">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">export&lt;/span> &lt;span class="nv">PATH&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$PATH&lt;/span>&lt;span class="s2">:~/.vscode-server/bin/&lt;/span>&lt;span class="nv">$VSCODE_HASH&lt;/span>&lt;span class="s2">/bin/remote-cli&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">fi&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/vscode/">vscode</category><category domain="https://nu50218.dev/tags/ssh/">ssh</category></item><item><title>（別解？）D: Modulo Operations - Exawizards2019 D</title><link>https://nu50218.dev/posts/exawizards2019-d-modulo-operations/</link><guid isPermaLink="true">https://nu50218.dev/posts/exawizards2019-d-modulo-operations/</guid><pubDate>Fri, 01 Jul 2022 18:26:49 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>別解っぽい面白い解き方をしたので記録に残します。&lt;/p>
&lt;h2 id="問題文">問題文&lt;/h2>
&lt;blockquote>
&lt;p>すぬけ君は黒板と$N$個の整数からなる集合$S$を持っています。$S$の$i$番目の要素は$S_i$です。&lt;/p>
&lt;p>すぬけ君は黒板に整数$X$を書いたのち、以下の操作を$N$回行います。&lt;/p>
&lt;ul>
&lt;li>$S$から要素を１つ選んで取り除く。&lt;/li>
&lt;li>その後、現在黒板に書かれた数を$x$、$S$から取り除かれた整数を$y$として、黒板に書かれた数を$x \mod y$に書き換える。&lt;/li>
&lt;/ul>
&lt;p>$S$から要素を取り除く順序は$N!$通りありえます。
それぞれの場合について、$N$回の操作後に黒板に書かれている数を求め、その総和を$10^9+7$で割ったあまりを求めてください。&lt;/p>
&lt;/blockquote>
&lt;p>引用元: &lt;a href="https://atcoder.jp/contests/exawizards2019/tasks/exawizards2019_d">https://atcoder.jp/contests/exawizards2019/tasks/exawizards2019_d&lt;/a>&lt;/p>
&lt;h2 id="同じ要素を選ぶことを許してみる">同じ要素を選ぶことを許してみる&lt;/h2>
&lt;p>問題設定では$S$の要素１つごとに操作を行っていますが、これを何度でも行うことを許してみましょう。
すなわち、次の操作を好きなだけ繰り返すことを考えます。&lt;/p>
&lt;ul>
&lt;li>$S$から要素を１つ選び、$y$とする。&lt;/li>
&lt;li>現在黒板に書かれた数を$x$として、黒板に書かれた数を$x \mod y$に書き換える。&lt;/li>
&lt;/ul>
&lt;p>このとき、実は２度目以降は同じ$y$を選んでも黒板に書かれた数は変わりません。
なぜなら、黒板に書かれた数は増加しない一方で、一度目の操作で$(x \mod y) &amp;lt; y$となるためです。&lt;/p>
&lt;p>すなわち、たとえば$y$を
$$
(10, 5, 8, 10, 4, 8, 8)
$$
として選んだとき、これから２度目以降の$10, 8$を除いた操作
$$
(10, 5, 8, 4)
$$
と最終的に同じ値となります。&lt;/p>
&lt;h2 id="ランダムに無限回操作してみる">ランダムに無限回操作してみる&lt;/h2>
&lt;p>さて、上記の操作をランダムに無限回繰り返すことを考えてみましょう。
すなわち、次の操作を無限回繰り返すことを考えます。&lt;/p>
&lt;ul>
&lt;li>$S$から&lt;strong>ランダムに&lt;/strong>要素を１つ選び、$y$とする。&lt;/li>
&lt;li>現在黒板に書かれた数を$x$として、黒板に書かれた数を$x \mod y$に書き換える。&lt;/li>
&lt;/ul>
&lt;p>このとき、確率$1$で要素$S$のすべてを少なくとも１回ずつ選びます。
「要素$S$のすべてを少なくとも１回ずつ選ぶ操作」を考えてみます。
そのような操作では、上述のように２度目以降の要素を除くことで、$S$の要素$N$個を１度ずつ選ぶ操作に対応します。
そしてその並び順は、ランダムに選んだことから任意の並び方について$1 / N!$の確率で選ばれます。&lt;/p>
&lt;p>以上の議論により、次の値が同じであることがわかります。&lt;/p>
&lt;ul>
&lt;li>$S$からランダムに要素を１つずつ取り除くとき、最終的に黒板に書かれた数が$n$である確率。&lt;/li>
&lt;li>無限回$S$からランダムに要素を選ぶとき、最終的に黒板に書かれた数が$n$である確率。&lt;/li>
&lt;/ul>
&lt;p>（最終的に$n$である確率は、「$i$回ランダムに操作したあとに$n$である確率」の$i \rightarrow \infty$における極限値とします）&lt;/p>
&lt;p>また、前者の確率が求まったとき、期待値を計算し$N!$倍することで出力値となります。
したがって、後者を効率的に計算できれば十分です。&lt;/p>
&lt;h2 id="ランダムに無限回操作したとき最終的にnである確率">ランダムに無限回操作したとき最終的に$n$である確率&lt;/h2>
&lt;p>現在黒板に$x$が書かれているとします。
$y \in S$が選ばれた場合、黒板の数は$x$から$x \mod y$へ遷移します。&lt;/p>
&lt;p>黒板にかかれている数を頂点として、遷移を有向辺で貼ってみます。
黒板に書かれた数は増加しないため、DAGに自己ループを生やしたものとなります。&lt;/p>
&lt;p>次の画像は$X = 8, S = \{3, 5\}$の場合のグラフです。
紫色の辺が$5$、オレンジ色が$3$を選ぶ遷移です。&lt;/p>
&lt;p>&lt;img src="https://nu50218.dev/images/exawizards2019-d-figure-graph.png" alt="exawizards2019-d-figure-graph.png">&lt;/p>
&lt;p>ランダムに無限回操作したとき、最終的に$n$である確率を考えます。
天下り的に書くと、これは$X$から確率$1$をDAG上で等しく分配していくことで計算できます。&lt;/p>
&lt;p>具体的には、次の計算をこれをトポロジカルソート順に$X$からやっていきます。
はじめ$X$は確率$1$を持っているとします。&lt;/p>
&lt;p>頂点$n$から、頂点$m_1, m_2, \dots, m_k \ (n \neq m_i)$へ辺が貼られているとします。
このとき、$m_1, m_2, \dots, m_k$へ、頂点$n$の持っている確率$p(n)$を$p(n) / k$ずつ分配します。
そして頂点$n$の持っている確率を$0$とします。&lt;/p>
&lt;p>最終的に得られる$p(n)$が、欲しい確率となります。&lt;/p>
&lt;p>気持ちとしては、「$X$からはじめて、$i$回操作後に$n$にいる確率」$p_i(n)$を、漸化式で考えるとわかります。
上記の画像の例から一部頂点を抜粋して書くと、&lt;/p>
&lt;p>$$
p_{i+1}(3) = \frac{1}{2} ( p_{i}(8) + p_{i}(3)),
$$
$$
p_{i+1}(0) = p_{i}(0) + \frac{1}{2} (p_{i}(3) + p_{i}(5) + p_{i}(6)),
$$&lt;/p>
&lt;p>となります。
グラフがDAG + 自己ループの形をしているため、最終的には頂点$0$のような「他頂点へ辺が向かっていない頂点」へ確率が溜まっていくわけです。
それを計算しています。&lt;/p>
&lt;h2 id="さいごに">さいごに&lt;/h2>
&lt;p>以上を用いて、atcoder::modint1000000007 で以下を計算して出力します。&lt;/p>
&lt;p>$$
N! \cdot \sum_{x \in \{0, 1, \dots, X\}} x \cdot p(x).
$$&lt;/p>
&lt;p>計算量は$O(NX)$で想定解と同じです。&lt;/p>
&lt;p>&lt;a href="https://atcoder.jp/contests/exawizards2019/submissions/32874061">ソースコードはこちら（提出 #32874061）&lt;/a>&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/categories/kyopro/">kyopro</category></item><item><title>リモートマシン上にお手軽インスタンスを立ち上げて、ハッピー開発ライフ</title><link>https://nu50218.dev/posts/ssh-remote-multipass-instance/</link><guid isPermaLink="true">https://nu50218.dev/posts/ssh-remote-multipass-instance/</guid><pubDate>Mon, 25 Apr 2022 11:20:25 +0000</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>ついにM1 Macに乗り換えました。
しかし毎回darwin/arm64向けの何かを気にするのが大変です。
ということで、この機会にお家のamd64マシンを開発用に使うことにしました。&lt;/p>
&lt;h2 id="はじめに">はじめに&lt;/h2>
&lt;p>多分M1は関係ありません。&lt;/p>
&lt;p>そして解説記事ではなく備忘録なものなので、わかりにくいかもしれません。&lt;/p>
&lt;h2 id="リモートマシンについて">リモートマシンについて&lt;/h2>
&lt;p>お家にあるamd64マシンは、M75q-1 Tinyというlenovoから出ている小さいデスクトップPCです。
新品実質3万円ぐらいという激安で購入できた時期があり、既に2年ぐらい自宅サーバーとして使い倒しています。
&lt;a href="https://nu50218.dev/posts/m5atom-co2-mqtt/">部屋のCO2濃度をモニタリングしてくれたり&lt;/a>もしています。
スペックはこんな感じで、愛をこめて&lt;strong>tiny&lt;/strong>という名前をつけています。&lt;/p>
&lt;ul>
&lt;li>OS: Ubuntu 20.04&lt;/li>
&lt;li>CPU: AMD Ryzen 5 PRO 3400GE&lt;/li>
&lt;li>メモリ: 16GB&lt;/li>
&lt;li>SSD 128GB(多分)&lt;/li>
&lt;/ul>
&lt;h2 id="やりたかったこと">やりたかったこと&lt;/h2>
&lt;p>VSCodeに&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers">Remote - Containers&lt;/a>という天才的な拡張機能が存在することをご存知でしょうか？
Dockerfileと設定のjsonを書くだけで、VSCodeのガワをそのままにコンテナの中で開発することができるやつです。&lt;/p>
&lt;p>このRemote - Containersが最近、更に便利になりました。
具体的には、リモートマシン上で動いているDockerデーモンをSSH経由で使うことができるようになりました。
つまり、M1 Macからtiny上で動くDockerデーモンを使うことで、「M1にも関わらずAMD64のCPU・イメージ上で開発」することができます。
これがやりたかったわけです。&lt;/p>
&lt;p>実はこれは、いわゆるIntel Macの時代からやりたいと思っていました。
以下の理由があります。&lt;/p>
&lt;ul>
&lt;li>Docker for Macが遅い&lt;/li>
&lt;li>クライアント端末の性能は何でもよくなる（極論Macbook Air最小構成）&lt;/li>
&lt;li>（つまり）M1に簡単に移行できる&lt;/li>
&lt;li>Remote - Containers on Remote Machineのワクワク感&lt;/li>
&lt;/ul>
&lt;h2 id="お手軽インスタンスを立ち上げる">お手軽インスタンスを立ち上げる&lt;/h2>
&lt;p>やりたかったことを達成するには、普通にtinyにDockerをインストールすればよい気がしますが、実は個人的な問題があります。
tinyでは常時自宅サーバーが動いています。
以前このようなことを試したとき、開発中にメモリとCPUを食べすぎて、自宅サーバー用のリソースが足りなくなりました。
なので、CPUとメモリを制限したVMをtinyの中に立ち上げて、開発用マシンとすることにしました。
実際、インスタンスを自由に作ったり壊したりできると嬉しい場面もありますし。&lt;/p>
&lt;p>こういう場合には、ESXiとかVirtualBoxを使うと思うんですが、それぞれ次の理由で却下されました。&lt;/p>
&lt;ul>
&lt;li>ESXi&lt;/li>
&lt;/ul>
&lt;p>それだけのために使うのは仰々しいような…&lt;/p>
&lt;p>メモリ足りなそう&lt;/p>
&lt;p>ネットワーク関係が面倒そう&lt;/p>
&lt;ul>
&lt;li>VirtualBox&lt;/li>
&lt;/ul>
&lt;p>何故か壊れました&lt;/p>
&lt;p>そんなときに颯爽と現れたのが、&lt;a href="https://multipass.run">&lt;strong>Multipass&lt;/strong>&lt;/a>です。
MultipassはVirtualBoxと違って動きました。
このようにCLIで簡単にインスタンスを作成/削除できます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">multipass launch --name ubuntu --mem 4G --disk 20G --cpus &lt;span class="m">4&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">multipass delete ubuntu
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>（ubuntuという名前で、メモリ4GB、ディスク20GB、4 vCPUのインスタンスを作成しています。デフォルトでUbuntu 20.04のイメージになります。）&lt;/p>
&lt;p>そして、このようにホストからアクセスできるプライベートIPアドレスを振ってくれます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">$ multipass info ubuntu
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Name: ubuntu
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">State: Running
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">IPv4: 10.138.112.156
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 172.17.0.1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Release: Ubuntu 20.04.4 LTS
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Image hash: c33e4d8f8fd5 &lt;span class="o">(&lt;/span>Ubuntu 20.04 LTS&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Load: 0.08 0.15 0.14
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Disk usage: 7.6G out of 19.2G
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Memory usage: 1.0G out of 3.8G
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Mounts: --
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="立ち上げたインスタンスのセットアップ">立ち上げたインスタンスのセットアップ&lt;/h2>
&lt;p>ということで、tinyにインスタンスを立ち上げることができました。
あとは立ち上げたインスタンスにDockerを入れて、SSHの公開鍵を追加すれば、使われる準備万端です。&lt;/p>
&lt;p>インスタンス内のシェルに入ります。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">multipass shell ubuntu
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Docker公式の便利スクリプトでDockerをインストールします。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">curl -fsSL https://get.docker.com -o get-docker.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">sudo sh get-docker.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dockerをrootless modeにするためにいくつかコマンドを実行します。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">sudo apt-get install -y uidmap
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">dockerd-rootless-setuptool.sh install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;export PATH=/usr/bin:&lt;/span>&lt;span class="nv">$PATH&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &amp;gt;&amp;gt; ~/.bashrc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;export DOCKER_HOST=unix:///run/user/1000/docker.sock&amp;#34;&lt;/span> &amp;gt;&amp;gt; ~/.bashrc
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>SSHクライアントの公開鍵を&lt;code>~/.ssh/authorized_keys&lt;/code>に追加します。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">vim ~/.ssh/authorized_keys
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="多段sshの設定">多段SSHの設定&lt;/h2>
&lt;p>あとはM1 Macから、立ち上げたインスタンスにSSH接続できるようにします。&lt;/p>
&lt;p>立ち上げたインスタンスは、ホストOSからしか接続できないネットワークにいます。
つまり、 &lt;code>10.138.112.156&lt;/code> はtinyで動いているホストOSからのみアクセスできます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">$ multipass info ubuntu
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">（中略）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">IPv4: 10.138.112.156
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 172.17.0.1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>したがって、tinyで動くUbuntuを踏み台にしてSSHをします。
次のような &lt;code>~/.ssh/config&lt;/code> を書いています。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-txt" data-lang="txt">&lt;span class="line">&lt;span class="cl">Host tiny.local
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> （tiny接続情報）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Host ubuntu.tiny.local
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> HostName 10.138.112.156
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> User ubuntu
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Port 22
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> UseKeychain yes
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> IdentityFile ~/.ssh/id_rsa_ubuntu
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ProxyJump tiny.local
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>最後の &lt;code>ProxyJump&lt;/code> を使うだけでほぼOKです。
これにより、次のコマンドで立てたインスタンスにSSH接続できるようになりました。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">ssh ubuntu.tiny.local
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="やりたかったことをやる">やりたかったことをやる&lt;/h2>
&lt;p>実際に立てたインスタンス上でRemote - Containersをやりたいときは、次の手順を踏みます。&lt;/p>
&lt;ol>
&lt;li>&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh">Remote - SSH&lt;/a>で立てたインスタンスに接続する。&lt;/li>
&lt;li>作業したいリポジトリ・ディレクトリを開く。&lt;/li>
&lt;li>コマンドパレット（Command + Shift + P）を開いて、&lt;code>Remote-Containers: Open Folder in Container&lt;/code> を選択&lt;/li>
&lt;/ol>
&lt;h2 id="あとがき">あとがき&lt;/h2>
&lt;p>実はこの記事も、立てたインスタンス上で動く（Hugoのイメージの）コンテナ上で、書きました。
天才的なことにポートフォワーディングもよしなにやってくれます。
コンテナ内で &lt;code>hugo serve&lt;/code> してもM1 Macの方の &lt;code>localhost:1313&lt;/code> からプレビューが見れます。
とても素晴らしい体験で、ハッピー開発ライフを送っていけそうな気がしています。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category></item><item><title>MagSafeバッテリーパックは評判より良い製品です！！</title><link>https://nu50218.dev/posts/magsafe-battery-pack/</link><guid isPermaLink="true">https://nu50218.dev/posts/magsafe-battery-pack/</guid><pubDate>Fri, 28 Jan 2022 23:48:57 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>MagSafeバッテリーパックは良くない方に誤解されて、もはや信者向けアイテムと思われています。
購入して使ってる自分からすると、そんなほどでもないよというお話です。&lt;/p>
&lt;h2 id="値段について">値段について&lt;/h2>
&lt;p>&lt;a href="https://www.apple.com/jp/shop/product/MJWY3ZA/A/magsafe%E3%83%90%E3%83%83%E3%83%86%E3%83%AA%E3%83%BC%E3%83%91%E3%83%83%E3%82%AF">MagSafeバッテリーパック - Apple（日本）&lt;/a>&lt;/p>
&lt;blockquote>
&lt;p>3,933円/月月額、3回払い&lt;/p>
&lt;p>または&lt;/p>
&lt;p>11,800円（税込）&lt;/p>
&lt;/blockquote>
&lt;p>信者向けと呼ばれている主な理由の1つがその値段です。
Ankerやmophie、belkinも同様のマグネットでくっついてワイヤレス充電するモバイルバッテリーを販売していますが、3000円〜4000円程度です。&lt;/p>
&lt;p>どうして倍以上の値段になるんでしょうか？
Apple税で値段が倍以上になっていると思われがちですが、実は「MagSafe」と「MagSafe互換」という本質的な違いがあります。&lt;/p>
&lt;h2 id="magsafeとmagsafe互換">MagSafeと、MagSafe互換&lt;/h2>
&lt;p>MagSafeはご存知の通り、マグネットで位置を固定して最大15Wで充電できる規格です。
MagSafeバッテリーパックは、当然MagSafeでiPhoneを充電します。&lt;/p>
&lt;p>それはそう、と思われるかもしれませんが、実は他社の「マグネットでくっついてワイヤレス充電するモバイルバッテリー」は、マグネットで位置を固定してQi(最大7.5W)で充電しています。&lt;/p>
&lt;p>たとえばAnkerのものは、Magineticとか、マグネット式ワイヤレス充電とか微妙な言い方をしていて、MagSafeで充電とは言っていません。&lt;/p>
&lt;blockquote>
&lt;p>Anker PowerCore Magnetic 5000&lt;/p>
&lt;p>マグネット式ワイヤレス充電対応
ワイヤレス充電の欠点をマグネットにより解決しました。&lt;/p>
&lt;p>&lt;a href="https://www.ankerjapan.com/products/a1619">https://www.ankerjapan.com/products/a1619&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>MagSafeバッテリーパックは電源につないだ状態だとMagSadeで最大15WでiPhoneを充電します。
それに対して他のものは最大7.5Wでしか充電できません。&lt;/p>
&lt;p>さらにMagSafeはNFCでiPhoneと通信できる機能があります。
これによりMagSafeバッテリーパックをiPhoneにくっつけたときに、iPhone側にバッテリー残量が表示されたり、バッテリーパック側のファームウェアがアップデートされたりします。&lt;/p>
&lt;p>つまり、そもそもMagSafeバッテリーパックと、他社の似た製品は、本質的に機能が違うわけです。
しかしこれがあまり理解されておらず、後述する出力や容量だけを比較して、高くて性能が低い信者向けアイテムだと誤解してしまうわけです。&lt;/p>
&lt;h2 id="性能について">性能について&lt;/h2>
&lt;p>まず出力についてです。
上述のように、他社のものはQiで充電するので出力は最大7.5Wです。
5Wだったり、7.5Wだったりします。
これに比べてMagSafeバッテリーパックは、&lt;strong>電源につないでいないときは&lt;/strong>5Wです。
ただ電源につなぐと最大15Wで充電できます。
後者もあまり知られておらず、5Wという情報だけ広まって信者向けと言われる一因の一つになっている気がします。&lt;/p>
&lt;p>次に容量についてですが、これがとても誤解されています。
たとえばAnkerのPowerCore Magnetic 5000は名前の通り5000mAhあります。
これに対してMagSafeバッテリーパックは1460mAhです。
容量に3倍以上の差があるように見えてしまうんですが、実は電圧が倍違う罠があります。
Ankerの方に電圧を揃えると2920mAhとなってだいぶ印象がかわります。
(WhじゃなくてmAhで書く風習をやめてほしい…)&lt;/p>
&lt;p>&lt;a href="https://kiritsume.com/magsafe-battery-pack-has-bigger-capacity-than-it-looks/">参考: AppleのMagSafeバッテリーパックは2倍の容量がある話&lt;/a>&lt;/p>
&lt;h2 id="よく見るツイート">よく見るツイート&lt;/h2>
&lt;p>これらを複合すると、こんな感じの悪く誤解された信者向けアイテム認定ツイートが出来上がります。&lt;/p>
&lt;blockquote>
&lt;p>AppleのMagSafeバッテリーパック、出力5Wだし容量1460mAhしかないのに1万円以上するのかよwwwww&lt;/p>
&lt;p>Ankerの622 Magnetic Battery (MagGo)は7.5Wで5000mAhで6000円弱だぞ&lt;/p>
&lt;p>信者のお布施用じゃん&lt;/p>
&lt;/blockquote>
&lt;p>悲しい。&lt;/p>
&lt;h2 id="実際使ってみてどうなの">実際使ってみてどうなの&lt;/h2>
&lt;p>悲しいことに僕はApple信者なので信者向けかどうかはもはやわかりません。
ただ、値段に目を瞑れば、個人的にはiPhone 12 miniと使うにはとてもいい製品だと感じています。&lt;/p>
&lt;p>もともと僕がMagSafeバッテリーパックを購入した理由は、iPhoneのバッテリーを1日持たせたかったからです。
結構ヘビーに使うので、iPhone 12 mini単体だと6〜8時間ぐらいでバッテリー残量がなくなってしまいます。
これはもちろんMagSafeバッテリーパックによって解決しました。
ただ、いい製品と感じているポイントはむしろデザインと15W充電にあります。&lt;/p>
&lt;p>まずデザインの話です。
iPhone 12 miniにくっつけて使うと、完全に寸法が一致していて一体化します。
モバイルバッテリーをくっつけている感じというよりむしろ、丸みを帯びて持ちやすくなったとすら感じます。
これが何が嬉しいかというと、MagSafeバッテリーパック自体の軽さもあって、外出時常につけて使えます。
バッテリーをつけたときに持ちにくいと、結局使うときは外して、使わないときにくっつけて充電するという感じになってしまいます。
外出時常につけて使うことで、バッテリー残量を意識するストレスが完全に消えます。
常に充電するなら、iPhone 12 miniなら5Wでも十分です。
この体験がとてもよくいい製品と感じているポイントの1つ目です。&lt;/p>
&lt;p>そして15W充電です。
Qiのワイヤレス充電器を使ったことがあるならわかると思いますが、7.5WはiPhoneの充電にはイライラするほど遅いです。
結局有線で充電してしまいます。
しかし、MagSafeバッテリーパックは電源につなぐことで最大15WのMagSafe充電器になります。
この速度はイライラしません！！
ということでiPhoneのlightning端子に何も挿すことなく、実質的にケーブルレスで生活することができます。
ケーブルレス生活も体験がよく、これがいい製品と感じているポイントのもう片方です。
(ちなみにiPhone 12/13 miniは最大12Wです…)&lt;/p>
&lt;p>ただ、こうなればもっと嬉しいという部分もあります。
バッテリーパックにlightningケーブルを挿さなきゃいけないところです。
USB-Cにしろといっているわけではなく、MagSafeバッテリーパック自体もMagSafeで充電したいということです。
それができれば、MagSafeバッテリーパックの背面にMOFTのマグネットスタンドをつけたり、最近入手したBelkinの3-in-1の充電スタンドにMagSafeバッテリーパックごとくっつけたりできるのになと思っています。
新型MagSafeバッテリーパックがそれになったら即買います。&lt;/p>
&lt;h2 id="最後に">最後に&lt;/h2>
&lt;p>MagSafeバッテリーパック、評判よりいい製品なので、みんな買ってほしいです…。
Appleは2週間返品無料なので、とりあえず他社のものを買う前に返品ありきで買ってみてお試ししても損はしないです。
僕はそれで無事購入してしまいました。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/magsafe/">magsafe</category></item><item><title>popin aladdinでDisney+を見る方法</title><link>https://nu50218.dev/posts/popin-aladdin-disneyplus/</link><guid isPermaLink="true">https://nu50218.dev/posts/popin-aladdin-disneyplus/</guid><pubDate>Sun, 28 Nov 2021 20:59:06 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>Macの画面をAirPlayして、Chromeで再生すれば見れます！！！&lt;/p>
&lt;p>AndroidスマホでDisney+アプリから直接キャストしても見れます。&lt;/p>
&lt;p>あとAladdin ConnectorとFireTV Stickで頑張るとか。&lt;/p>
&lt;p>なんでiPhoneとかMacのSafariだと再生できないんだろう😢&lt;/p></description></item><item><title>競プロは役に立つのか？に対する自分の答え</title><link>https://nu50218.dev/posts/comp-prog-business/</link><guid isPermaLink="true">https://nu50218.dev/posts/comp-prog-business/</guid><pubDate>Sun, 14 Nov 2021 21:33:56 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>定期的に競技プログラミングが役に立つ/立たないの話が盛り上がります。&lt;/p>
&lt;p>数年間IT企業でアルバイトして、なんとなく自分の中で答えが出たというか、ソフトウェアエンジニアの中での「自分の強み」みたいなのがわかってきました。&lt;/p>
&lt;h2 id="前提">前提&lt;/h2>
&lt;p>まず、一般的な話ではなくて、あくまで個人の話として読んでください。&lt;/p>
&lt;p>そして、ここでいうソフトウェアエンジニアは、&lt;a href="https://www.optimind.tech">配送計画&lt;/a>とか&lt;a href="https://www.asprova.jp">工場のスケジューリング&lt;/a>とか明らかに役に立ちそうな分野ではなく、一般の(？)ソフトウェアエンジニアを指しています。&lt;/p>
&lt;h2 id="自分の話">自分の話&lt;/h2>
&lt;p>まず自分の話をしないと意味不明だと思うので、競プロ関連の歴を書きます。&lt;/p>
&lt;p>3年前ぐらいにAtCoderを初めて、8ヶ月ぐらいで青になって、1年半ぐらいで黄色までいきました。&lt;/p>
&lt;p>そして青になったぐらいのタイミングで、競プロじゃないプログラミング(いわゆる業務プログラミング)を学びたいと思って、IT企業のアルバイトに応募して数年間働いてきました。&lt;/p>
&lt;p>&lt;img src="https://nu50218.dev/images/comp-prog-business-rating.png" alt="comp-prog-business-rating.png">&lt;/p>
&lt;p>&lt;a href="https://atcoder.jp/users/nu50218">https://atcoder.jp/users/nu50218&lt;/a>&lt;/p>
&lt;p>画像からわかると思いますが、黄色になってすぐ青に戻り、黄色という目標が消えたのでモチベが下がって2年ぐらい隠居状態になっています。&lt;/p>
&lt;p>ただ、2021/11のICPC国内予選を突破できたぐらいには、まだ能力があります。&lt;/p>
&lt;p>また、最近は大学でもアルゴリズムの研究室に入って研究してるので、そういう意味では完全に離れたわけではないです。&lt;/p>
&lt;h2 id="よくある競プロのメリット">よくある競プロのメリット&lt;/h2>
&lt;p>こんな感じのメリットをよく見かけます。&lt;/p>
&lt;ul>
&lt;li>
&lt;p>実装がはやい&lt;/p>
&lt;/li>
&lt;li>
&lt;p>正確に実装できる&lt;/p>
&lt;/li>
&lt;li>
&lt;p>計算量を意識しながらコードが書ける&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>たしかにそうなんですが、これらは個人的には本質的じゃないように思います。&lt;/p>
&lt;p>本質的というのは、競プロをやっている人が、そうでない人に比べて明確に差があることを指しています。&lt;/p>
&lt;p>というのも、競プロやってないけど結構プログラム書ける人がLeetCodeでちょっと練習すれば、これらは必要なレベルまで行けそうな気がしているためです。&lt;/p>
&lt;p>上2つは言うまでもなくという感じで、計算量を意識するというのも、実際には二分探索ぐらいのレベルまで理解していれば大抵の場面で十分だと感じています。&lt;/p>
&lt;h2 id="自分の強み">自分の強み&lt;/h2>
&lt;p>競プロによる自分の強みは、一言で表すと「現実を数理モデルで見ることができる」ことにあると思っています。&lt;/p>
&lt;p>ソフトウェアエンジニアの基本は「問題解決」です。&lt;/p>
&lt;p>なにか解決したい現実の問題があって、それをソフトウェアを通して解決します。&lt;/p>
&lt;p>その中で「数理モデルにして最適化する」という選択肢が自然にあって、すぐに数理モデルとして定式化でき、解けそうかどうか直感でなんとなくわかります。&lt;/p>
&lt;p>さっき考えた具体例を出して説明します。&lt;/p>
&lt;blockquote>
&lt;p>あるカフェでは、淹れてもらうコーヒー豆を選べるのですが、それぞれ合うフードを店員が暗記し、レジでオススメしていました。
しかし新しい豆が入荷したり、新しいフードが登場したりするたびに店員の暗記が必要で、困っていました。
これを解決するシステムを依頼された私は、客の選んだ豆をレジに入力したら、登録しておいた対応するオススメのフードが画面に表示されるようにしました。&lt;/p>
&lt;p>好評だったので、次の仕事として、もっと売上を増やせそうなオススメシステムに改良することを依頼されました。
どのような改良をしましょうか？&lt;/p>
&lt;/blockquote>
&lt;p>いくつもアイデアがあると思います。&lt;/p>
&lt;p>たとえば、ポイントカードがあれば、過去の履歴を見てフード2つ買ってくれるような人には2つオススメするとか。&lt;/p>
&lt;p>ポイントカードの履歴を使って機械学習で作った推薦モデルからオススメするとか。&lt;/p>
&lt;p>同じフードばかり売って品切れが起きるとその後フードの購入率が下がって売上が下がるので、オススメ上位3つを表示するようにして、店員がバランス良く売るとか。&lt;/p>
&lt;p>ここで数理モデルとして見てみると、たとえばこんな感じにできたりします。&lt;/p>
&lt;blockquote>
&lt;p>売上の期待値を最大化したい。&lt;/p>
&lt;p>次のことがわかっている。&lt;/p>
&lt;ul>
&lt;li>今日用意されるフードの種類とそれぞれの数&lt;/li>
&lt;li>今日の来店者数と、注文する豆の割合の予測&lt;/li>
&lt;li>ある豆に対してあるフードをオススメしたときの購入率&lt;/li>
&lt;/ul>
&lt;/blockquote>
&lt;p>そして「ある豆に対してあるフードをオススメする確率を決定変数にして線形計画法を適用」という感じで解けそうです。&lt;/p>
&lt;p>(具体例終わり)&lt;/p>
&lt;p>こんな感じで「数理モデルにして最適化する」という選択肢が自然に増えます。&lt;/p>
&lt;p>業務プログラミングだと、「最適化問題があるので、最適化してください」みたいな形をしていない問題ばっかりです。&lt;/p>
&lt;p>競プロだったり数理最適化で訓練してる人でないと自然な選択肢として出てこないですし、定式化もなかなかできないと思います。&lt;/p>
&lt;p>競プロは問題に設定がついているので、知らぬ間に現実の問題とそれに対応する数理モデルが脳に学習されています。&lt;/p>
&lt;p>競プロが「仕様(入出力)が与えられるので、高速なプログラムを早く正確に書く」という構造なので、それに引っ張られたメリットが挙げられがちなんですが、実は逆で、こっちのほうが結構本質的な違いかなと思っています。&lt;/p>
&lt;h2 id="競プロは役に立つのかに対する自分の答え">競プロは役に立つのか？に対する自分の答え&lt;/h2>
&lt;p>まず決まったプログラムを書く際に役に立つことは基本ないです。&lt;/p>
&lt;p>しかし「数理モデルにして最適化」のレイヤーで役に立つ可能性はあって、個人としては競プロは役に立っています。&lt;/p>
&lt;p>なんですが、競プロをやっているだけで身につく能力でもないと思います。&lt;/p>
&lt;p>結局、一般的に競プロが業務の役に立つかは微妙なところで、その人次第かなというところに考えは落ち着きました。&lt;/p></description><category domain="https://nu50218.dev/categories/kyopro/">kyopro</category></item><item><title>ロボット掃除機にケーブル噛まれる問題の対処</title><link>https://nu50218.dev/posts/robot-vacuum-cable-problem/</link><guid isPermaLink="true">https://nu50218.dev/posts/robot-vacuum-cable-problem/</guid><pubDate>Tue, 09 Nov 2021 20:35:59 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>ロボット掃除機は便利ですが、床に転がったケーブル(延長コードやLANケーブル)を噛んでしまうという問題があります。&lt;/p>
&lt;p>最悪ケースだと、ケーブルを噛んだまま移動して、ケーブルをつないでいた機器を引っ張って落下させるときもあります。&lt;/p>
&lt;p>調べていくなかで見つけたいくつかの対処法を共有します。&lt;/p>
&lt;p>ちなみに僕は数ヶ月前にスパイラルチューブで床のケーブルを全部巻いて、それから噛まれていません。&lt;/p>
&lt;h2 id="スパイラルチューブ">スパイラルチューブ&lt;/h2>
&lt;p>ケーブルが噛まれるのは、噛めるぐらい細いためです。&lt;/p>
&lt;p>そして、高さがないため障害物として認識されずケーブルの上を通り、噛んでしまいます。&lt;/p>
&lt;p>この方向からの解決策として、スパイラルチューブがあります。&lt;/p>
&lt;p>スパイラルチューブはケーブルをまとめて保護するチューブです。&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/jC15IgoZeDs" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>サイズがいくつかあるのですが、とりあえず太いやつを買えばOKだと思います。&lt;/p>
&lt;p>&lt;strong>メリット&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>安い&lt;/li>
&lt;li>チューブに通して床に置くだけ&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>デメリット&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>見栄えは微妙&lt;/li>
&lt;li>チューブをケーブルに巻くのがひたすらダルい&lt;/li>
&lt;li>新しいケーブルを通すのがひたすらダルい&lt;/li>
&lt;li>既存のケーブルをとるのがひたすらダルい&lt;/li>
&lt;/ul>
&lt;p>ちなみに、ケーブルを巻くのがダルい人向け(プロ用？)に、「ヘララップ」というスパイラルじゃないチューブがあります。&lt;/p>
&lt;p>ただこちらは個人向けに売っていないので、ちょっと入手がめんどくさいです。&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/WgZ-xcS97Iw" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;h2 id="ケーブルモール">ケーブルモール&lt;/h2>
&lt;p>皆さんご存知、壁に貼るやつです。&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/YkVvbHKbgLc" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>ケーブルモールは床にケーブルを置かないことで、ロボット掃除機が噛むのを阻止します。&lt;/p>
&lt;p>これが一番、難易度と見た目のバランスが良いと思います。&lt;/p>
&lt;p>&lt;strong>メリット&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>安い&lt;/li>
&lt;li>見栄えがいい&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>デメリット&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>適当な長さにカットしたり、曲がり角をきれいにするのが面倒&lt;/li>
&lt;li>(賃貸とかだと)シール跡が残る問題&lt;/li>
&lt;/ul>
&lt;h2 id="oaフロア">OAフロア&lt;/h2>
&lt;p>ガチ勢向け。オフィスフロア/フリーアクセスフロア/&lt;/p>
&lt;p>床の上に「ケーブルが通る床」を敷き詰めてそこにケーブルを通します。&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/jx9GQxzw4sg" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>&lt;strong>メリット&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>他の用途にも色々使えそう&lt;/li>
&lt;li>すごい&lt;/li>
&lt;li>えらい&lt;/li>
&lt;li>つよい&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>デメリット&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>高そう&lt;/li>
&lt;li>施工大変そう&lt;/li>
&lt;/ul>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/1Pbi9QSzAwI" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div></description></item><item><title>藤が丘周辺の個人的オシャレなお店</title><link>https://nu50218.dev/posts/fujigaoka/</link><guid isPermaLink="true">https://nu50218.dev/posts/fujigaoka/</guid><pubDate>Mon, 27 Sep 2021 09:52:14 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>今回は、名古屋市藤が丘駅周辺のオシャレなお店を紹介しようと思います。&lt;/p>
&lt;h2 id="はじめに">はじめに&lt;/h2>
&lt;p>この地域、ネットで調べてもなかなか情報が出てきません。&lt;/p>
&lt;p>なので逆に、近くに住んでいる僕がお気に入りの店を紹介する記事です。&lt;/p>
&lt;p>稀に更新されます。&lt;/p>
&lt;h2 id="オシャレなお店たち">オシャレなお店たち&lt;/h2>
&lt;h3 id="tori8coffee">tori8coffee&lt;/h3>
&lt;p>お気に入りのカフェです。&lt;/p>
&lt;p>アイスの飲み物が&lt;a href="https://www.iittala.jp/products/list.php?category_id=30">iittalaのlempi&lt;/a>っていうグラスで出されて可愛いです。&lt;/p>
&lt;blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/CSk9wAqlm-B/?utm_source=ig_embed&amp;amp;utm_campaign=loading" data-instgrm-version="13" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);">&lt;div style="padding:16px;"> &lt;a href="https://www.instagram.com/p/CSk9wAqlm-B/?utm_source=ig_embed&amp;amp;utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> &lt;div style=" display: flex; flex-direction: row; align-items: center;"> &lt;div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;">&lt;/div> &lt;div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;">&lt;/div> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;">&lt;/div>&lt;/div>&lt;/div>&lt;div style="padding: 19% 0;">&lt;/div> &lt;div style="display:block; height:50px; margin:0 auto 12px; width:50px;">&lt;svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink">&lt;g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">&lt;g transform="translate(-511.000000, -20.000000)" fill="#000000">&lt;g>&lt;path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631">&lt;/path>&lt;/g>&lt;/g>&lt;/g>&lt;/svg>&lt;/div>&lt;div style="padding-top: 8px;"> &lt;div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram&lt;/div>&lt;/div>&lt;div style="padding: 12.5% 0;">&lt;/div> &lt;div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;">&lt;div> &lt;div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);">&lt;/div> &lt;div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;">&lt;/div> &lt;div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);">&lt;/div>&lt;/div>&lt;div style="margin-left: 8px;"> &lt;div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;">&lt;/div> &lt;div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)">&lt;/div>&lt;/div>&lt;div style="margin-left: auto;"> &lt;div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);">&lt;/div> &lt;div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);">&lt;/div> &lt;div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);">&lt;/div>&lt;/div>&lt;/div> &lt;div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;">&lt;/div> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;">&lt;/div>&lt;/div>&lt;/a>&lt;p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">&lt;a href="https://www.instagram.com/p/CSk9wAqlm-B/?utm_source=ig_embed&amp;amp;utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by tori8coffee藤が丘 (@tori8coffee)&lt;/a>&lt;/p>&lt;/div>&lt;/blockquote> &lt;script async src="https://nu50218.dev//www.instagram.com/embed.js">&lt;/script>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://tori8coffee.com">公式ホームページ&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://www.nissho-apn.co.jp/area/nagoya/1196704_1646.html">名古屋市名東区にある「tori8coffee（トリハチコーヒー）」はハンドドリップの淹れたてスペシャルティコーヒーがいただける落ち着いたカフェです。&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h3 id="珈琲豆ストア-コモン">珈琲豆ストア コモン&lt;/h3>
&lt;p>外観が特徴的なコーヒー豆を売っているお店。&lt;/p>
&lt;p>自転車を止めて中へ入るまでのコーヒーの香りが大好き。&lt;/p>
&lt;blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/B7PYACZFa8h/?utm_source=ig_embed&amp;amp;utm_campaign=loading" data-instgrm-version="13" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);">&lt;div style="padding:16px;"> &lt;a href="https://www.instagram.com/p/B7PYACZFa8h/?utm_source=ig_embed&amp;amp;utm_campaign=loading" style=" background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;" target="_blank"> &lt;div style=" display: flex; flex-direction: row; align-items: center;"> &lt;div style="background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;">&lt;/div> &lt;div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center;"> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;">&lt;/div> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;">&lt;/div>&lt;/div>&lt;/div>&lt;div style="padding: 19% 0;">&lt;/div> &lt;div style="display:block; height:50px; margin:0 auto 12px; width:50px;">&lt;svg width="50px" height="50px" viewBox="0 0 60 60" version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink">&lt;g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">&lt;g transform="translate(-511.000000, -20.000000)" fill="#000000">&lt;g>&lt;path d="M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631">&lt;/path>&lt;/g>&lt;/g>&lt;/g>&lt;/svg>&lt;/div>&lt;div style="padding-top: 8px;"> &lt;div style=" color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;"> View this post on Instagram&lt;/div>&lt;/div>&lt;div style="padding: 12.5% 0;">&lt;/div> &lt;div style="display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;">&lt;div> &lt;div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);">&lt;/div> &lt;div style="background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;">&lt;/div> &lt;div style="background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);">&lt;/div>&lt;/div>&lt;div style="margin-left: 8px;"> &lt;div style=" background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;">&lt;/div> &lt;div style=" width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)">&lt;/div>&lt;/div>&lt;div style="margin-left: auto;"> &lt;div style=" width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);">&lt;/div> &lt;div style=" background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);">&lt;/div> &lt;div style=" width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);">&lt;/div>&lt;/div>&lt;/div> &lt;div style="display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;"> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;">&lt;/div> &lt;div style=" background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;">&lt;/div>&lt;/div>&lt;/a>&lt;p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">&lt;a href="https://www.instagram.com/p/B7PYACZFa8h/?utm_source=ig_embed&amp;amp;utm_campaign=loading" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;" target="_blank">A post shared by 珈琲豆ストア　コモン (@common.2013)&lt;/a>&lt;/p>&lt;/div>&lt;/blockquote> &lt;script async src="https://nu50218.dev//www.instagram.com/embed.js">&lt;/script>
&lt;ul>
&lt;li>&lt;a href="https://www.common-coffee.com/about.html">公式ホームページ&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="quattro-bar-m4">QUATTRO BAR M4.&lt;/h3>
&lt;p>高架下のちょっと狭めのイタリアン。&lt;/p>
&lt;p>ランチが1000円で前菜とパスタとパン＆オリーブオイルが出てきてスゴイ。たしか+500円ぐらい課金するとデカイ肉料理とデザートが出てきてヤバい。&lt;/p>
&lt;p>ただコスパが良いとかそういうことではなくて、出てくる品も一般人にはできないレベルでメチャクチャ美味しい。&lt;/p>
&lt;h2 id="オシャレというわけでもないけどおすすめのお店">オシャレというわけでもないけどおすすめのお店&lt;/h2>
&lt;h3 id="とんかつ-八千代西店-藤ケ丘店">とんかつ 八千代西店 藤ケ丘店&lt;/h3>
&lt;p>名古屋市に限りなく近い長久手市にあるとんかつ屋さん。&lt;/p>
&lt;p>平常時は1500円〜ぐらいのお高めだけど、ランチはカツ丼580円(税込)からあるのでランチがおすすめ。
しかもビックリ、味噌汁と漬物と一品もついてきます。&lt;/p></description></item><item><title>論文書いてたら適応障害になってた</title><link>https://nu50218.dev/posts/paper-adjustment/</link><guid isPermaLink="true">https://nu50218.dev/posts/paper-adjustment/</guid><pubDate>Fri, 10 Sep 2021 13:29:56 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>結論：ちょっとでもメンタルがアレな気がしたら自己判断せずに精神科行こうね！&lt;/p>
&lt;h2 id="精神科行く前">精神科行く前&lt;/h2>
&lt;p>初の英語論文書くことが、はじめてのことだらけでストレスになっていた。
締切が一ヶ月後とかで焦りもあった。&lt;/p>
&lt;p>その結果バイトも論文もほぼ手をつけず(というか気力がなく)、ただ生きて焦る生活が続いていた。
深夜ずっと目が覚めていて4時ごろ寝て昼に起きるような生活をしていたし、定期的にお腹がストレスでキリキリしてた。&lt;/p>
&lt;p>実はプチ鬱病みたいなものだと思っていた。
大学もバイトもリモートで人と喋っていないのもあるのかなと思っていた。
4時頃寝ているのも怠惰だと思っていたけど、一ヶ月ぐらい続いてこれはどうやら異常だと思い始めた。
前に友人らと「早めの精神科」みたいなことを喋っていたのを思い出し精神科を予約。&lt;/p>
&lt;h2 id="精神科行った">精神科行った&lt;/h2>
&lt;p>まず臨床心理士とお話した。
臨床心理士という職業を名前しか知らなかったけれど、「現在の状態と、問題に感じていること」を上手く整理して聞いてくれた。
「…つまり諸々にやる気が起きて、睡眠が改善されればOKというわけですね」みたいなことを最後に言われて、できるエンジニアに通じるところがあるなと思った。&lt;/p>
&lt;p>臨床心理士の人が医師に状態を伝え、論文で慣れていないことによる適応障害ですねと言われた。
適応障害を場所とか環境に適応できない奴だと思っていたので、意外だった。&lt;/p>
&lt;blockquote>
&lt;p>実はプチ鬱病みたいなものだと思っていた。
(どうやらうつ病と適応障害は症状が似ているらしい。)
医師から睡眠薬とかセロトニン出る薬とか色々紹介されたけど、とりあえず睡眠薬だけでやっていくことに決めた。&lt;/p>
&lt;/blockquote>
&lt;p>あとで適応障害について調べたらほぼ症状が一致していた。&lt;/p>
&lt;h2 id="精神科行った後">精神科行った後&lt;/h2>
&lt;p>睡眠薬飲み始めた。
バイト先と大学の先生に適応障害らしいと伝え(少し前から匂わせてはいた)、ここ2日ぐらいお休みしている。&lt;/p>
&lt;p>市販薬じゃない睡眠薬の効果は半端なくて、もともとAM04:00~AM12:00ごろ寝ていたのが、二日間の実績はこんな感じ。&lt;/p>
&lt;ul>
&lt;li>PM12:00 ~ AM08:00&lt;/li>
&lt;li>PM12:00 ~ AM05:30(！？)&lt;/li>
&lt;/ul>
&lt;p>全体的に調子良さげ。
朝早く起きて食べる朝マックが尊い。&lt;/p>
&lt;h2 id="まとめ">まとめ&lt;/h2>
&lt;p>精神科行く前は怠惰とリモート疲れ、論文がただ慣れていないから大変で、全体的にうつ病っぽくなっていると精神を評価していた。
どうやら行ってみたら適応障害という名前がついていて、怠惰ではなさそうだし、うつ病とは違うものということがわかった。
そして解決への道すじも得た。&lt;/p>
&lt;p>やはり自分でメンタルどうにかしようとすると、症状の程度や原因を正しく捉えられないことが多い。&lt;/p>
&lt;p>&lt;strong>結論：ちょっとでもメンタルがアレな気がしたら自己判断せずに精神科行こうね！&lt;/strong>&lt;/p></description></item><item><title>SSHの仕組み</title><link>https://nu50218.dev/posts/ssh-how-it-works/</link><guid isPermaLink="true">https://nu50218.dev/posts/ssh-how-it-works/</guid><pubDate>Wed, 21 Jul 2021 17:14:25 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>SSHが内部的にどういう仕組みなのか知らず使っていたので調べてみました！&lt;/p>
&lt;p>どこか間違っていたらブログ下のメールよりお願いします🙇‍♂️&lt;/p>
&lt;h2 id="全体の流れ">全体の流れ&lt;/h2>
&lt;p>SSHはおおまかに、次のような流れで通信しています。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Diffie-Hellman鍵交換を用いてクライアントとサーバーしか知らない共通鍵Kを生成する。このとき同時にクライアントは正しいサーバーと通信していることも検証。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>共通鍵Kを用いて暗号化された通信経路Pを作る。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Pの上で、パスワードや公開鍵などの方法でサーバー側がクライアントを認証する。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Pの上で、shellやport-forwardなど好きなことを行う。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;h2 id="1-鍵交換サーバーの検証">1. 鍵交換＆サーバーの検証&lt;/h2>
&lt;p>Diffie-Hellman鍵交換とは、以下のようなお互いに共通鍵を得るプロトコルです。
アリスとボブが鍵交換するとき、通信経路上で盗聴される可能性があっても、最終的にアリスとボブのみ共通の鍵を知った状態になります。&lt;/p>
&lt;blockquote>
&lt;p>まず値の大きな素数$p$を用意する。また$g$を${\displaystyle ({\mathbb {Z} }/p{\mathbb {Z} })^{\ast }}$の生成元とする。この$g$と$p$は公開されているものとする。&lt;/p>
&lt;p>いまアリスとボブが通信を行うとする。このときアリスとボブはお互い自分だけの知る秘密の値 $a, b$ を選択する、この値は 0 以上 $p−2$ 以下の中からランダムに選ぶ。（ここで、ゼロや小さな値（$g^a &amp;lt; p$ となる $a$ 等）を選択すると安全性が損なわれるが、そのような確率は無視できるほど小さい。）
アリスは以下の値 $A$ を計算してそれをボブに送信する。&lt;/p>
&lt;p>$A=g^{a} \ {\bmod {p}}$&lt;/p>
&lt;p>ボブも同様に以下の値 B を計算してそれをアリスに送信する。&lt;/p>
&lt;p>$ B=g^{b} \ {\bmod {p}}$&lt;/p>
&lt;p>アリスは自分だけの知る秘密の値 a とボブから送られてきて受信した値 B から以下の値を計算する。&lt;/p>
&lt;p>$ K_{A}=B^{a} \ {\bmod {p}}$&lt;/p>
&lt;p>ボブも自分だけの知る秘密の値 b とアリスから送られてきて受信した値 A から以下の値を計算する。&lt;/p>
&lt;p>$ K_{B}=A^{b} \ {\bmod {p}}$&lt;/p>
&lt;p>このときアリスとボブが計算した $K_{A}$ と $K_{B}$ は&lt;/p>
&lt;p>$ K_{A}=K_{B}=g^{ab} \ {\bmod {p}}$&lt;/p>
&lt;p>となっていて一致するので、以後この値を共通鍵暗号方式の鍵$K$として使用する。&lt;/p>
&lt;p>&lt;a href="https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%95%E3%82%A3%E3%83%BC%E3%83%BB%E3%83%98%E3%83%AB%E3%83%9E%E3%83%B3%E9%8D%B5%E5%85%B1%E6%9C%89">wikipedia / ディフィー・ヘルマン鍵共有&lt;/a>より引用&lt;/p>
&lt;/blockquote>
&lt;p>Diffie-Hellman鍵交換はアリスとボブの通信経路上で鍵が盗聴されることはないですが、これは「アリスとボブが」通信していた場合に限ります。
というのは、第三者Cさんがどちらかになりすますことで中間者攻撃が可能です。&lt;/p>
&lt;p>具体的には、アリスとボブが鍵交換して暗号化された通信経路を作ろうとするときに、Cさんがアリスに対してはボブになりすまし、ボブに対してはアリスになりすますことで、A &amp;lt;-&amp;gt; C、C &amp;lt;-&amp;gt; Bの暗号化された通信経路を作ります。
アリスとボブはお互いにボブ、アリスと暗号化された(と思っている)経路で通信しますが、実際にはCさんが間に挟まって復号/暗号化しながら通信をリレーしているため、盗聴することができてしまいます。
詳しくは&lt;a href="https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%95%E3%82%A3%E3%83%BC%E3%83%BB%E3%83%98%E3%83%AB%E3%83%9E%E3%83%B3%E9%8D%B5%E5%85%B1%E6%9C%89#%E4%B8%AD%E9%96%93%E8%80%85%E6%94%BB%E6%92%83">wikipedia / ディフィー・ヘルマン鍵共有#中間者攻撃&lt;/a>を参照してください。&lt;/p>
&lt;p>このため、SSHではDiffie-Hellman鍵交換を行いながら同時に、サーバーの公開鍵/秘密鍵を用いてクライアントが正しいサーバーと通信しているか検証します。&lt;/p>
&lt;p>クライアントがアリス、サーバーがボブだとすると、サーバーはクライアントに対して$B (= g^{b} \ {\bmod {p}})$を送信します。&lt;/p>
&lt;p>このときに、サーバーがサーバーの秘密鍵で「サーバーの公開鍵と$B$」に&lt;a href="https://wikiwiki.jp/masami/TIPS/SSH#b5648848">電子署名して送信&lt;/a>することで、クライアントはサーバーの公開鍵を用いて署名を検証し、送ってきた相手が期待したサーバーと確信できます。&lt;/p>
&lt;p>またそのようにして得られた$K_{A} = (K_{B})$を用いて暗号化された通信経路で通信できれば、サーバーに対しても正しく$A$が送信できていることがわかり、中間者攻撃の問題は解決できます。&lt;/p>
&lt;p>サーバーから送られてきた「サーバーの公開鍵」が正しいことも検証する必要がありますが、それは&lt;code>~/.ssh/known_hosts&lt;/code>とマッチして確かめます。
マッチしないとき(大抵ssh初回アクセス時)は、&lt;/p>
&lt;pre tabindex="0">&lt;code>$ ssh 192.168.100.1
...
The authenticity of host &amp;#39;192.168.100.1 (192.168.100.1)&amp;#39; can&amp;#39;t be established.
RSA key fingerprint is h1:g2:3o:4e:h5:67:ho:ge:12:3f:5u:g8:a0.
Are you sure you want to continue connecting (yes/no)?
&lt;/code>&lt;/pre>&lt;p>みたいに聞かれて、yesと答えると&lt;code>~/.ssh/known_hosts&lt;/code>に追加されて接続されます(のでよくわからないけどyesはヤバい)。&lt;/p>
&lt;p>ちなみに実際にはDiffie-Hellman鍵交換ではない鍵交換、&lt;a href="https://ja.wikipedia.org/wiki/%E6%A5%95%E5%86%86%E6%9B%B2%E7%B7%9A%E3%83%87%E3%82%A3%E3%83%95%E3%82%A3%E3%83%BC%E3%83%BB%E3%83%98%E3%83%AB%E3%83%9E%E3%83%B3%E9%8D%B5%E5%85%B1%E6%9C%89">楕円曲線ディフィー・ヘルマン鍵共有&lt;/a>が使われていることもあります。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://qiita.com/aqmr-kino/items/8c3306ea8022b0d5cbe4">鍵交換方式(KexAlgorithms) - OpenSSHの暗号化周りの設定について&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="共通鍵を用いて暗号化された通信経路を作成">共通鍵を用いて暗号化された通信経路を作成&lt;/h2>
&lt;p>一回共通鍵を得てしまえばあとはこっちのもので、AESとかChacha20とか色々暗号化方式があるみたいです。&lt;/p>
&lt;blockquote>
&lt;p>CBC系の暗号化方式はSSHプロトコルの仕様上に問題があるため、基本的に使用せず、Chacha20やAES-GCM、AES-CTRを利用するようにします。&lt;/p>
&lt;/blockquote>
&lt;ul>
&lt;li>&lt;a href="https://qiita.com/aqmr-kino/items/8c3306ea8022b0d5cbe4#%E6%9A%97%E5%8F%B7%E5%8C%96%E6%96%B9%E5%BC%8Fciphers">暗号化方式(Ciphers) - OpenSSHの暗号化周りの設定について&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="暗号化された通信経路上でサーバー側がクライアントを認証">暗号化された通信経路上で、サーバー側がクライアントを認証&lt;/h2>
&lt;p>まあ普通にベーシック認証 over HTTPSみたいに&lt;a href="https://wikiwiki.jp/masami/TIPS/SSH#i637e292">ユーザー名とパスワード送信&lt;/a>して認証とかしたりします。&lt;/p>
&lt;p>あとはよくあるのは、サーバー側の&lt;code>~/.ssh/authorized_keys&lt;/code>にクライアントの公開鍵を置いて、クライアントの秘密鍵で認証する方式です。
&lt;a href="https://qiita.com/angel_p_57/items/2e3f3f8661de32a0d432#%E5%A6%A5%E5%BD%93%E3%81%AA%E8%AA%AC%E6%98%8E">妥当な説明 - SSHの公開鍵認証における良くある誤解の話&lt;/a>によれば、Diffie-Hellman鍵交換で得た共通鍵から作られたセッションIDをクライアントの秘密鍵で電子署名して渡すことで、サーバーが&lt;code>~/.ssh/authorized_keys&lt;/code>で検証して認証するようです。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/ssh/">ssh</category></item><item><title>豚汁が美味しい理由？</title><link>https://nu50218.dev/posts/tonziru-oishi/</link><guid isPermaLink="true">https://nu50218.dev/posts/tonziru-oishi/</guid><pubDate>Wed, 09 Jun 2021 17:17:30 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>豚汁が美味しい理由を考察してみました！&lt;/p>
&lt;p>味噌汁にごま油たらしてみたら味に深みがでつつ、味噌汁とは別の味になりました。&lt;/p>
&lt;p>もともと味噌と油は相性が良いから、豚汁も美味しいのではと思いました。&lt;/p>
&lt;p>いかがでしたか？&lt;/p>
&lt;p>というかもっと一般化して、発酵食品と油って相性良い気がしました。&lt;/p></description><category domain="https://nu50218.dev/categories/food/">food</category></item><item><title>自作スマートロック一旦諦めた</title><link>https://nu50218.dev/posts/give-up-smartlock/</link><guid isPermaLink="true">https://nu50218.dev/posts/give-up-smartlock/</guid><pubDate>Sat, 05 Jun 2021 19:14:15 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>自作スマートロックを一旦諦めた話です。
思っていたより要件がキツすぎた。&lt;/p>
&lt;p>先日の記事「&lt;a href="https://nu50218.dev/posts/m5atom-co2-mqtt/">M5Atom + MQTT + GrafanaでCO2を監視する&lt;/a>」で、&lt;/p>
&lt;blockquote>
&lt;ul>
&lt;li>もっと色々作りたくなった&lt;/li>
&lt;/ul>
&lt;p>IoT系初めて触ったけど結構楽しい！ 結構安いのに(1700円ぐらい)Wi-FiとかBluetoothとかボタンとか付いていて色々遊べそうです。 スマートロック自作したい、、、&lt;/p>
&lt;/blockquote>
&lt;p>と書いていて、色々試行錯誤しましたが、やっていくうちに色々問題があることがわかって一旦断念しました。&lt;/p>
&lt;p>ちなみにたまに出てくる「サムターン」というのは内側から開け締めするとき回すアレです。&lt;/p>
&lt;h2 id="そもそも何故やろうと思ったのか">そもそも何故やろうと思ったのか&lt;/h2>
&lt;p>まずは上述の通り、楽しそうというのがあります。&lt;/p>
&lt;p>ただもともと、既製品がいまいち自分の要件を満たしていないため、スマートロックほしいなぁと思いつつ買ってはいなかった、というのが背景にあります。&lt;/p>
&lt;p>既製品は、買い切りタイプで日本のサムターンに合ったものだとこの2つぐらいだと思います。&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://qrio.me/smartlock/">Qrio Lock&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://jp.candyhouse.co/products/sesame3">sesame3&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>どちらも通常Bluetooth Low Energy(BLE)でスマホと通信して解錠します。
課金してBluetooth Wi-Fiハブみたいなのを買うと、その会社のサーバーに繋がってリモートで鍵の操作ができるようになります。&lt;/p>
&lt;p>で、要件を満たしていないといっていたのはこのサーバーに繋がる部分です。
僕はリモートで操作できるようにしたいのですが、もしこのサーバーが攻撃されたら仕組みによっては勝手に鍵を開けられてしまいます。
仮に中間者がいたとしても安全であると明記されていないため、ちょっと怖くて買えていません。
Nature Remoみたいなリモコンの電波勝手に飛ばされるぐらいならいいんですけどね。&lt;/p>
&lt;h2 id="やったこと">やったこと&lt;/h2>
&lt;h3 id="先駆者を見た">先駆者を見た&lt;/h3>
&lt;p>なんかいっぱいいます。すごい。&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://jorublog.site/electronic-work-smart-lock/">大学生の電子工作　ラズパイでスマートロックを自作してみた&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://ppdr.softether.net/smartlock-1">帰宅したら自動で解錠するスマートロックを自作する①～オートロック編～&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://youtu.be/UrTNUKeVzU4">【夫が欲しいというがお金はかけたくないので】スマートロック手作りしてみた【家改造電子工作#2】&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/UrTNUKeVzU4" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;h3 id="家の鍵分解した">家の鍵分解した&lt;/h3>
&lt;p>頑張ってサムターン回さなくても、分解して中にいい感じにしこめないかチェックした。
結局いい感じにしこめないっぽいことがわかったけど、鍵の構造知れたからこれはこれで楽しかったです。&lt;/p>
&lt;h3 id="いろいろ買った">いろいろ買った&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://www.switch-science.com/catalog/6478/">Servo Kit 180‘&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>↑のサーボモーターが弱かったから追加で買った。&lt;/p>
&lt;ul>
&lt;li>サーボモーター SG92R&lt;/li>
&lt;/ul>
&lt;p>サムターン回す部分欲しくて買った。&lt;/p>
&lt;ul>
&lt;li>QrioLockのサムターン回すパーツ(これだけPayPayフリマで売ってた)&lt;/li>
&lt;/ul>
&lt;h3 id="結果">結果&lt;/h3>
&lt;p>試行錯誤したり考えた結果、いろいろ問題があることがわかりました。&lt;/p>
&lt;ol>
&lt;li>サムターンが固すぎて動作が微妙&lt;/li>
&lt;/ol>
&lt;p>SG92Rでも、サムターンが固すぎて回ったり回らなかったりした。
たまにサムターン回すパーツとの接合部分がガバガバで、モーターの先端だけ回ったりしていた。
これは結構大変、、、&lt;/p>
&lt;ol start="2">
&lt;li>ちゃんと運用していける？&lt;/li>
&lt;/ol>
&lt;p>たとえばなんらかのバグでずっと閉める位置にサーボモーターが力を入れて操作できなくなったら、帰ってきたときに物理鍵を使っても開けられなくて、鍵屋とかを呼ぶ羽目になるかもしれない。
鍵が固くて変な所に圧力がかかってそのうちどこか壊れそう。
なにかの理由で物理鍵で開けたときに状態管理壊れない？
などなど&lt;/p>
&lt;ol start="3">
&lt;li>モーターとかどうやって固定する？&lt;/li>
&lt;/ol>
&lt;p>ドアにモーターとか固定しなきゃいけないけど、それをちゃんと作る手段を持っていなかった…
ガムテープとかで頑張ればまあできると思うんですが、比較的すぐ(数ヶ月とか)壊れそう。
多分3Dプリンターで作るのがいいんですけど、3Dプリンターも、3Dモデルを作るスキルもなし。&lt;/p>
&lt;h3 id="反省感想">反省＆感想&lt;/h3>
&lt;p>なんとかなるやろの精神で無計画で突っ込んだらなんとかなりませんでした。ぴえん。&lt;/p>
&lt;p>その代わり結構知見が得られました。
鍵の構造知れたり、スマートロックのセキュリティを考えたり、スマートロックは他のIoT家電に比べてバグが致命的とか。&lt;/p>
&lt;p>なんかスマートロックとの通信で単純に&lt;/p>
&lt;pre tabindex="0">&lt;code>{&amp;#34;lock&amp;#34;: &amp;#34;open&amp;#34;}
&lt;/code>&lt;/pre>&lt;p>とか送って開け締めすると、中間者攻撃とか、他の人がそれを送って開け締めできちゃいますよね。
これらを解決するために、&lt;/p>
&lt;ul>
&lt;li>開ける権限を持っている人からのメッセージであること&lt;/li>
&lt;li>最近発行されたメッセージであること
が検証できればよくて、&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>{&amp;#34;lock&amp;#34;: &amp;#34;open&amp;#34;, &amp;#34;timestamp&amp;#34;: &amp;#34;2021-06-05T19:14:15+09:00&amp;#34;}
&lt;/code>&lt;/pre>&lt;p>みたいに発行した時間を載せたメッセージを電子署名すれば良さそうだなーって考えてました。&lt;/p>
&lt;p>余ったサーボモーターは、なにか別のものに使おうと思います。
電子工作力上がったらチャレンジ再開するかも知れません。&lt;/p>
&lt;p>自作しなくても、既存スマートロックを改造するとかBluetoothハブを自作するとか手はありそうですし、そっちをやってみてもいいかもしれません。&lt;/p>
&lt;h3 id="追記20190909">追記(2019/09/09)&lt;/h3>
&lt;p>今日Sesame4が発表されて買いました(え？)&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/oh6z-tY0F4M" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>というのも、スマホに擬態してBluetoothで直接通信して操作できそうなことが最近わかったためです。&lt;/p>
&lt;p>(これはSesame miniだけど)&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://qiita.com/odetarou/items/51424e1963c5d5099f1a">スマートロックのSesame miniをBluetooth連携する(ESP32編)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://qiita.com/odetarou/items/9628d66d4d94290b5f2d">スマートロックのSesame miniをnodeでBluetooth連携する&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>PythonでSesame OS2とBluetoothで直接通信するライブラリ&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://github.com/mochipon/pysesameos2">pysesameos2&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>ローカルで通信できるならむしろ自作より既製品を買います。
でたまたまそのタイミングでSesame3とほぼ変わらない新作が出たのでSesame4を買いました。&lt;/p>
&lt;p>ちなみに、Sesame4の発表動画見ていて&lt;/p>
&lt;blockquote>
&lt;p>たとえばなんらかのバグでずっと閉める位置にサーボモーターが力を入れて操作できなくなったら、帰ってきたときに物理鍵を使っても開けられなくて、鍵屋とかを呼ぶ羽目になるかもしれない。
鍵が固くて変な所に圧力がかかってそのうちどこか壊れそう。&lt;/p>
&lt;/blockquote>
&lt;p>と過去の自分が持っていた疑問に対する回答があってためになりました。
詳しくは動画の1分ぐらいからを見てほしいんですが、遊星ギアというのを使ってゴネゴネする(固定する歯車を変える)とモーターの力がかかるモードと、全くかからないモードを切り替えられるらしいです。
す、すげーーー！！！&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/iot/">iot</category></item><item><title>M5Atom + MQTT + GrafanaでCO2を監視する</title><link>https://nu50218.dev/posts/m5atom-co2-mqtt/</link><guid isPermaLink="true">https://nu50218.dev/posts/m5atom-co2-mqtt/</guid><pubDate>Thu, 06 May 2021 21:41:00 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>二酸化炭素が室内に多いと、眠くなったり集中力が低くなったり良くないらしいです。
濃度の増加に気付いて換気するために、M5AtomでCO2を監視するシステムを作りました。&lt;/p>
&lt;h2 id="完成図">完成図&lt;/h2>
&lt;p>&lt;img src="https://nu50218.dev/images/m5atom-co2-mqtt-1.png" alt="m5atom-co2-mqtt-1.png">&lt;/p>
&lt;h2 id="材料">材料&lt;/h2>
&lt;ul>
&lt;li>ATOM Matrix&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://www.switch-science.com/catalog/6260/">https://www.switch-science.com/catalog/6260/&lt;/a>&lt;/p>
&lt;p>ATOM Matrixじゃなくても、m5stackの奴なら良いと思います。
Atom Liteとか、Stickみたいなやつとか。&lt;/p>
&lt;ul>
&lt;li>TVOC/eCO2 ガスセンサユニット（SGP30）&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://www.switch-science.com/catalog/6619/">https://www.switch-science.com/catalog/6619/&lt;/a>&lt;/p>
&lt;ul>
&lt;li>USB-Cケーブル&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://www.switch-science.com/catalog/3792/">https://www.switch-science.com/catalog/3792/&lt;/a>&lt;/p>
&lt;p>これじゃなくても給電できれば多分OK&lt;/p>
&lt;ul>
&lt;li>Prometheus&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://prometheus.io">https://prometheus.io&lt;/a>&lt;/p>
&lt;p>データを集めて、クエリに答えてくれる偉い人&lt;/p>
&lt;ul>
&lt;li>Grafana&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://grafana.com">https://grafana.com&lt;/a>&lt;/p>
&lt;p>Prometheusにクエリ投げてイケイケなグラフを描画してくれたりアラート出せる人&lt;/p>
&lt;ul>
&lt;li>Mosquitto&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://mosquitto.org">https://mosquitto.org&lt;/a>
&lt;a href="https://hub.docker.com/_/eclipse-mosquitto">https://hub.docker.com/_/eclipse-mosquitto&lt;/a>&lt;/p>
&lt;p>IoTで使われがちなMQTTというPub/Subのプロトコルがあるらしく、それのOSSのサーバー&lt;/p>
&lt;ul>
&lt;li>mqtt2prometheus&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://github.com/hikhvar/mqtt2prometheus">https://github.com/hikhvar/mqtt2prometheus&lt;/a>&lt;/p>
&lt;p>MQTTのトピックと、それをどのようにPrometheusに流したいかを設定ファイルで書くといい感じにやってくれる奴
わかる人向けに書くと、設定ファイルに従ったexporterとして動いてくれます。&lt;/p>
&lt;h2 id="調理工程">調理工程&lt;/h2>
&lt;ol>
&lt;li>物理的なやつをつなぐ&lt;/li>
&lt;/ol>
&lt;p>M5AtomにセンサーとUSBケーブルを繋ぎます。&lt;/p>
&lt;ol start="2">
&lt;li>Mosquittoに定期的にデータをPublishするプログラムを書き込む&lt;/li>
&lt;/ol>
&lt;p>GitHubにコードをあげたので参考になると思います。
Arduino IDEを頑張ると書き込めます。&lt;/p>
&lt;p>&lt;a href="https://github.com/nu50218/m5atom-co2-mqtt">https://github.com/nu50218/m5atom-co2-mqtt&lt;/a>&lt;/p>
&lt;ol start="3">
&lt;li>PrometheusとGrafanaとMosquittoとmqtt2prometheusを繋ぐ&lt;/li>
&lt;/ol>
&lt;p>どれもDockerファイルがあるので簡単です。
設定もちゃんとドキュメントかネットを見ればわかると思います。&lt;/p>
&lt;p>図としては以下のような感じです。&lt;/p>
&lt;p>&lt;img src="https://nu50218.dev/images/m5atom-co2-mqtt-2.png" alt="m5atom-co2-mqtt-2.png">&lt;/p>
&lt;ol start="4">
&lt;li>Grafanaからダッシュボード作る&lt;/li>
&lt;/ol>
&lt;p>完成！&lt;/p>
&lt;h2 id="感想">感想&lt;/h2>
&lt;ul>
&lt;li>Arduino IDEが結構つらい…&lt;/li>
&lt;/ul>
&lt;p>LSPが欲しくなったり、ライブラリのインポートが独特(？なんか依存ファイルができるんじゃなくてポチッと押す…)だったりで結構辛かったです。&lt;/p>
&lt;ul>
&lt;li>コード通りに動かない&lt;/li>
&lt;/ul>
&lt;p>確率で無限にWi-Fiに繋がらないとか変な挙動しました。&lt;/p>
&lt;ul>
&lt;li>日本語の情報が少なめでちょっとつらかった&lt;/li>
&lt;/ul>
&lt;p>m5stackとかArduino周りの情報が少なくて結構辛かったんですが、&lt;a href="https://docs.m5stack.com/en/arduino/arduino_home_page?id=quickstart">公式のドキュメント&lt;/a>見たら普通にいけました。&lt;/p>
&lt;p>あとは、ライブラリ入れたら見れるサンプルが結構豊富で、これを見れば結構大丈夫でした。
二酸化炭素センサーもコードサンプルがあったのでAPIがわかってよかったです。&lt;/p>
&lt;ul>
&lt;li>MQTTとかいうやつの存在を知った&lt;/li>
&lt;/ul>
&lt;p>IoT系は普段使ってる(WEB周りの)技術とは結構勝手が違って面白かったです。
大抵の場合プロセッサーが安価で性能がめちゃめちゃ低いので、なるべく軽い処理をさせたいという問題が生じて、MQTTのような独特のIoT向けのソフトウェアが生まれているっぽいです。&lt;/p>
&lt;ul>
&lt;li>もっと色々作りたくなった&lt;/li>
&lt;/ul>
&lt;p>IoT系初めて触ったけど結構楽しい！
結構安いのに(1700円ぐらい)Wi-FiとかBluetoothとかボタンとか付いていて色々遊べそうです。
スマートロック自作したい、、、&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/iot/">iot</category><category domain="https://nu50218.dev/tags/mqtt/">mqtt</category><category domain="https://nu50218.dev/tags/grafana/">grafana</category><category domain="https://nu50218.dev/tags/prometheus/">prometheus</category></item><item><title>実質500円！うなぎとミントの混ぜご飯</title><link>https://nu50218.dev/posts/unagi-mint-gohan/</link><guid isPermaLink="true">https://nu50218.dev/posts/unagi-mint-gohan/</guid><pubDate>Sun, 25 Apr 2021 13:24:45 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>実質500円✨ボウルひとつで作れる✨うなぎとミントの混ぜご飯をご紹介します。写真は撮る前に美味しくて消えたのでありません。&lt;/p>
&lt;h2 id="inspired-by">inspired by&lt;/h2>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/eLS0iQmMSFg" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;h2 id="材料-2人前">材料 (2人前)&lt;/h2>
&lt;p>合計実質1001円なので、1人前実質500円になります。&lt;/p>
&lt;h3 id="松屋-うな丼w-ライス大盛り-持ち帰り-実質973円">松屋 うな丼(W) ライス大盛り 持ち帰り 実質973円&lt;/h3>
&lt;p>&lt;a href="https://www.matsuyafoods.co.jp/matsuya/news_lp/210413.html">キャンペーン&lt;/a>で持ち帰りが2021/04/27まで30%ポイント還元です。&lt;/p>
&lt;p>また、&lt;/p>
&lt;blockquote>
&lt;p>※新発売を記念して、うな丼関連メニューをご注文のお客様を対象に、2021年4月27日（火）午前10時まで、ライス大盛を無料サービス！&lt;/p>
&lt;/blockquote>
&lt;p>なので、&lt;/p>
&lt;blockquote>
&lt;p>うな丼 （お新香・みそ汁・山椒小袋付）1,390円&lt;/p>
&lt;/blockquote>
&lt;p>がライス大盛りで実質973円です。&lt;/p>
&lt;h3 id="スペアミント-28円">スペアミント 28円&lt;/h3>
&lt;p>近くのスーパーにパックで売ってました。&lt;/p>
&lt;h3 id="新鮮なブラックペッパー-実質0円">新鮮なブラックペッパー 実質0円&lt;/h3>
&lt;p>新鮮な方がやっぱり香りがいいです。&lt;/p>
&lt;h2 id="作り方">作り方&lt;/h2>
&lt;ol>
&lt;li>ボウルにうな丼とうなぎのタレをいれてうなぎを崩しながら混ぜます。&lt;/li>
&lt;/ol>
&lt;p>※山椒はいれません！！&lt;/p>
&lt;ol start="2">
&lt;li>
&lt;p>ミントをパック全部入れて軽く混ぜます。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>ブラックペッパーをお好きな量(多め)かけます。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>以上！&lt;/p>
&lt;h2 id="食べた感想">食べた感想&lt;/h2>
&lt;p>ミント美味い！！
入れすぎたぐらい入れたのに、ミントの香りがうなぎのタレにめちゃくちゃ合う。
さすが日高シェフ…。
ミントもブラックペッパーも思い切って入れたほうが美味しいです多分。&lt;/p></description><category domain="https://nu50218.dev/tags/food/">food</category></item><item><title>CMU Databases Systems #01</title><link>https://nu50218.dev/posts/cmu-databases-systems-01/</link><guid isPermaLink="true">https://nu50218.dev/posts/cmu-databases-systems-01/</guid><pubDate>Sat, 24 Apr 2021 21:04:58 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>ちょうど興味あったし、YouTubeにカーネギーメロン大学のDBの授業あったので見始めた。&lt;/p>
&lt;p>初回↓&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/oeYBdghaIjc" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>とりあえず初回を見た感想は、たまに英語わからんけどスライド見ながらなら大意はとれそうぐらいの感じだった。&lt;/p>
&lt;p>期待していたとおり、SQLの書き方の授業というような感じではなくて、理論と、実際の実装を解説してくれてた。&lt;/p>
&lt;p>(なんか、授業を通して 卍toy DB written in C++卍 をつくろう！みたいな感じですごい)&lt;/p>
&lt;p>いろいろへぇ〜ってことが多かった。たとえば、&lt;/p>
&lt;ul>
&lt;li>
&lt;p>DBMSはDB Management Systemで、MySQLはDBMSであってDBではない。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>もともとシステムごとに毎回個別にデータ管理するやつを書いてた背景があって、関係モデルと言う概念がうまれた。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>なんか関係は数学用語の関係と一緒だった(多分)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>なんかほぼ集合だった。&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>DBの中身わかる人になって、クエリを見たらその速度がわかるようになれると嬉しいですね。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category></item><item><title>楽天期間限定ポイントの消費の方法</title><link>https://nu50218.dev/posts/consume-rakuten-point/</link><guid isPermaLink="true">https://nu50218.dev/posts/consume-rakuten-point/</guid><pubDate>Sat, 24 Apr 2021 13:04:27 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>楽天期間限定ポイントの消費方法を調べてみました！&lt;/p>
&lt;p>楽天ペイで期間限定ポイント使えるみたいです。&lt;/p>
&lt;p>&lt;img src="https://nu50218.dev/images/consume-rakuten-point-1.png" alt="consume-rakuten-point-1.png">&lt;/p>
&lt;p>なんか全額ポイントで払えませんって言われたので1円クレカで払ったらいけました(謎仕様…)&lt;/p>
&lt;h2 id="まとめ">まとめ&lt;/h2>
&lt;p>いかがでしたか？&lt;/p></description></item><item><title>splatnet2statinkをDockerで動かす</title><link>https://nu50218.dev/posts/splatnet2statink-docker/</link><guid isPermaLink="true">https://nu50218.dev/posts/splatnet2statink-docker/</guid><pubDate>Mon, 19 Apr 2021 13:45:20 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>splatoon2は、公式アプリを使うことで最近の試合の結果を見ることができます。
&lt;a href="https://github.com/frozenpandaman/splatnet2statink">splatnet2statink&lt;/a>は、ゴネゴネしてそのデータを取得し、&lt;a href="https://stat.ink/@nu50218">stat.ink&lt;/a>にアップロードしてくれるツールです。
常に動かすには少し面倒な仕様だったので、Dockerイメージにして使いやすくしました。&lt;/p>
&lt;p>使い方が知りたい人は、&lt;a href="https://github.com/nu50218/splatnet2statink-docker#readme">GitHubのリポジトリのREADME&lt;/a>を見てください。&lt;/p>
&lt;h2 id="問題点">問題点&lt;/h2>
&lt;h3 id="python製">Python製&lt;/h3>
&lt;p>よくわからないけど経験上気づいたら壊れていがちです。&lt;/p>
&lt;p>あとあまり環境を汚したくないです。&lt;/p>
&lt;h3 id="起動方法">起動方法&lt;/h3>
&lt;p>config.txt (初回に生成される) と同じディレクトリで起動しなきゃいけないです。&lt;/p>
&lt;p>Python製というのもあいまって、ポータビリティが悪いです。&lt;/p>
&lt;h2 id="解決策">解決策&lt;/h2>
&lt;p>DockerイメージにしてDocker Hubにあげちゃいます。&lt;/p>
&lt;p>気づいたら壊れていがち → 壊れない！&lt;/p>
&lt;p>環境を汚したくない → 汚れない！&lt;/p>
&lt;p>config.txtと同じディレクトリで起動しなきゃいけない → 後述&lt;/p>
&lt;p>ポータビリティが悪い → Docker最強！&lt;/p>
&lt;p>ということで解決しました。&lt;/p>
&lt;p>&lt;a href="https://hub.docker.com/repository/docker/nu50218/splatnet2statink">nu50218/splatnet2statink - Docker Hub&lt;/a>&lt;/p>
&lt;h3 id="configtxtの処理">config.txtの処理&lt;/h3>
&lt;p>config.txtは初回に生成されます。
volumeでホストにconfig.txtをおいてもいいんですが、他のPCに移すときにコピーしなきゃいけないのでちょっと面倒です。&lt;/p>
&lt;p>個人的には設定ファイルよりも環境変数で設定したい気持ちがあります。
なので、以下のようなGoのコードを書いて、docker runしたときに間に挟まって起動時に環境変数からconfig.txtを生成してくれるようにしました。&lt;/p>
&lt;p>&lt;a href="https://github.com/nu50218/splatnet2statink-docker/blob/main/main.go">https://github.com/nu50218/splatnet2statink-docker/blob/main/main.go&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;encoding/json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;log&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;os&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;os/exec&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;github.com/pkg/errors&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// {&amp;#34;api_key&amp;#34;: &amp;#34;&amp;#34;, &amp;#34;cookie&amp;#34;: &amp;#34;&amp;#34;, &amp;#34;user_lang&amp;#34;: &amp;#34;&amp;#34;, &amp;#34;session_token&amp;#34;: &amp;#34;&amp;#34;}
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">type&lt;/span> &lt;span class="nx">ConfigData&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">APIKey&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`json:&amp;#34;api_key&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Cookie&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`json:&amp;#34;cookie&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">UserLang&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`json:&amp;#34;user_lang&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">SessionToken&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`json:&amp;#34;session_token&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// generate config.txt from environment variable
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kd">func&lt;/span> &lt;span class="nf">prepare&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">error&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;USE_ENVIRONMENT_VARIABLE&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s">&amp;#34;1&amp;#34;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">config&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nx">ConfigData&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">APIKey&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;API_KEY&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Cookie&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;COOKIE&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">UserLang&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;USER_LANG&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">SessionToken&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;SESSION_TOKEN&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">f&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Create&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;config.txt&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">errors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">WithStack&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">json&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">NewEncoder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">f&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nf">Encode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">config&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">errors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">WithStack&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">run&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cmd&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">exec&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Command&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;python&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">append&lt;/span>&lt;span class="p">([]&lt;/span>&lt;span class="kt">string&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="s">&amp;#34;splatnet2statink.py&amp;#34;&lt;/span>&lt;span class="p">},&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Args&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">:]&lt;/span>&lt;span class="o">...&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">...&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cmd&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stdin&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stdin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cmd&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stdout&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stdout&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cmd&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stderr&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stderr&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">_&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">cmd&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Run&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">cmd&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ProcessState&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">ExitCode&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nf">prepare&lt;/span>&lt;span class="p">();&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">log&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Println&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Exit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nf">run&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>標準入出力、エラー出力はそのままつないで、exit codeも同じものを返すようにして擬態させました。&lt;/p>
&lt;p>これでたとえばdocker-compose.ymlを使うと、&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yml" data-lang="yml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">splatnet2statink&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">nu50218/splatnet2statink:latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">environment&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">USE_ENVIRONMENT_VARIABLE=1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">API_KEY=えーぴーあい・かぎ&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">COOKIE=くっきー&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">SESSION_TOKEN=せっしょん・とーくん&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="l">USER_LANG=ゆーざー・げんご&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">restart&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">always&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">command&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>-&lt;span class="l">s -r -M&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>のように設定するだけで勝手にconfig.txtが内部的に生成されて、splatnet2statink.pyが起動されてくれるようになりました！&lt;/p>
&lt;p>ということで&lt;/p>
&lt;p>config.txtと同じディレクトリで起動しなきゃいけない&lt;/p>
&lt;p>も解決です。&lt;/p>
&lt;h2 id="余談-なんか壊れてたのでpr出した">余談: なんか壊れてたのでPR出した&lt;/h2>
&lt;p>自作イメージを使ってさっそく常時アップロードをはじめたところ、なんか壊れました。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">Traceback&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">most&lt;/span> &lt;span class="n">recent&lt;/span> &lt;span class="n">call&lt;/span> &lt;span class="n">last&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">File&lt;/span> &lt;span class="s2">&amp;#34;/splatnet2statink/splatnet2statink.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">line&lt;/span> &lt;span class="mi">1282&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="o">&amp;lt;&lt;/span>&lt;span class="n">module&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">populate_battles&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">is_s&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">is_t&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">is_r&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">debug&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">File&lt;/span> &lt;span class="s2">&amp;#34;/splatnet2statink/splatnet2statink.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">line&lt;/span> &lt;span class="mi">375&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">populate_battles&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">post_battle&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">s_flag&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">t_flag&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">True&lt;/span> &lt;span class="k">if&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span> &lt;span class="k">else&lt;/span> &lt;span class="kc">False&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">debug&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">File&lt;/span> &lt;span class="s2">&amp;#34;/splatnet2statink/splatnet2statink.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">line&lt;/span> &lt;span class="mi">1092&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">post_battle&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">payload&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">set_scoreboard&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">payload&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">bn&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">mystats&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">s_flag&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">File&lt;/span> &lt;span class="s2">&amp;#34;/splatnet2statink/splatnet2statink.py&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">line&lt;/span> &lt;span class="mi">658&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">set_scoreboard&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sorted_ally_scoreboard&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">sorted&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ally_scoreboard&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">itemgetter&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">11&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">reverse&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ne">TypeError&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;&amp;lt;&amp;#39;&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">supported&lt;/span> &lt;span class="n">between&lt;/span> &lt;span class="n">instances&lt;/span> &lt;span class="n">of&lt;/span> &lt;span class="s1">&amp;#39;NoneType&amp;#39;&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="s1">&amp;#39;str&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>まあエラーメッセージを読めば分かる通り、Noneと文字列を比較しようとして、比較関数がないよ！って怒られています。&lt;/p>
&lt;p>Pythonワカラナイなりにprintデバッグをして頑張った結果原因が判明しました。
ソートのキーにユーザー名を使っているくせに、匿名アップロードオプション(&lt;a href="https://stat.ink/@nu50218/spl2/3675280">他のユーザーの名前を隠して投稿する機能&lt;/a>)で匿名をNoneとして扱っていたのが原因でした。&lt;/p>
&lt;p>コマンドラインツールでどんどんオプション追加していくとバグるやつ、わかるなぁと思いながら修正してPRを出し、マージされました。&lt;/p>
&lt;p>&lt;a href="https://github.com/frozenpandaman/splatnet2statink/pull/119">https://github.com/frozenpandaman/splatnet2statink/pull/119&lt;/a>&lt;/p>
&lt;p>今回の場合は、いろいろなオプションを一つの関数で頑張ってやっているのがよくなくて、単一責任の原則を無視して関数にオプションを追加していった結果バグが生まれたのかなぁとコードを読んでいて思いました。
コード量増えるけど適度に&lt;code>upload()&lt;/code>と&lt;code>upload_anonymously()&lt;/code>みたいに関数分割するの大事そうです。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/splatoon2/">splatoon2</category><category domain="https://nu50218.dev/tags/docker/">docker</category></item><item><title>失敗しないネット回線の選び方</title><link>https://nu50218.dev/posts/how-to-choose-internet-line/</link><guid isPermaLink="true">https://nu50218.dev/posts/how-to-choose-internet-line/</guid><pubDate>Wed, 24 Mar 2021 20:55:21 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>インターネットの回線は結構罠が多いです。どの時間帯でもそこそこの速度(100Mbps程度)を安定して出すには、数々の罠を乗り越える必要があります。この記事は、罠に嵌る被害者を減らすことを目的として、知っておくとよさそうな情報をなぐり書きました。&lt;/p>
&lt;h2 id="はじめに">はじめに&lt;/h2>
&lt;p>この記事の対象読者は、少しは技術的な話がわかる人です。&lt;/p>
&lt;p>何もわからない人は、とりあえず&lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#%E6%A3%9F%E5%86%85%E9%85%8D%E7%B7%9A%E6%96%B9%E5%BC%8F%E3%81%AE%E8%A9%B1">棟内配線方式&lt;/a>をチェックして、&lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#%E3%82%AA%E3%82%B9%E3%82%B9%E3%83%A1%E5%9B%9E%E7%B7%9A">オススメ回線&lt;/a>あたりを契約しておけばまあ、無難に安定して速いと思います。あとはキャッシュバックをちゃんと受け取れば(&lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%83%90%E3%83%83%E3%82%AF%E3%81%AE%E8%A9%B1">後述&lt;/a>)満点に近いと思います。&lt;/p>
&lt;p>ガチプロというわけでもないので、間違ったことを書いていたらすみません…。参考程度によろしくおねがいします。一番下のメールでご指摘いただければ修正すると思います。&lt;/p>
&lt;p>また、アフィリエイトのリンクは貼っていないので正直な意見を書いています。&lt;/p>
&lt;h2 id="ネット回線の分類">ネット回線の分類&lt;/h2>
&lt;p>回線を分類して、順番に説明を書いていきます。インターネット回線を敷こうとすると、色々会社があって訳わからないですが、実は以下のように分類できます。&lt;/p>
&lt;p>ちなみに勝手に名前をつけているので、通称と違うかもしれないです。&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>分類&lt;/th>
&lt;th>例&lt;/th>
&lt;th>概要&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>NTT系&lt;/td>
&lt;td>フレッツ光 &lt;br> ドコモ光 &lt;br> ぷらら光&lt;/td>
&lt;td>NTTの敷いた光ファイバーを使います&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>電力系&lt;/td>
&lt;td>コミュファ光&lt;/td>
&lt;td>NTTとは違った独自で敷かれた線で通信します。電力会社の系列で、たいてい全国ではなくて一部の地域にサービスを提供しています。(たとえばコミュファ光は中部地方)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>ダークファイバー系&lt;/td>
&lt;td>auひかり &lt;br> NURO光&lt;/td>
&lt;td>NTTから余った光ファイバー(ダークファイバー)を借りて、それで通信します&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>その他&lt;/td>
&lt;td>ケーブルテレビ &lt;br> マンション共用回線 &lt;br> J:COM &lt;br> SoftBank Air&lt;/td>
&lt;td>ヤバい&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="その他はオワリです">その他はオワリです&lt;/h2>
&lt;p>その他のやつを契約することです。大体激ヤバ回線と思ってください。&lt;/p>
&lt;p>マンション共用回線は、インターネット無料とかWi-Fi無料とかの奴です。一つの回線を居住者全員で共有するので、使う人が多くなるとオワリます。&lt;/p>
&lt;p>J:COMはなんか知らないけど悪評高いです。&lt;/p>
&lt;p>SoftBank Airは実質テザリングなので自明にオワリです。&lt;/p>
&lt;p>ケーブルテレビはワンチャン救いがありそう。&lt;/p>
&lt;p>ということでもろもろ理解している人以外は契約してはダメです。&lt;/p>
&lt;h2 id="ntt系について">NTT系について&lt;/h2>
&lt;h3 id="仕組み">仕組み&lt;/h3>
&lt;p>NTTのフレッツ光と、ドコモ光など光コラボレーション(以下、光コラボ)と呼ばれるNTTから間借りしているものがあります。多分光コラボは、格安SIMとかのMVNOと同じような感じです。僕も一年前契約するとき勘違いしていたんですが、ドコモ光とかフレッツ光とか、ソフトバンク光とか、このNTT系は基本的に同じNTTの敷いた光ファイバーを通っていきます。&lt;/p>
&lt;p>じゃあ何が違うのかというと、NGN網というのを理解する必要があります。&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>NGN網とは&lt;/strong>&lt;/p>
&lt;p>家まで来ているNTTの光ファイバーは、実は直接インターネットに接続しているわけではありません。NTTの線で日本中に張り巡らされた巨大な閉じたネットワーク(NGN網)に接続されます。NGN網とインターネットを繋ぐ、インターネットサービスプロバイダー(以下、ISP)というのがいて、そのサーバーを通ってインターネットへNGN網から出ていきます。&lt;/p>
&lt;/blockquote>
&lt;p>したがって、基本的に同じ光ファイバーを通っていくと書いたのは、ISPまでは同じで、ISP以降が違うという話です。例として、&lt;a href="https://www.nttdocomo.co.jp/hikari/provider_list/">ドコモ光のプロバイダー一覧&lt;/a>を見てみるとなんとなく理解できると思います。「ドコモ光は遅い、フレッツ光は速い」のようなことを言っている人をたまに見かけますが、会社のせいというよりは、ISPの違いです(多分)。&lt;/p>
&lt;h3 id="ipv4が遅いみたいな話">IPv4が遅いみたいな話&lt;/h3>
&lt;p>詳細は省きますが、IPv4とIPv6で、基本的にISPまでの経路が違って、現状IPv4のほうが容量が足りていません。これによりピークタイムでは普通にIPv4で通信しようとすると遅くなります。(IPv4とIPv6自体には速度の違いはほぼないと思いますが様々な事情で、、、)&lt;/p>
&lt;p>※ ここらへんの話は難しくて理解が浅いので、結構ガバガバなことを書いていると思います。 &lt;a href="https://diary.sorah.jp/2020/06/20/ngn-explained-2020">NTT フレッツ光における通信速度などの現状について、背景や仕組みから正しく理解する 2020&lt;/a> がとても詳しく書いてありオススメです。&lt;/p>
&lt;p>で、結構な人がこの罠にはまりがちです。夜中になると急に遅くなる…って言っている人はだいたいこのパターンだと思います。&lt;/p>
&lt;p>この罠の回避策として、IPv4のパケットをIPv6で包んで通信するやつがあります。いわゆるIPv4 over IPv6で、&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://www.jpne.co.jp/service/v6plus/">v6プラス&lt;/a>&lt;/li>
&lt;li>DS-Lite&lt;/li>
&lt;li>&lt;a href="https://www.plala.or.jp/ipv6/">ぷららv6エクスプレス&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>などがそれにあたります。&lt;/p>
&lt;p>僕的には、家/賃貸にNTTの&lt;strong>光ファイバーが&lt;/strong>来ているなら(参照: &lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#%E6%A3%9F%E5%86%85%E9%85%8D%E7%B7%9A%E6%96%B9%E5%BC%8F%E3%81%AE%E8%A9%B1">棟内配線方式の話&lt;/a>)、&lt;strong>これらを使うのが速度も安定して速く、そこそこ安くてオススメ&lt;/strong>です。&lt;/p>
&lt;h3 id="賃貸の他の人でntt系の人が多いから速度が落ちるみたいな話">賃貸の他の人でNTT系の人が多いから速度が落ちるみたいな話&lt;/h3>
&lt;p>これよく代理店の営業の人とかに言われるんですが、一つの光ファイバーをマンション全体で共有しているわけではないので、多分嘘です。光ファイバーの最大分岐数みたいなのが決まっていて、最大32部屋しか共有しません。で光ファイバーは1Gbps×32=32Gbpsより全然キャパシティあるので、他の原因で遅くなっていると思います。上で書いたISP詰まってる問題が大半だと思っていて、営業の人はそれを勘違いしているんだと思います。&lt;/p>
&lt;h2 id="電力系について">電力系について&lt;/h2>
&lt;p>コミュファ光しか知らないのですが、コラボ光ではないので&lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#IPv4%E3%81%8C%E9%81%85%E3%81%84%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AA%E8%A9%B1">IPv4が遅いみたいな話&lt;/a>の罠がないと思います。&lt;/p>
&lt;p>&lt;strong>光ファイバーが&lt;/strong>来ているなら(参照: &lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#%E6%A3%9F%E5%86%85%E9%85%8D%E7%B7%9A%E6%96%B9%E5%BC%8F%E3%81%AE%E8%A9%B1">棟内配線方式の話&lt;/a>)、こだわりがなければ割と良さそうと思っています。&lt;/p>
&lt;h2 id="ダークファイバー系">ダークファイバー系&lt;/h2>
&lt;p>知っている限りではNURO光とauひかりがあります。&lt;/p>
&lt;p>使ったことないですがとりあえず安定して爆速、だけでいいならこれが最強だと思います。が、使える地域が結構都会に限定されているのが難点です。&lt;/p>
&lt;p>NURO光は工事が遅い、結局工事できないとかありがちです。&lt;/p>
&lt;p>東京はauひかりの10Gbpsで常勝というイメージがありますが、嘘かもしれません。&lt;/p>
&lt;p>電力系とダークファイバー系は使ってないのであまり量なくてすみません。&lt;/p>
&lt;h2 id="キャッシュバックの話">キャッシュバックの話&lt;/h2>
&lt;p>いろんな会社がキャッシュバックのキャンペーンやっています。これ結構罠で、たとえば&lt;a href="https://www.plala.or.jp/p-hikari/campaign/">ぷららのキャンペーン&lt;/a>から引用すると、&lt;/p>
&lt;blockquote>
&lt;p>キャッシュバック方法について&lt;/p>
&lt;p>10か月の継続利用を確認後、振込口座確認についてのメールをお送りいたします。
所定の方法で、口座番号などお振り込み先に関する回答をいただいたのち、ご指定の口座へお振込いたします。
振込口座確認メールは、ご入会時に取得されたぷららのメールアドレス宛てにお送りします。なお、お送りしたメールは「ぷららWebメール」でご確認いただけます。
振込口座確認メール送付の翌月末までにご回答ください、期限までに回答いただけない場合は対象外となります。&lt;/p>
&lt;/blockquote>
&lt;p>とあります。&lt;/p>
&lt;p>大体の会社が忘れた頃にメールを送ってきて、それに期限内に回答しないとキャッシュバックもらえません。多分結構な人が忘れています。&lt;/p>
&lt;h2 id="代理店の営業の話">代理店の営業の話&lt;/h2>
&lt;p>定期的にネット回線契約しませんか？という訪問の営業が来ます。この人達は、「ほげほげ光の者です」のように名乗りますが、正しくは「ほげほげ光(の代理店)の者」です。ほげほげ光の契約者を営業でとってきて、ほげほげ光から紹介ありがとね金を貰っている別の会社です。&lt;/p>
&lt;p>で、この人達が結構平然と嘘を付いてくるので気をつけたほうが良いです。例(ノンフィクション)をあげると、&lt;/p>
&lt;ul>
&lt;li>「この建物のネットワーク設備を担当しています」&lt;/li>
&lt;li>「この建物のネットワーク設備を管理者から任されています」&lt;/li>
&lt;/ul>
&lt;p>嘘です。&lt;/p>
&lt;ul>
&lt;li>「この建物NTTの回線使ってる人が多いから、遅くなるんですよ〜」&lt;/li>
&lt;/ul>
&lt;p>&lt;a href="https://nu50218.dev/posts/how-to-choose-internet-line/#%E8%B3%83%E8%B2%B8%E3%81%AE%E4%BB%96%E3%81%AE%E4%BA%BA%E3%81%A7NTT%E7%B3%BB%E3%81%AE%E4%BA%BA%E3%81%8C%E5%A4%9A%E3%81%84%E3%81%8B%E3%82%89%E9%80%9F%E5%BA%A6%E3%81%8C%E8%90%BD%E3%81%A1%E3%82%8B%E3%81%BF%E3%81%9F%E3%81%84%E3%81%AA%E8%A9%B1">嘘です。&lt;/a>&lt;/p>
&lt;ul>
&lt;li>「NURO光です」&lt;/li>
&lt;/ul>
&lt;p>NURO光の代理店です。&lt;/p>
&lt;ul>
&lt;li>「最大1Gbps出ます」(コミュファ光の代理店の人)&lt;/li>
&lt;/ul>
&lt;p>コミュファ光、棟内VDSL方式(最大100Mbps)なのに…？&lt;/p>
&lt;ul>
&lt;li>「月額1980円です」&lt;/li>
&lt;/ul>
&lt;p>初月割引した価格をあたかも通常の月額のように言ってきます。&lt;/p>
&lt;ul>
&lt;li>「コロナで支援金出ていて〜」&lt;/li>
&lt;/ul>
&lt;p>後で調べたけど意味がよくわからなかった。&lt;/p>
&lt;p>したがって、別にキャッシュバック額が増えるとか得があるわけでもないので、代理店は無視して直接契約したほうがいいです。&lt;/p>
&lt;h2 id="棟内配線方式の話">棟内配線方式の話&lt;/h2>
&lt;p>これとても大事！！&lt;/p>
&lt;p>戸建てタイプは直接光ファイバー敷くので、マンションタイプが関係ある話です。&lt;/p>
&lt;p>建物の内部の配線方式で結構変わります。&lt;/p>
&lt;blockquote>
&lt;p>集合住宅のフレッツ光の配線は、3種類あります。
共用スペースに引き込んだ光回線を各戸で共有する「共同利用方式」には、マンション内の配線によって「光配線方式」「VDSL方式」「LAN配線方式」の3つの方式があります。&lt;/p>
&lt;/blockquote>
&lt;p>(&lt;a href="https://flets.com/first/kouji/const_apartment.html">フレッツ光のサイト&lt;/a>から引用)&lt;/p>
&lt;p>まず前提として、NTT系とか電力系とかダークファイバー系でも、基本的にはマンションの共用スペース(MDF室)に光ファイバーを持ってきて、そこから各部屋につなぎます。回線契約するときに工事すると思うんですが、大抵はMDF室までは来てるので、アレはMDF室から部屋まで繋いでいます。たまに部屋まですでに来てるとラッキーという感じです。&lt;/p>
&lt;p>そのときにMDF室から部屋まで光ファイバーで繋ぐのが光配線方式、LANケーブルがLAN配線方式(？)、電話の線でやってしまうのがVDSL方式です。&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>方式&lt;/th>
&lt;th>速度&lt;/th>
&lt;th>他の利用者の影響&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>光配線方式&lt;/td>
&lt;td>1Gbps~&lt;/td>
&lt;td>ほぼなし&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>LAN配線方式&lt;/td>
&lt;td>100Mbps~&lt;/td>
&lt;td>不明(なんかありそう)&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>VDSL方式&lt;/td>
&lt;td>~100Mbps&lt;/td>
&lt;td>不明(なんかありそう)&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>光配線方式はOKです。少なくとも最大1Gbpsで契約できると思います。他の居住者の影響もほぼないと思います。&lt;/p>
&lt;p>LAN配線方式はよくわかっていません。LANケーブルが古いと最大100Mbpsしか出ないとか、MDF室でマンション全体の光ファイバーの通信の終端をさせているので、処理能力に限界でそう感があります。うーん。&lt;/p>
&lt;p>VDSL方式は電話の線という都合上100Mbpsまでしか出ません。悲しいです。&lt;/p>
&lt;p>VDSL方式になってしまうのを回避するために、お部屋探しをする際にはその会社に電話して建物名を伝えて配線方式を教えてもらうのがオススメです。&lt;/p>
&lt;p>NTTと電力系で違ったりするのでどちらも調べて、光配線方式の方を契約するのがいいと思います。&lt;/p>
&lt;h2 id="ipv4-over-ipv6系でポート開放できない話">IPv4 over IPv6系でポート開放できない話&lt;/h2>
&lt;p>基本できません。v6プラスは一部指定された256個ぐらいのポートだけしか開けません。DS-Liteは全部ダメだったような。&lt;/p>
&lt;p>&lt;a href="https://www.jpne.co.jp/service/v6plus-static/">v6プラス固定IPサービス&lt;/a>これを契約しないと基本ほぼダメそうな印象です。&lt;/p>
&lt;p>PPPoEの方のIPでポート開いて、外に出ていくパケットはIPv4 over IPv6で、とかやっている人もいました。&lt;/p>
&lt;p>ちなみに僕は一時期VPSを契約してトンネリングしてましたがv6プラス固定IPサービスにしました。&lt;/p>
&lt;h2 id="オススメ回線">オススメ回線&lt;/h2>
&lt;p>まとめです。これに従えば基本どの時間も安定して高速に通信できると思います。&lt;/p>
&lt;p>まず、&lt;/p>
&lt;ul>
&lt;li>NURO光&lt;/li>
&lt;li>auひかり&lt;/li>
&lt;/ul>
&lt;p>が契約できるならそれでいいと思います。&lt;/p>
&lt;p>そうでなければ、まず、NTTか電力系の回線が光配線方式のマンション/アパート、あるいは戸建てに住みます。&lt;/p>
&lt;p>NTTが光配線方式なら、&lt;a href="https://enhikari.jp">enひかり&lt;/a>のv6プラスオプションつけたものです。コラボ光の中で一番安いし2年縛りとかないので。お好みでフレッツ光クロスで10Gbpsにしたりv6プラス固定IPサービスにできるのも嬉しいポイントです。キャッシュバックの計算とか出来る人なら、他のコラボ光でもv6プラスさえつけちゃえばOKだと思います。&lt;/p>
&lt;p>電力系の回線が光配線方式なら普通の1Gbpsのプラン契約すればいいと思います。お好みでオプション付けていただいて。&lt;/p>
&lt;h2 id="最後に">最後に&lt;/h2>
&lt;p>読んでいただいてありがとうございました。&lt;/p>
&lt;p>この記事がどなたかの役に立ったら嬉しいです！&lt;/p>
&lt;h2 id="めちゃめちゃ参考記事">めちゃめちゃ参考記事&lt;/h2>
&lt;p>&lt;a href="https://diary.sorah.jp/2020/06/20/ngn-explained-2020">NTT フレッツ光における通信速度などの現状について、背景や仕組みから正しく理解する 2020&lt;/a>&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/tech/">tech</category><category domain="https://nu50218.dev/tags/internet/">internet</category></item><item><title>マトロイドに対する貪欲アルゴリズムの正当性の証明</title><link>https://nu50218.dev/posts/prove-matroid-greedy/</link><guid isPermaLink="true">https://nu50218.dev/posts/prove-matroid-greedy/</guid><pubDate>Wed, 10 Feb 2021 16:15:31 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>マトロイドの最小基問題に対する貪欲アルゴリズムの正当性を示します。&lt;/p>
&lt;p>「離散数学のすすめ」という本のマトロイドの章(詳しく証明が書いていない…)を、行間を補完して自分の言葉に書き直しています。&lt;/p>
&lt;p>マトロイドとその貪欲アルゴリズムについて軽く知っている前提です。&lt;/p>
&lt;h2 id="定義">定義&lt;/h2>
&lt;p>有限集合$E$とその部分集合族$\mathcal{I} \subseteq 2^E$(&lt;a href="https://ja.wikipedia.org/wiki/%E5%86%AA%E9%9B%86%E5%90%88">冪集合&lt;/a>)が以下の(I0)〜(I2)を満たすとき、$M = (E, \mathcal{I})$を&lt;strong>マトロイド&lt;/strong>という。&lt;/p>
&lt;p>(I0) $\emptyset \in \mathcal{I}$&lt;/p>
&lt;p>(I1) $I \subseteq J \in \mathcal{I} \Longrightarrow I \in \mathcal{I}$&lt;/p>
&lt;p>(I2) $I, J \in \mathcal{I}, |I| &amp;lt; |J| \Longrightarrow \exists e \in J \setminus I, I \cup \{e\} \in \mathcal{I}$&lt;/p>
&lt;p>マトロイド$M = (E, \mathcal{I})$の$\mathcal{I}$を、独立集合族と呼び、その要素を&lt;strong>独立集合&lt;/strong>という。&lt;/p>
&lt;p>独立集合のうち&lt;a href="https://qiita.com/ryuta-ito/items/9b795f2e6a2d5d1f5faf#%E6%A5%B5%E5%A4%A7">極大&lt;/a>なものを&lt;strong>基&lt;/strong>という。&lt;/p>
&lt;h2 id="最小基問題">最小基問題&lt;/h2>
&lt;p>マトロイド$M = (E, \mathcal{I})$と重み関数$w: E \rightarrow \mathbb{R}$に対して、$w(B) = \sum_{e \in B} w(e)$を最小にする基$B$を求める問題。&lt;/p>
&lt;p>$E$を辺集合、$\mathcal{I}$を森集合としてあげると最小全域木問題になる。&lt;/p>
&lt;h2 id="最小基問題に対する貪欲アルゴリズム">最小基問題に対する貪欲アルゴリズム&lt;/h2>
&lt;ol>
&lt;li>$I$を空集合、$S$を$E$とする。&lt;/li>
&lt;li>$S$を$w$で昇順に並び替え、$S_1, S_2, \dots, S_{|S|}$とする。&lt;/li>
&lt;li>$i=1, 2, \dots, |S|$について、4を順に行う。&lt;/li>
&lt;li>$I \cup \{S_i\}$が独立集合なら$I$に加える。&lt;/li>
&lt;/ol>
&lt;p>終了時の$I$が最小基となっている。&lt;/p>
&lt;h2 id="補題1">補題1&lt;/h2>
&lt;p>マトロイド$M=(E, \mathcal{I})$の基の要素数はすべて同じ。&lt;/p>
&lt;blockquote>
&lt;p>(証明)&lt;/p>
&lt;p>ある基$I, J$が存在して$|I| \neq |J|$と仮定する。$|I| &amp;lt; |J|$として一般性を失わない。&lt;/p>
&lt;p>このとき(I2)より、ある$e$が存在して$|I| &amp;lt; |I \cup \{e\}|$となる。これは$I$が極大であることに矛盾する。&lt;/p>
&lt;/blockquote>
&lt;h2 id="補題2">補題2&lt;/h2>
&lt;p>要素数$k$の独立集合のうち、$w(I)$を最小にする$I \in \mathcal{I}$を$I_k$とする。$I_{k+1}$が存在するならば、ある$e \in I_{k+1} \setminus I_{k}$が存在して$I_k \cup \{e\} \in \mathcal{I}, w(I_k \cup \{e\}) = w(I_{k+1})$を満たす。&lt;/p>
&lt;blockquote>
&lt;p>(証明)&lt;/p>
&lt;p>(I2)より、ある$e \in I_{k+1} \setminus I_{k}$が存在して$I_k \cup \{e\} \in \mathcal{I}$である。この$e$が$w(I_k \cup \{e\}) = w(I_&amp;gt; {k+1})$を満たすことを示す。&lt;/p>
&lt;p>まず、$I_{k+1}$の最小性より$w(I_{k+1}) \leq w(I_k \cup \{e\})$である。&lt;/p>
&lt;p>また、(I1)より$I_{k+1} \setminus \{e\}$は要素数$k$の独立集合である。したがって、$I_k$の最小性より、$w(I_{k+1}) = w(I_{k+1} \setminus \{e\}) + w(e) \geq w(I_k) + w(e) = w(I_k \cup \{e\})$。&lt;/p>
&lt;p>以上より$w(I_k \cup \{e\}) = w(I_{k+1})$。&lt;/p>
&lt;/blockquote>
&lt;h2 id="正当性の証明">正当性の証明&lt;/h2>
&lt;p>貪欲アルゴリズムは以下のようなアルゴリズムで、最終的に$I$が最小基として得られるというものでした。&lt;/p>
&lt;blockquote>
&lt;ol>
&lt;li>$I$を空集合、$S$を$E$とする。&lt;/li>
&lt;li>$S$を$w$で昇順に並び替え、$S_1, S_2, \dots, S_{|S|}$とする。&lt;/li>
&lt;li>$i=1, 2, \dots, |S|$について、4を順に行う。&lt;/li>
&lt;li>$I \cup \{S_i\}$が独立集合なら$I$に加える。&lt;/li>
&lt;/ol>
&lt;/blockquote>
&lt;p>まず$I$は常に、$I$と要素数が同じ独立集合の中で最小の独立集合である(=Aとします)ことを示します。&lt;/p>
&lt;blockquote>
&lt;p>(証明)&lt;/p>
&lt;p>はじめ$I$は空集合で、(I0)より独立集合なのでAを満たす。&lt;/p>
&lt;p>ステップ4を実行する直前に$I$がAを満たすと仮定する。&lt;/p>
&lt;p>ステップ4で$S_i$を加えるとき、$S_i$は、$I$の要素でなく$I \cup \{S_i\}$が独立集合であるような最小の$S$の要素の一つである。
そうでないとき、すなわち$S_j (j &amp;lt; i)$が存在して$I \cup \{S_j\}$が独立集合のとき、(I0)より$i = j$のときの$I$についても$I \cup \{S_j\}$は独立&amp;gt; 集合であるから、ステップ4で$I$に加えられているはずであり、矛盾する。&lt;/p>
&lt;p>したがって、$S_i$を加えるとき、補題2で$w(I \cup \{S_i\}) = w(I) + w(S_i) \leq w(I) + w(e) = w(I_{|I|+1})$となり、ステップ4実行直後も$I$はAを満たす。$S_i$が$I$に加えられないときも明らかにAを満たすので、ステップ4実行直後も$I$はAを満たす。&lt;/p>
&lt;p>以上より帰納的に$I$は常にAを満たす。&lt;/p>
&lt;/blockquote>
&lt;p>補題1より、あとは終了時に$I$が基であることを示せば十分です。&lt;/p>
&lt;p>基は極大な独立集合で、独立集合であることは示したので、極大でないと仮定して矛盾を導きます。&lt;/p>
&lt;blockquote>
&lt;p>(証明)&lt;/p>
&lt;p>終了時の$I$が極大でない、すなわち、ある独立集合$K$が存在して$I \subseteq K$と仮定する。&lt;/p>
&lt;p>このとき、(I2)よりある独立集合$J$と$e \not\in I$が存在して$J = I \cup \{e\}$かつ$J \subseteq K$を満たす。
ステップ2で$e$が$S_k$と番号をつけられたとき、(I1)より$i=k$のときステップ4の直前で$I \cup \{e\}$は独立集合であり、ステップ4で$I$に追加されているはずである。
したがって$e \not\in I$に矛盾する。&lt;/p>
&lt;/blockquote>
&lt;p>以上から示せました。&lt;/p></description><category domain="https://nu50218.dev/categories/kyopro/">kyopro</category><category domain="https://nu50218.dev/tags/math/">math</category></item><item><title>FIT FOOD HOME 使ってみた</title><link>https://nu50218.dev/posts/fit-food-home/</link><guid isPermaLink="true">https://nu50218.dev/posts/fit-food-home/</guid><pubDate>Sun, 07 Feb 2021 16:17:27 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>FIT FOOD HOMEっていう冷凍の健康的な料理を届けてくれるサービスを使ってみました。&lt;/p>
&lt;p>&lt;a href="https://store.tavenal.com">サイトはこちら&lt;/a>&lt;/p>
&lt;p>いくつか種類があるんですが、ダイエットミール500ってやつをとりあえず頼んでみました。
1食およそ500kcalのものが送られてきます。&lt;/p>
&lt;p>食べ方は、24時間ぐらい冷蔵庫にいれて微妙に解凍して、電子レンジで3分ちょっと加熱するだけです。
一緒に入ってる食べ方の紙が結構わかりにくくて、最初フタ開けて加熱するのを知らずにそのまま加熱したりしてしまいました。&lt;/p>
&lt;p>で、食べた感想としては、ギリギリ美味しくない感じでした…。
決してまずくはないですが、なんだろう、良くも悪くも身体に健康という味がします。
自然な味付けを冷凍して、解凍してうまく元の味に復元させられていないような感じです。&lt;/p>
&lt;p>あと、カロリー500kcalまで切り詰めて食事したいわけではない自分にとっては、絶妙にお腹が空いてしまいそこも微妙でした。&lt;/p>
&lt;p>これらのことから、1食1000円程度の価値を感じなかったのでダイエットミール500の定期購入はやめることにしました。&lt;/p>
&lt;p>おかずプレートってやつはおかずだけ送られてきて1食600円程度なのでまだワンチャンあるかもしれません。&lt;/p></description><category domain="https://nu50218.dev/tags/food/">food</category></item><item><title>nike training club始めた</title><link>https://nu50218.dev/posts/ntc-started/</link><guid isPermaLink="true">https://nu50218.dev/posts/ntc-started/</guid><pubDate>Mon, 01 Feb 2021 21:35:29 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>2週間ぐらい前からnike training clubはじめました。&lt;/p>
&lt;p>nike training clubっていうアプリです。&lt;/p>
&lt;p>&lt;a href="https://www.nike.com/jp/ntc-app">公式サイト&lt;/a>&lt;/p>
&lt;p>トレーナーの動きがスマホ上に出てくるので、30分ぐらい真似してトレーニングします。
トレーナーのお兄さんとお姉さんは、筋肉量とその柔らかさとバランス能力がえげつなくて、同じ動きはできません。&lt;/p>
&lt;p>週何回程度とか、ビギナー程度とか、持ってるトレーニング器具を選ぶと、勝手にスケジュールを調整してくれるので基本それにしたがってトレーニングします。
器具が何もなくても、ヨガマット(トレーニングマット？)さえあればとりあえずOKです。&lt;/p>
&lt;p>1年に1回ぐらいこのアプリやろうと思って、毎回初回で挫折していました。
ところが今年はなぜか、2週間続いていて、今後も続けられそうな感じがあります。
ついにトレーニングマットを買ったのが続けられている理由に感じています。&lt;/p>
&lt;p>アプリ内の記事に、継続は報酬を与えて脳をいじるのが大事(意訳)と書いてありました。
トレーニングきついけど(大学も行かず、バイトも行かずで家にいるため？)身体動かすの楽しいので、報酬を与えることができている気がします。&lt;/p>
&lt;p>マットの件で道具から入るの大事なんだなぁと思って、ネットで調べたナイキのそこそこのランニングシューズ、ペガサス37を買って昨日ぐらいからランニングもはじめました。
ランニングシューズってよくわかってなかったんですが、たしかに履いてみて通常の靴との差を感じています。&lt;/p>
&lt;p>まず疲れ方が違うように感じました。
通常の靴に比べて、足の裏がまったく痛くならないです。
下半身全体で受け止めている感じ。
クッションが多いからだと思います。&lt;/p>
&lt;p>あとは、持久走にありがちな喉で血の味がする現象がないです。
むしろ心地よい走りで、ただ疲労がたまったのでもう走れません、はい、終わり。という感じ。
これは、ランニングシューズ関係あるのかな…&lt;/p>
&lt;p>現状は15分ぐらい走ったら疲れてるので、遅めでもいいから30分気持ちよく走れるようになるのが当面の憧れです。&lt;/p>
&lt;p>training clubもそうなんですけど、nike run clubっていうのもあって、連動してくれます。
あと、2つともApple Watchとも連動してくれます。
これらを組み合わせると開始と終了のときにタッチするだけで勝手にデータが残ってくれます。
ゲームみたいで楽しいので、継続という面では個人的に大きいです。&lt;/p></description><category domain="https://nu50218.dev/tags/ntc/">ntc</category></item><item><title>「v6プラス」固定IPサービスのためにRTX830を買った</title><link>https://nu50218.dev/posts/rtx830/</link><guid isPermaLink="true">https://nu50218.dev/posts/rtx830/</guid><pubDate>Sat, 26 Dec 2020 19:08:30 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>&lt;a href="https://www.jpne.co.jp/service/v6plus-static/">「v6プラス」固定IPサービス&lt;/a>というサービスがあります。&lt;/p>
&lt;p>その終端として使っていたルーターをエレコムのWRC-1167GS2-BからYAMAHAのRTX830に買い替えました。&lt;/p>
&lt;h2 id="wrc-1167gs2-bを使っていた理由">WRC-1167GS2-Bを使っていた理由&lt;/h2>
&lt;p>「v6プラス」固定IPサービスを使うには、&lt;/p>
&lt;ul>
&lt;li>ひかり電話のオプションをつけて、NTTから「v6プラス」対応ひかり電話ルーター、ホームゲートウェイ 、レンタルルーターを手に入れる&lt;/li>
&lt;li>&lt;a href="https://www.jpne.co.jp/service/v6plus-static/">対応ルーター(下の方に書いてある)&lt;/a>を購入する&lt;/li>
&lt;/ul>
&lt;p>のいずれかをしなくてはいけません。&lt;/p>
&lt;p>ひかり電話は別に使わないので対応ルーターを買うことにしました。&lt;/p>
&lt;p>しかし、一覧を見るとわかるんですがだいたい高いです。&lt;/p>
&lt;p>なのでひとまずメルカリで中古のWRC-1167GS2-Bを2000円ぐらいで買って、Wi-Fiを切って使っていました。&lt;/p>
&lt;p>具体的には、Wi-FiはSynologyのRT2600acをつないでそこから飛ばしていました。&lt;/p>
&lt;h2 id="wrc-1167gs2-bに対する不満">WRC-1167GS2-Bに対する不満&lt;/h2>
&lt;h3 id="機能が少ない">機能が少ない&lt;/h3>
&lt;p>まあ家庭用ルーターなのでしょうがないです。&lt;/p>
&lt;h3 id="ipipトンネリングが遅い">IPIPトンネリングが遅い&lt;/h3>
&lt;p>「v6プラス」固定IPサービスはIPv4のパケットをIPv6で包んで、NTTの閉域網を通ってJPNEの設備から外に出してあげています。&lt;/p>
&lt;p>これがなんか妙に遅いです。体感では200Mbpsが上界、たいてい100Mbps前半という感じでした。&lt;/p>
&lt;h2 id="rtx830を買おうと思った理由">RTX830を買おうと思った理由&lt;/h2>
&lt;h3 id="早くなりそう">早くなりそう&lt;/h3>
&lt;p>で、最近ツイッターで情報収集をしていたらIPIPトンネリングはルーターの性能が結構要求されるということを知りました。&lt;/p>
&lt;p>また、RTX830は頑張れば700Mbpsぐらいまで出ると情報もありました。（YAMAHA製ルーターの中でも速い方っぽい）&lt;/p>
&lt;p>仕様見てないのでわかんないですが、まあさすがにRTX830のほうが性能いいでしょう。&lt;/p>
&lt;h3 id="機能が多い">機能が多い&lt;/h3>
&lt;p>はい。&lt;/p>
&lt;h3 id="wi-fiがない">Wi-Fiがない&lt;/h3>
&lt;p>Wi-Fiはすでに別のものがあるのでその分コスパ重視。&lt;/p>
&lt;h3 id="情報がいっぱいありそう">情報がいっぱいありそう&lt;/h3>
&lt;p>YAMAHA製ルーターはネットに情報がいっぱいあって、初心者の自分には嬉しそうだと思いました。&lt;/p>
&lt;h3 id="安く買えた">安く買えた&lt;/h3>
&lt;p>ひかりTVショッピングでメルマガクーポンとLINE PAYの10%オフを適用したら実質35000円ぐらいで買えました。&lt;/p>
&lt;h2 id="実際に買ってみて">実際に買ってみて&lt;/h2>
&lt;p>バカ早くなりました。&lt;/p>
&lt;p>IPv4にしか対応していない&lt;a href="https://www.speedtest.net">speedtest.net&lt;/a>で、上下300Mbpsが下界という感じで、調子がいいと500Mbpsぐらい出ます。&lt;/p>
&lt;p>RTX830のCPU使用率を見ても最大40%ぐらいしか使ってないようなので、NGN網のIPv6のスピードを十分に引き出せているようです。&lt;/p>
&lt;p>ちなみにYAMAHAのルーター初なんですが、CONFIGの書き方の情報がネットに散乱していて結構難しいです。&lt;/p>
&lt;p>YAMAHAのサイトに「v6プラス」固定IPサービスの&lt;a href="http://www.rtpro.yamaha.co.jp/RT/docs/ipip/index.html#setting11">設定例&lt;/a>があって、とりあえずこれを使えば動いたので助かりました。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/tech/">tech</category><category domain="https://nu50218.dev/tags/network/">network</category></item><item><title>激ウマほうれん草ペペロンチーノのレシピ</title><link>https://nu50218.dev/posts/spinach-peperoncino/</link><guid isPermaLink="true">https://nu50218.dev/posts/spinach-peperoncino/</guid><pubDate>Wed, 09 Sep 2020 11:04:54 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;h2 id="これは何">これは何&lt;/h2>
&lt;p>適当に作って美味しかった手抜き簡単ほうれん草ペペロンチーノのレシピです。&lt;/p>
&lt;p>&lt;img src="https://nu50218.dev/images/spinach-peperoncino.jpg" alt="spinach-peperoncino.jpg">&lt;/p>
&lt;h2 id="材料">材料&lt;/h2>
&lt;p>一人前です。&lt;/p>
&lt;ul>
&lt;li>
&lt;p>成城石井のペペロンチーノソース&lt;/p>
&lt;/li>
&lt;li>
&lt;p>ディチェコのスパゲッティーニ100g&lt;/p>
&lt;/li>
&lt;li>
&lt;p>トップバリューの冷凍ほうれん草半分（100g）&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="作り方">作り方&lt;/h2>
&lt;h3 id="1-冷凍ほうれん草とお湯を沸かす">1. 冷凍ほうれん草とお湯を沸かす&lt;/h3>
&lt;p>1Lぐらいのお水に用意した冷凍ほうれん草を全ていれて沸騰させます。&lt;/p>
&lt;p>沸騰したら塩を15gぐらい入れます。&lt;/p>
&lt;h3 id="2-パスタを茹でる">2. パスタを茹でる&lt;/h3>
&lt;p>ほうれん草はそのまま、パスタを入れて8分はかります。&lt;/p>
&lt;p>3分毎ぐらいに麺を軽く混ぜると均一な仕上がりになります。&lt;/p>
&lt;p>麺を試食していい感じになったら、ザルにあげてよく湯切りします。&lt;/p>
&lt;h3 id="3-ソースを絡める">3. ソースを絡める&lt;/h3>
&lt;p>ザルからお皿に麺を移して、ペペロンチーノソースをかけます。&lt;/p>
&lt;h3 id="4-すぐ食べる">4. すぐ食べる&lt;/h3>
&lt;p>写真を撮らずにすぐ食べます。&lt;/p>
&lt;h2 id="まとめ">まとめ&lt;/h2>
&lt;p>ぜひ作ってみてください。&lt;/p></description><category domain="https://nu50218.dev/tags/food/">food</category></item><item><title>shapez.ioをMac向けにビルドして遊ぶ</title><link>https://nu50218.dev/posts/shapez.io-macos/</link><guid isPermaLink="true">https://nu50218.dev/posts/shapez.io-macos/</guid><pubDate>Wed, 24 Jun 2020 13:59:02 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;h2 id="shapezioとは">shapez.ioとは&lt;/h2>
&lt;p>Factorioみたいなゲームです。&lt;a href="https://github.com/tobspr/shapez.io">ソースがGitHubに公開されています。&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://github.com/tobspr/shapez.io/issues/147">アプリに署名しなきゃいけない関係で、&lt;/a>まだMac向けに配信されていません。&lt;/p>
&lt;p>なんとなく中身を読んでいたらソースからビルドして遊べる状態になったのでやり方を書いておきます。&lt;/p>
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
&lt;iframe src="https://www.youtube.com/embed/KyorY1uIqiQ" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;h2 id="もろもろの依存のインストール">もろもろの依存のインストール&lt;/h2>
&lt;p>READMEに書いてあるとおりにいろいろやっていきます。
&lt;code>git lfs&lt;/code>と&lt;code>ffmpeg&lt;/code>、&lt;code>yarn&lt;/code>が動くようにしておく必要があります。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">git clone https://github.com/tobspr/shapez.io.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> shapez.io
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">git lfs pull
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yarn
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> yarn gulp &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> yarn
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ../electron &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> yarn
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> ../
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>これでもろもろの依存をインストールできました。&lt;/p>
&lt;h2 id="ビルド">ビルド&lt;/h2>
&lt;p>&lt;a href="https://github.com/tobspr/shapez.io/blob/master/.travis.yml">.travis.yml&lt;/a>を元にあまり中身を理解していないままビルドの方法を書きます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> gulp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yarn gulp build.standalone-prod
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yarn gulp standalone.prepare
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yarn gulp standalone.package.prod.darwin64
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>これで成功すれば、&lt;/p>
&lt;p>&lt;code>tmp_standalone_files&lt;/code>というディレクトリに&lt;code>shapez.io-standalone-darwin-x64&lt;/code>ができていてその中に&lt;code>shapez.io-standalone.app&lt;/code>が入っていて遊べます！&lt;/p>
&lt;h3 id="ffmpegナンチャラみたいなエラーが出たら">ffmpegナンチャラみたいなエラーが出たら&lt;/h3>
&lt;p>&lt;code>ffmpeg&lt;/code>を実行して&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">dyld: Library not loaded: /usr/local/opt/libffi/lib/libffi.6.dylib
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>みたいなエラーがでてきたら、多分&lt;/p>
&lt;pre tabindex="0">&lt;code>cp /usr/local/opt/libffi/lib/libffi.7.dylib /usr/local/opt/libffi/lib/libffi.6.dylib
&lt;/code>&lt;/pre>&lt;p>でなおります。 &lt;a href="https://github.com/platformio/platform-lattice_ice40/issues/7#issuecomment-619466591">※参考&lt;/a>&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/game/">game</category><category domain="https://nu50218.dev/tags/tech/">tech</category></item><item><title>Cloud FunctionsのGo1.13でプロジェクトIDが取得できなかった</title><link>https://nu50218.dev/posts/cloud-functions-go113/</link><guid isPermaLink="true">https://nu50218.dev/posts/cloud-functions-go113/</guid><pubDate>Mon, 15 Jun 2020 15:54:55 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>タイトルのとおりです。&lt;/p>
&lt;p>環境変数&lt;code>GCP_PROJECT&lt;/code>がセットされていません。&lt;/p>
&lt;p>たしかにドキュメントを読むとGo1.11は対応してます！って書いてありました。。。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/go/">go</category><category domain="https://nu50218.dev/tags/tech/">tech</category></item><item><title>完全栄養食BASE BREAD買ってみた</title><link>https://nu50218.dev/posts/base-bread/</link><guid isPermaLink="true">https://nu50218.dev/posts/base-bread/</guid><pubDate>Fri, 05 Jun 2020 12:54:45 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>タイトルのとおりです。&lt;/p>
&lt;p>BASE FOODっていう会社が出してる完全栄養食のパン、&lt;a href="https://shop.basefood.co.jp/products/basebread">BASE BREAD&lt;/a>を買ってみました。&lt;/p>
&lt;p>最近チョコの味のやつが増えて2種類になったらしく、両方買って食べてみたので感想を書きます。&lt;/p>
&lt;h2 id="感想">感想&lt;/h2>
&lt;p>普通においしいです。チョコの方は菓子パンで、チョコじゃないプレーンな方は全粒粉パンみたいな感じです。チョコの方が、顎が疲れなくて好きです。&lt;/p>
&lt;p>はじめ税込みで一食分350円ぐらいして結構お高めな印象を受けましたが、まともな栄養バランスの自炊も同じぐらいかかってしまうので手間を考えると割とアリです。袋から開けて食べるだけなので。&lt;/p>
&lt;p>カロリー、炭水化物、塩分らへん以外は1食分の栄養をカバーしているっぽいです。逆にそれらが不足しているので、カップ麺を飲み干せば栄養完璧では？と思ってカップ麺を食べる言い訳ができてしまいました。実際これだけ食べてると結構お腹がすきます。栄養を摂取してる感覚はありません。&lt;/p>
&lt;h2 id="最後に">最後に&lt;/h2>
&lt;p>気に入ったので追加でめちゃくちゃ買いました。&lt;/p>
&lt;p>ちなみにネットでクーポンを検索して発見できれば送料が少し安くなります。&lt;/p>
&lt;p>Amazonでも売ってるけど公式で買うほうが安いです多分。&lt;/p></description><category domain="https://nu50218.dev/tags/food/">food</category></item><item><title>Goで[]byteをjsonパッケージで扱うときの挙動につまった</title><link>https://nu50218.dev/posts/go-unmarshal-bytes/</link><guid isPermaLink="true">https://nu50218.dev/posts/go-unmarshal-bytes/</guid><pubDate>Tue, 07 Apr 2020 14:20:34 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>Goで&lt;code>[]byte&lt;/code>をjsonパッケージで扱うときの挙動につまったので調べました。&lt;/p>
&lt;h2 id="不思議な挙動">不思議な挙動&lt;/h2>
&lt;p>以下をみてください。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;encoding/json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;log&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">type&lt;/span> &lt;span class="nx">A&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Hoge&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span> &lt;span class="s">`json:&amp;#34;hoge&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="nx">data&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="nb">byte&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">`{&amp;#34;hoge&amp;#34;: &amp;#34;fuga&amp;#34;}`&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">a&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">A&lt;/span>&lt;span class="p">{}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">json&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Unmarshal&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">data&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">log&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Fatal&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Println&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">string&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Hoge&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>感覚では、stringはバイト列なので、&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">fuga
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>と出力しそうに思えるんですが、実際には謎の文字列が表示されます (&lt;a href="https://play.golang.org/p/UUpZ9Dw9L8i">playground&lt;/a>)&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">~�
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="理由">理由&lt;/h2>
&lt;p>jsonパッケージのコードを追っていってわかりました。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">d&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="nx">decodeState&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">literalStore&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">item&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">v&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Value&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">fromQuoted&lt;/span> &lt;span class="kt">bool&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kt">error&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>の中に、以下のような処理があります。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="k">case&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Slice&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Type&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nf">Elem&lt;/span>&lt;span class="p">().&lt;/span>&lt;span class="nf">Kind&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="nx">reflect&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Uint8&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">d&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">saveError&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nx">UnmarshalTypeError&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nx">Value&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s">&amp;#34;string&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">Type&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Type&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="nx">Offset&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">int64&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">d&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">readIndex&lt;/span>&lt;span class="p">())})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">b&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nb">make&lt;/span>&lt;span class="p">([]&lt;/span>&lt;span class="kt">byte&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">base64&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">StdEncoding&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">DecodedLen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">s&lt;/span>&lt;span class="p">)))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">base64&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">StdEncoding&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Decode&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">s&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">d&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">saveError&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">break&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">v&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">SetBytes&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">b&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="nx">n&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;a href="https://github.com/golang/go/blob/74d6de03fd7db2c6faa7794620a9bcf0c4f018f2/src/encoding/json/decode.go#L945-L967">view on GitHub&lt;/a>&lt;/p>
&lt;p>文字列をセットするときに、セットする対象が&lt;code>reflect.Uint8&lt;/code>の型のスライスならば&lt;code>base64.StdEncoding&lt;/code>でエンコードしてからセットされるらしいです。&lt;code>byte&lt;/code>は&lt;code>uint8&lt;/code>への&lt;a href="https://github.com/golang/go/blob/74d6de03fd7db2c6faa7794620a9bcf0c4f018f2/src/builtin/builtin.go#L88">エイリアスなので&lt;/a>、最初に挙げた例では&lt;code>hoge&lt;/code>がエンコードされた&lt;code>~�&lt;/code>が出力されたんだと思います。&lt;/p>
&lt;p>ちなみに、ちゃんとドキュメントにも書いてありました。ドキュメントを読みましょう。ごめんなさい。&lt;/p>
&lt;p>&lt;strong>&lt;a href="https://golang.org/pkg/encoding/json/#Unmarshal">Unmarshal&lt;/a>&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>Unmarshal uses the inverse of the encodings that Marshal uses, …&lt;/p>
&lt;/blockquote>
&lt;p>&lt;strong>&lt;a href="https://golang.org/pkg/encoding/json/#Marshal">Marshal&lt;/a>&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON value.&lt;/p>
&lt;/blockquote>
&lt;h2 id="対処法">対処法&lt;/h2>
&lt;h3 id="stringを使う">stringを使う&lt;/h3>
&lt;p>型を&lt;code>[]byte&lt;/code>ではなくてstringにすると動きます。&lt;code>[]byte(s)&lt;/code>でコピーなしで変換できるので良さそうと思ったんですが実はコピーが走るらしいです（！？）&lt;/p>
&lt;p>以下の記事では&lt;code>unsafe&lt;/code>パッケージを使用したノーコピーのやり方が書いてありました。&lt;/p>
&lt;p>&lt;a href="http://tocsato.hatenablog.com/entry/2016/09/06/080743">[]byte と string のキャスト - tocsatoの備忘録&lt;/a>&lt;/p>
&lt;h3 id="rawmessageを使う">RawMessageを使う&lt;/h3>
&lt;p>jsonパッケージに&lt;a href="https://golang.org/pkg/encoding/json/#RawMessage">RawMessage&lt;/a>という&lt;code>[]byte&lt;/code>へのエイリアスの型があって、&lt;code>UnmarshalJSON&lt;/code>が実装されているので、たとえば最初の例では&lt;code>&amp;quot;&lt;/code>付きで&lt;code>&amp;quot;fuga&amp;quot;&lt;/code>がセットされます。&lt;code>[]byte&lt;/code>に変換して適切にカットしてあげれば$O(1)$でお目当ての&lt;code>[]byte&lt;/code>が得られるはずです（多分）。&lt;/p>
&lt;h3 id="自分でunmarshaljsonを書く">自分でUnmarshalJSONを書く&lt;/h3>
&lt;p>たとえば以下のようなコードを書けます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;encoding/json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;log&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">type&lt;/span> &lt;span class="nx">A&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Hoge&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span> &lt;span class="s">`json:&amp;#34;hoge&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">a&lt;/span> &lt;span class="o">*&lt;/span>&lt;span class="nx">A&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="nf">UnmarshalJSON&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">data&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="kt">byte&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kt">error&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">type&lt;/span> &lt;span class="nx">A2&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Hoge&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="s">`json:&amp;#34;hoge&amp;#34;`&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">a2&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nb">new&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">A2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">json&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Unmarshal&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">data&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">a2&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">err&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Hoge&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="nb">byte&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">a2&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Hoge&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="kc">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="感想">感想&lt;/h2>
&lt;p>なぜbase64でエンコード/デコードするのか、理由があるのでしょうか。不思議。&lt;/p>
&lt;h2 id="ライセンス表記">ライセンス表記&lt;/h2>
&lt;p>以下のライセンスに基づきGoのソースコードを引用しています。&lt;/p>
&lt;p>&lt;a href="https://golang.org/LICENSE">LICENSE - The Go Programming Language&lt;/a>&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/go/">go</category><category domain="https://nu50218.dev/tags/tech/">tech</category></item><item><title>Visual Studio Codeでスニペットのときに補完が効かない</title><link>https://nu50218.dev/posts/vscode-snippets-suggestions/</link><guid isPermaLink="true">https://nu50218.dev/posts/vscode-snippets-suggestions/</guid><pubDate>Tue, 07 Apr 2020 11:19:08 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>設定で&lt;code>editor.suggest.snippetsPreventQuickSuggestions&lt;/code>とかいうのがデフォルトでONになってます。&lt;/p>
&lt;p>基本設定→設定で&lt;code>snippetsPreventQuickSuggestions&lt;/code>と検索すれば出てきます。&lt;/p>
&lt;p>これをOFFにすると候補が効きます。&lt;/p>
&lt;p>なんでデフォルトでONなんだろう。知ってる人がいたらおしえてください。&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/vscode/">vscode</category><category domain="https://nu50218.dev/tags/tech/">tech</category></item><item><title>Parenting Partnering Returns | GCJ2020 Qual C</title><link>https://nu50218.dev/posts/gcj-2020-qual-c/</link><guid isPermaLink="true">https://nu50218.dev/posts/gcj-2020-qual-c/</guid><pubDate>Sun, 05 Apr 2020 16:42:35 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>Google Code Jam 2020 Qualification Roundの3問目、&lt;a href="https://codingcompetitions.withgoogle.com/codejam/round/000000000019fd27/000000000020bdf9">Parenting Partnering Returns&lt;/a>が易しいけど割と好きな感じだったので自分の解法の証明を書きます。Goで解きました。&lt;/p>
&lt;h2 id="問題の概要">問題の概要&lt;/h2>
&lt;p>$N (\leq 1000)$個のタスクにそれぞれ開始の時間$S_i$と終了の時間$E_i$がある。それぞれのタスクをCameronとJamieの二人に割り振りたい。ただし1人1タスクしか同時にできない。&lt;/p>
&lt;p>このような割り振り方が存在するかを判定し、存在するなら1つ出力する。存在しないなら&lt;strong>IMPOSSIBLE&lt;/strong>と出力。&lt;/p>
&lt;h2 id="解法">解法&lt;/h2>
&lt;p>以下をすべてのタスクを割り当てるまで繰り返す。途中で終了していなければ、得られた割り振り方を出力する。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>$X$をまだ割り当てていないタスクのうち開始がもっとも早いもののいずれか1つとする&lt;/p>
&lt;/li>
&lt;li>
&lt;p>$X$をCameronに割り当てられるなら割り当てて1に戻る&lt;/p>
&lt;/li>
&lt;li>
&lt;p>$X$をJamieに割り当てられるなら割り当てて1に戻る&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>IMPOSSIBLE&lt;/strong>と出力して終了&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>ソートで$O(N \log N)$、上の処理で$O(N)$かかって全体$O(N \log N)$です。&lt;/p>
&lt;h2 id="証明">証明&lt;/h2>
&lt;p>条件を満たす割り振り方が存在するか否かで場合分けをして考えます。&lt;/p>
&lt;h3 id="存在しない場合">存在しない場合&lt;/h3>
&lt;p>明らかにこの解法は途中で終了していなければ正しい割り振り方を得ます。つまり、条件を満たす割り振り方が存在しない場合、この解法は途中で終了します。よって正しく&lt;strong>IMPOSSIBLE&lt;/strong>を出力します。&lt;/p>
&lt;h3 id="存在する場合">存在する場合&lt;/h3>
&lt;p>途中で終了していなければ正しい割り振り方を得るので、存在する場合、途中で終了しないことを示します。&lt;/p>
&lt;p>&lt;strong>IMPOSSIBLE&lt;/strong>と出力するとき、$X$はCameronとJamieのどちらにも割り当てられません。すでにCameronとJamieに割り振っているタスクは開始が$X$以前であることから、ある区間が存在して、3つ以上のタスクがその区間と被っていることがわかります。このようなとき、条件を満たす割り振り方は存在しないので、背理法より示せました。&lt;/p>
&lt;p>※イメージ&lt;/p>
&lt;p>&lt;img src="https://nu50218.dev/images/gcj-2020-qual-c-1.png" alt="gcj-2020-qual-c-1.png">&lt;/p>
&lt;h2 id="感想">感想&lt;/h2>
&lt;p>GCJのジャッジ環境のGoのバージョンが低すぎてキレそうになりました。&lt;code>sort.Slice&lt;/code>が見つからないって言われたので多分1.8より前です。$N \leq 1000$だったので愚直バブルソートを書きました。C++を使いましょう。&lt;/p>
&lt;p>ちなみにこれを書いてるときに調べたらGo1.8より前は&lt;code>sort&lt;/code>パッケージが存在していなかったわけではなくて、&lt;code>sort.Interface&lt;/code>を満たすようにこっちで書いて渡してあげるとソートしてくれるっぽいです。&lt;/p>
&lt;p>&lt;a href="https://blog.70-10.net/2019/10/31/go-sort-less-than-1.8/">参考: Go 1.8以前のバージョンでソートする&lt;/a>&lt;/p>
&lt;p>あと、&lt;a href="https://draw.io">draw.io&lt;/a>をはじめて使いました。評判通りめっちゃ使いやすかったです。&lt;/p>
&lt;h2 id="コード">コード&lt;/h2>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt"> 10
&lt;/span>&lt;span class="lnt"> 11
&lt;/span>&lt;span class="lnt"> 12
&lt;/span>&lt;span class="lnt"> 13
&lt;/span>&lt;span class="lnt"> 14
&lt;/span>&lt;span class="lnt"> 15
&lt;/span>&lt;span class="lnt"> 16
&lt;/span>&lt;span class="lnt"> 17
&lt;/span>&lt;span class="lnt"> 18
&lt;/span>&lt;span class="lnt"> 19
&lt;/span>&lt;span class="lnt"> 20
&lt;/span>&lt;span class="lnt"> 21
&lt;/span>&lt;span class="lnt"> 22
&lt;/span>&lt;span class="lnt"> 23
&lt;/span>&lt;span class="lnt"> 24
&lt;/span>&lt;span class="lnt"> 25
&lt;/span>&lt;span class="lnt"> 26
&lt;/span>&lt;span class="lnt"> 27
&lt;/span>&lt;span class="lnt"> 28
&lt;/span>&lt;span class="lnt"> 29
&lt;/span>&lt;span class="lnt"> 30
&lt;/span>&lt;span class="lnt"> 31
&lt;/span>&lt;span class="lnt"> 32
&lt;/span>&lt;span class="lnt"> 33
&lt;/span>&lt;span class="lnt"> 34
&lt;/span>&lt;span class="lnt"> 35
&lt;/span>&lt;span class="lnt"> 36
&lt;/span>&lt;span class="lnt"> 37
&lt;/span>&lt;span class="lnt"> 38
&lt;/span>&lt;span class="lnt"> 39
&lt;/span>&lt;span class="lnt"> 40
&lt;/span>&lt;span class="lnt"> 41
&lt;/span>&lt;span class="lnt"> 42
&lt;/span>&lt;span class="lnt"> 43
&lt;/span>&lt;span class="lnt"> 44
&lt;/span>&lt;span class="lnt"> 45
&lt;/span>&lt;span class="lnt"> 46
&lt;/span>&lt;span class="lnt"> 47
&lt;/span>&lt;span class="lnt"> 48
&lt;/span>&lt;span class="lnt"> 49
&lt;/span>&lt;span class="lnt"> 50
&lt;/span>&lt;span class="lnt"> 51
&lt;/span>&lt;span class="lnt"> 52
&lt;/span>&lt;span class="lnt"> 53
&lt;/span>&lt;span class="lnt"> 54
&lt;/span>&lt;span class="lnt"> 55
&lt;/span>&lt;span class="lnt"> 56
&lt;/span>&lt;span class="lnt"> 57
&lt;/span>&lt;span class="lnt"> 58
&lt;/span>&lt;span class="lnt"> 59
&lt;/span>&lt;span class="lnt"> 60
&lt;/span>&lt;span class="lnt"> 61
&lt;/span>&lt;span class="lnt"> 62
&lt;/span>&lt;span class="lnt"> 63
&lt;/span>&lt;span class="lnt"> 64
&lt;/span>&lt;span class="lnt"> 65
&lt;/span>&lt;span class="lnt"> 66
&lt;/span>&lt;span class="lnt"> 67
&lt;/span>&lt;span class="lnt"> 68
&lt;/span>&lt;span class="lnt"> 69
&lt;/span>&lt;span class="lnt"> 70
&lt;/span>&lt;span class="lnt"> 71
&lt;/span>&lt;span class="lnt"> 72
&lt;/span>&lt;span class="lnt"> 73
&lt;/span>&lt;span class="lnt"> 74
&lt;/span>&lt;span class="lnt"> 75
&lt;/span>&lt;span class="lnt"> 76
&lt;/span>&lt;span class="lnt"> 77
&lt;/span>&lt;span class="lnt"> 78
&lt;/span>&lt;span class="lnt"> 79
&lt;/span>&lt;span class="lnt"> 80
&lt;/span>&lt;span class="lnt"> 81
&lt;/span>&lt;span class="lnt"> 82
&lt;/span>&lt;span class="lnt"> 83
&lt;/span>&lt;span class="lnt"> 84
&lt;/span>&lt;span class="lnt"> 85
&lt;/span>&lt;span class="lnt"> 86
&lt;/span>&lt;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;bufio&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;bytes&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;os&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;strconv&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">type&lt;/span> &lt;span class="nx">Interval&lt;/span> &lt;span class="kd">struct&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Index&lt;/span> &lt;span class="kt">int&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Assignee&lt;/span> &lt;span class="kt">byte&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Start&lt;/span> &lt;span class="kt">int&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">End&lt;/span> &lt;span class="kt">int&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">intervals&lt;/span> &lt;span class="p">[]&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="nx">Interval&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">less&lt;/span> &lt;span class="kd">func&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">j&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kt">bool&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="k">range&lt;/span> &lt;span class="nx">intervals&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="p">&amp;lt;&lt;/span> &lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">intervals&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="o">++&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">!&lt;/span>&lt;span class="nf">less&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// swap
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">solve&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">N&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nf">nextInt&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">intervals&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nb">make&lt;/span>&lt;span class="p">([]&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="nx">Interval&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">i&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="k">range&lt;/span> &lt;span class="nx">intervals&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">interval&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="o">&amp;amp;&lt;/span>&lt;span class="nx">Interval&lt;/span>&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">Index&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nx">i&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Start&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nf">nextInt&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">End&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nf">nextInt&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">interval&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">intervals&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">func&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">j&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">Start&lt;/span> &lt;span class="p">&amp;lt;&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">j&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">Start&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cLast&lt;/span> &lt;span class="kt">int&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">jLast&lt;/span> &lt;span class="kt">int&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">interval&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="k">range&lt;/span> &lt;span class="nx">intervals&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">cLast&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Start&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Assignee&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="sc">&amp;#39;C&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">cLast&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">End&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">continue&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="nx">jLast&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Start&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Assignee&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="sc">&amp;#39;J&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">jLast&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">End&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">continue&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="s">&amp;#34;IMPOSSIBLE&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nf">sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">intervals&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">func&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">j&lt;/span> &lt;span class="kt">int&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="kt">bool&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">i&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">Index&lt;/span> &lt;span class="p">&amp;lt;&lt;/span> &lt;span class="nx">intervals&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="nx">j&lt;/span>&lt;span class="p">].&lt;/span>&lt;span class="nx">Index&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">var&lt;/span> &lt;span class="nx">b&lt;/span> &lt;span class="nx">bytes&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Buffer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">_&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">interval&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="k">range&lt;/span> &lt;span class="nx">intervals&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">WriteByte&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">interval&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Assignee&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">String&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">T&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nf">nextInt&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="nx">x&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">x&lt;/span> &lt;span class="o">&amp;lt;=&lt;/span> &lt;span class="nx">T&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nx">x&lt;/span>&lt;span class="o">++&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">s&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nf">solve&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Printf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Case #%d: %s\n&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">x&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">s&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">var&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">s&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="nx">bufio&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">NewScanner&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">os&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">Stdin&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">init&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">bufio&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ScanWords&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">nextInt&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">int&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Scan&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">_&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">strconv&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Atoi&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Text&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">n&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">nextString&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kt">string&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Scan&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">s&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Text&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div></description><category domain="https://nu50218.dev/categories/kyopro/">kyopro</category><category domain="https://nu50218.dev/tags/kyopro/">kyopro</category><category domain="https://nu50218.dev/tags/gcj/">gcj</category><category domain="https://nu50218.dev/tags/go/">go</category><category domain="https://nu50218.dev/tags/tech/">tech</category></item><item><title>Goのfmt.Errorfでは%wを使ったほうがいいらしい</title><link>https://nu50218.dev/posts/fmt-errorf-format/</link><guid isPermaLink="true">https://nu50218.dev/posts/fmt-errorf-format/</guid><pubDate>Fri, 27 Mar 2020 13:27:39 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;p>Goの&lt;code>fmt.Errorf&lt;/code>では、&lt;code>%v&lt;/code>より&lt;code>%w&lt;/code>を使ったほうがいいらしいです。&lt;/p>
&lt;p>&lt;code>fmt.Errorf&lt;/code> を使って &lt;code>error&lt;/code> をラップするとき、なんとなく便利な &lt;code>%v&lt;/code> を使って&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="nx">err&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="kc">nil&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Errorf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;unable to hoge: %v&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>って書きがちだったんですが、&lt;a href="https://golang.org/pkg/fmt/#Errorf">公式ドキュメント&lt;/a>によると&lt;/p>
&lt;blockquote>
&lt;p>If the format specifier includes a %w verb with an error operand, the returned error will implement an Unwrap method returning the operand. It is invalid to include more than one %w verb or to supply it with an operand that does not implement the error interface. The %w verb is otherwise a synonym for %v.&lt;/p>
&lt;/blockquote>
&lt;p>とあり、&lt;code>%w&lt;/code> で一個だけエラーを指定してあげると、Go1.13からの &lt;code>Unwrap() error&lt;/code> を実装した &lt;code>error&lt;/code> を返してくれるらしいです。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;errors&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">e&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">errors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">New&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;fuga&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">err&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Errorf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;unable to %s: %w&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s">&amp;#34;hoge&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">e&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">fmt&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Println&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">errors&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nf">Unwrap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;a href="https://play.golang.org/p/H5Z4U7wczCL">playground&lt;/a>&lt;/p>
&lt;p>でも&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">fuga
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>とプリントされるのでちゃんとできてますね。かしこい！&lt;/p></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/go/">go</category><category domain="https://nu50218.dev/tags/tech/">tech</category></item><item><title>Volvicが異常においしいという話</title><link>https://nu50218.dev/posts/volvic-umasugi/</link><guid isPermaLink="true">https://nu50218.dev/posts/volvic-umasugi/</guid><pubDate>Fri, 27 Mar 2020 00:12:14 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;h2 id="はじめに">はじめに&lt;/h2>
&lt;p>&lt;a href="https://www.kirin.co.jp/products/softdrink/volvic/index.html">Volvic&lt;/a>とは、キリンから出ているペットボトルの水です。&lt;/p>
&lt;p>手元の&lt;a href="https://www.crystalgeyser.jp">CRYSTAL GEYSER&lt;/a>と飲み比べても異常に美味しかったので、比較してどこが自分にとって美味しいのか調べてみました。&lt;/p>
&lt;h2 id="比較">比較&lt;/h2>
&lt;h3 id="ラベルに書いてあること">ラベルに書いてあること&lt;/h3>
&lt;h4 id="成分表示">成分表示&lt;/h4>
&lt;p>diffだけ&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>成分&lt;/th>
&lt;th>CRYSTAL GEYSER&lt;/th>
&lt;th>Volvic&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>ナトリウム&lt;/td>
&lt;td>1.13mg&lt;/td>
&lt;td>1.16mg&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>カルシウム&lt;/td>
&lt;td>0.64mg&lt;/td>
&lt;td>1.15mg&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>マグネシウム&lt;/td>
&lt;td>0.54mg&lt;/td>
&lt;td>0.80mg&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>カリウム&lt;/td>
&lt;td>0.18mg&lt;/td>
&lt;td>0.62mg&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h4 id="成分表示以外">成分表示以外&lt;/h4>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>&lt;/th>
&lt;th>CRYSTAL GEYSER&lt;/th>
&lt;th>Volvic&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>硬さ&lt;/td>
&lt;td>軟水&lt;/td>
&lt;td>軟水&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>原材料名&lt;/td>
&lt;td>水（湧水）&lt;/td>
&lt;td>水（鉱泉水）&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>採水地&lt;/td>
&lt;td>ウィード（シャスタ水源）&lt;/td>
&lt;td>ボルヴィック&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>原産国&lt;/td>
&lt;td>アメリカ合衆国&lt;/td>
&lt;td>フランス&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h3 id="味">味&lt;/h3>
&lt;p>CRYSTAL GEYSERはほんの少し（全然飲めるけど）嫌な感じがある。Volvicはスッキリと喉を通り抜ける。&lt;/p>
&lt;h3 id="キャップ">キャップ&lt;/h3>
&lt;p>Volvicのほうが1.1倍ぐらい、直径が大きい。
CRYSTAL GEYSERはフィンロックもとても小さいことに気づいた。&lt;/p>
&lt;h2 id="考察">考察&lt;/h2>
&lt;h3 id="成分の違い">成分の違い&lt;/h3>
&lt;p>&lt;a href="https://nu50218.dev/posts/volvic-umasugi/#%E6%88%90%E5%88%86%E8%A1%A8%E7%A4%BA">比較/成分表示&lt;/a>を見ると違いは歴然で、CRYSTAL GEYSERに比べてVolvicはミネラルが多く含まれていることがわかった。たしかに原材料名がCRYSTAL GEYSERの湧水に対して鉱泉水というもので、ミネラルが多く含まれそうな名前をしている。他の軟水の鉱泉水を飲んでみることで成分の違いがおいしさの秘訣なのかを確認できそう。&lt;/p>
&lt;h3 id="飲み口の違い">飲み口の違い&lt;/h3>
&lt;p>キャップの部分にも大きな違いが見られた。しかし、&lt;a href="https://nu50218.dev/posts/volvic-umasugi/#%E5%91%B3">比較/味&lt;/a>でも書いたように、喉を通るときの感覚が違い、これは飲み口の違いによらないので、今回はVolvicの美味しさに寄与しているかはわからなかった。お互いの中身を入れ替えて試してみるとなにかわかるかもしれない。&lt;/p>
&lt;h2 id="感想">感想&lt;/h2>
&lt;p>まず2つの水の種類が湧水と鉱泉水で違うのをまったく知りませんでした（7区分あるらしい）。&lt;a href="https://nu50218.dev/posts/volvic-umasugi/#%E6%88%90%E5%88%86%E3%81%AE%E9%81%95%E3%81%84">考察/成分の違い&lt;/a>で述べたように、他の軟水の鉱泉水があればそれを飲んでみたいと思います。&lt;/p>
&lt;p>ところで&lt;a href="https://www.kirin.co.jp/products/softdrink/volvic/arrange1.html">フレンチアレンジウォーターとかいうおしゃれなVolvic使用例&lt;/a>がホームページにあって今度作ってみようと思いました。&lt;/p>
&lt;h2 id="参考">参考&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;a href="https://goods.jccu.coop/voice/opinion/2013/08/post-72.html">鉱水って、硬水のこと？？&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;a href="https://www.kirin.co.jp/products/softdrink/volvic/index.html">Volvic | ソフトドリンク | 商品情報 | キリン&lt;/a>&lt;/p>
&lt;/li>
&lt;/ul></description><category domain="https://nu50218.dev/tags/water/">water</category><category domain="https://nu50218.dev/tags/volvic/">volvic</category></item><item><title>KaTeX Hugo テスト</title><link>https://nu50218.dev/posts/mathjax-test/</link><guid isPermaLink="true">https://nu50218.dev/posts/mathjax-test/</guid><pubDate>Thu, 26 Mar 2020 17:23:31 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;h2 id="katexのテスト">KaTeXのテスト&lt;/h2>
&lt;p>mathjaxを使おうと思ったけどKaTeXのほうが軽いらしいです。&lt;a href="https://blog.atusy.net/2019/05/09/katex-in-hugo/">Hugo で KaTeX&lt;/a>で設定できました。&lt;/p>
&lt;h3 id="インライン">インライン&lt;/h3>
&lt;p>文字列$f(x)= 5$文字列&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-md" data-lang="md">&lt;span class="line">&lt;span class="cl">文字列$f(x)= 5$文字列
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="改行するやつ">改行するやつ&lt;/h3>
&lt;p>文字列
$$
f(x)= 5
$$
文字列&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-md" data-lang="md">&lt;span class="line">&lt;span class="cl">文字列
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">f(x)= 5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$$
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">文字列
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="参考">参考&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://blog.atusy.net/2019/05/09/katex-in-hugo/">Hugo で KaTeX&lt;/a>&lt;/li>
&lt;/ul></description><category domain="https://nu50218.dev/categories/tech/">tech</category><category domain="https://nu50218.dev/tags/hugo/">hugo</category><category domain="https://nu50218.dev/tags/latex/">latex</category></item><item><title>My First Post</title><link>https://nu50218.dev/posts/my-first-post/</link><guid isPermaLink="true">https://nu50218.dev/posts/my-first-post/</guid><pubDate>Thu, 26 Mar 2020 13:28:09 +0900</pubDate><author>blog@nu50218.dev (nu50218)</author><copyright>© nu50218 2020~</copyright><description>&lt;h2 id="this-is-my-first-post">This is my first post&lt;/h2>
&lt;h3 id="新しい記事の作り方自分用">新しい記事の作り方（自分用）&lt;/h3>
&lt;p>&lt;code>$ hugo new posts/&amp;lt;NAME&amp;gt;.md&lt;/code>&lt;/p>
&lt;p>&lt;a href="https://gohugo.io/getting-started/quick-start/#step-4-add-some-content">QuickStart&lt;/a>に書いてあった。&lt;/p></description><category domain="https://nu50218.dev/tags/hugo/">hugo</category></item></channel></rss>