一般化して、等差数列の作り方。
One to Ten
Generate the sequence of numbers from 1 to 10, one number per line. Inspired by this Reddit thread: https://redd.it/ak4it2
問題
何もない状態から、以下の連番を作成せよ。1
2
3
4
5
6
7
8
9
10
愚直にやると
この問題に出会うまでは、マクロと変数を使ったアプローチしか思いつかなかった。例えば、以下のようなものである。
:let i=1<CR>qqi<C-R>=i<CR><Esc>:let i=i+1<CR>o<Esc>q9@qddZZ
- :let i=1<CR>
変数iを初期化する。 - qq
マクロの記録を開始する。 - i<C-R>=i<CR><Esc>
インサートモードに入り、変数iの値をエクスプレッションレジスタ(:help c_CTRL-R)経由で挿入し、ノーマルモードに戻る。 - :let i=i+1<CR>
変数iをインクリメントする。 - o<Esc>
空白の一行を下に挿入する。 - q
マクロの記録を停止する。 - 9@qddZZ
マクロを9回実行し、余分な一行を削除したのち、ファイルを保存して終了する。
この方法の良い点は、いかなる数列に対しても同様の手順で作成できる点である。
しかし、たかが連番にマクロと変数操作を用いるのは大げさである。
スコアはお察し。
スコアはお察し。
解説
現時点での最善の方法は以下である。
i0<Esc>Y9Pv}g<C-A>ZZ
このスマートな回答のスコアは12点である。
- i0<Esc>
0を挿入する。 - Y9P
一行目、すなわち「0」をコピーし9回貼り付ける。
なお、同じようでもY9pとしてしまうと、貼り付けが終わったときにカーソルが2行目に移動してしまう。 - v}
一行目から末尾まで選択する。 - g<C-A>
連番を作成する。 - ZZ
ファイルを保存して終了。
原理
最初に1をずらっと並べて、次にビジュアルモードで選択し、最後にg<C-A>とすることで連番を作成できる。
なぜこのようなことが可能なのだろうか。
Vimのhelpを見てみよう(:help v_CTRL-A、:help v_g_CTRL-A)
Vimのhelpを見てみよう(:help v_CTRL-A、:help v_g_CTRL-A)
==================================================
*v_CTRL-A*
{Visual}CTRL-A
Add [count] to the number or alphabetic character in the highlighted text. {not in Vi}
*v_g_CTRL-A*
{Visual}g CTRL-A
Add [count] to the number or alphabetic character in the highlighted text. If several lines are highlighted, each one will be incremented by an additional [count] (so effectively creating a [count] incrementing sequence). {not in Vi}
For Example, if you have this list of numbers:
1. ~
1. ~
1. ~
1. ~
Move to the second "1." and Visually select three lines, pressing g CTRL-A results in:
1. ~
2. ~
3. ~
4. ~
==================================================
例に倣って考えてみる。
矩形選択で <CTRL-A> とした場合は、helpの例で表すと次のようになる。
1. ~ → 2. ~
1. ~ → 2. ~
1. ~ → 2. ~
1. ~ → 2. ~
一方で、矩形選択で g<CTRL-A> とした場合には、次のようになる。
1. ~ → 1. ~ (+1) = 2. ~
1. ~ → 1. ~ (+2) = 3. ~
1. ~ → 1. ~ (+3) = 4. ~
1. ~ → 1. ~ (+4) = 5. ~
(+n) は "additional"、連番を実現できる所以である。
そして[count]を指定した場合、例えば 5g<CTRL-A> とした場合には、次のようになる。
1. ~ → 1. ~ (+1+1+1+1+1) = 6. ~
1. ~ → 1. ~ (+2+2+2+2+2) = 11. ~
1. ~ → 1. ~ (+3+3+3+3+3) = 16. ~
1. ~ → 1. ~ (+4+4+4+4+4) = 21. ~
分かりやすく書きなおすと、
1. ~ → 1. ~ (+1 * 5) = 6. ~
1. ~ → 1. ~ (+2 * 5) = 11. ~
1. ~ → 1. ~ (+3 * 5) = 16. ~
1. ~ → 1. ~ (+4 * 5) = 21. ~
となる。
これは、初項6、公差5の等差数列に他ならない。
0 件のコメント:
コメントを投稿
コメント表示は承認制に設定しています