読者です 読者をやめる 読者になる 読者になる

もう大人だしこの春から(Vim)Golfを始めてみよう

vim

この記事は Vim Advent Calendar 2012 : ATND 121日目の記事です。
前日は@ujmさんのVim-users.jp - Vim Advent Calendar 2012 ujihisa 8でした。

VimGolfとは?

コードゴルフというのがありますが、それと似たようなものです。
Vimのキーストロークの少なさを競う遊びです。
少ないほどモテます。
VimGolf - real Vim ninjas count every keystroke!

Vim Advent Calendar 20日目のこちらの記事でも紹介されました。
VimGolfでハイスコアを取ったらトップの人のコメントが見れた話 - ゆり日記

以下に、導入と実際にやってみた結果を載せます。
なおhttp://vimgolf.com/challenges/50ee7504c0e3aa0002000040の回答に触れることになりますので、
見たくない方はご注意ください。

概要

VimGolfは大きく分けて次のような流れで参加出来ます。

  1. Twitterアカウントでサインイン
  2. gemでvimgolfをinstall
    1. なのでrubyが必要です
  3. vimgolfコマンドで問題にチャレンジ
    1. vimgolf用のvimが立ち上がる
    2. バッファの内容は問題に合わせた状態になっている
    3. 指定された結果状態になるように、あれこれいじる
    4. 保存して閉じる
  4. 正解なら送信してランキングに登録される
    1. 失敗なら再挑戦
  5. サイトで順位を見て一喜一憂する

サインイン

VimGolf - real Vim ninjas count every keystroke!にアクセスします。
画面右上の「Sign in with Twitter」からTwitterアカウントで登録します。

インストール

画面右上にターミナルっぽい表示枠があります。
ここには次のように記載されています。

Your VimGolf key: xxxxxxxxxxxxxxxx

$ gem install vimgolf
$ vimgolf setup
$ vimgolf put [challenge ID]

ここに載っている通りにコマンドを実行します。
まずはgemでインストールです。

/Users/kanno% gem install vimgolf
Fetching: highline-1.6.16.gem (100%)
Fetching: vimgolf-0.4.2.gem (100%)

------------------------------------------------------------------------------
Thank you for installing vimgolf-0.4.2.

0.1.3: custom vimgolf .vimrc file to help level the playing field
0.2.0: proxy support, custom diffs + proper vimscript parser/scoring
0.3.0: improve windows support, switch to YAML to remove c-ext dependency
0.4.0: improved diff/retry CLI, emacs support: http://bit.ly/yHgOPF

*NOTE*: please re-run "vimgolf setup" prior to playing!

For more information, rules & updates: http://vimgolf.com/about
------------------------------------------------------------------------------
Successfully installed highline-1.6.16
Successfully installed vimgolf-0.4.2
2 gems installed
Installing ri documentation for highline-1.6.16...
Installing ri documentation for vimgolf-0.4.2...
Installing RDoc documentation for highline-1.6.16...
Installing RDoc documentation for vimgolf-0.4.2...

インストールに成功したら、続いてsetupを行います。
ここでAPIKeyの入力を求められるので、「Your VimGolf Key」に表示されているKeyを入力します。

/Users/kanno% vimgolf setup
Please specify your VimGolf API key (register on vimgolf.com to get it):

成功すると次のようなメッセージが表示されます。

Saved. Happy golfing!

使い方

実行と結果送信

次のコマンドで各問題に挑戦できます。

vimgolf put チャレンジID

チャレンジIDは先程のターミナルチックなところに表示されているIDです。
もしくはURLの最後のパスでも構いません。

コマンドを実行すると問題のダウンロードが始まり、
ダウンロードを終えるとvimが立ち上がります。
この時のVimはVimGolf用に最小設定になっています。
プラグインはもちろん、キーマッピング等のカスタマイズもありません。
詳しくは公式サイトに書かれています。
http://vimgolf.com/about

次の問題を例に取ります。
http://vimgolf.com/challenges/50ee7504c0e3aa0002000040

/Users/kanno% vimgolf put 50ee7504c0e3aa0002000040
Downloading Vimgolf challenge: 50ee7504c0e3aa0002000040
Launching VimGolf session for challenge: 50ee7504c0e3aa0002000040

Vimが起動するとバッファには予め次の内容が書き込まれています。
これはサイトで見た場合の「Start file」に該当します。

vimchallenge

ここからあれこれいじって、バッファを期待する結果の状態にします。
これはサイトで見た場合の「End file」に該当します。

vimchallenge
vimchalleng
vimchallen
vimchalle
vimchall
vimchal
vimcha
vimch
vimc
vim
vi
v

vimchallenge
imchallenge
mchallenge
challenge
hallenge
allenge
llenge
lenge
enge
nge
ge
e

これでOKとなったら保存して閉じます。
成功した場合は次のようなメッセージが出ます。

Success! Your output matches. Your score: 46
Upload result to VimGolf? (yes / no)

yesを入力すればサーバーに結果が送信されます。

Uploading to VimGolf...
Uploaded entry, thanks for golfing!
View the leaderboard: http://vimgolf.com/challenges/50ee7504c0e3aa0002000040

失敗した場合は次のようなメッセージが出ます。

Uh oh, looks like your entry does not match the desired output.
Would you like to see a [d]iff or [r]etry or [q]uit ?

説明するまでもありませんが、一応。
[d]を押せば何が間違っていたのかをvimdiff形式で見れます。

[r]を押せば最初からやり直せます。
[q]を押せば諦めて終了します。


なお、結果は何度でも送信出来ます。
現在サーバーに登録されている自分の手数よりも少なければ更新できます。
現在登録されている手数よりも多い場合は送信しても無視されます。
(ただしデータ的に登録されているので、
もしWeb上から現在の手数を消すと次に送信されていた結果が表示されるようになります)

サイト上で他の人の回答を見る

細かい条件は分かりませんが、自分の順位より少しだけ上位の人の回答まで見えます。
他の人がどう解いたのか、手数を少なくするにはどうしたらいいか非常に参考になります。

実際にチャレンジしてみた

問題はさきほどのサンプルと同じです。

初チャレンジ

まずはサイト上で問題を見て考えます。
閃きます。
コピペすれば早い。

この時点でTOPは17手。余裕で勝てる気がします。

その結果がこちら。





他を寄せ付けない勢いでのビリです。

操作的には数手なんですが、1文字貼り付けるごとに1カウントされているのでしょうか。
どうやらちゃんと考えないといけないようです。

まじめに初チャレンジ

次のようにタイプして解いてみました。
マクロを[a]と[w]で分けていますが特別な意味はありません。

qayyp$xq10@aggyyGo<Esc>pqwyypxq10@w:wq<CR>

文章で説明しても分かりにくいでしょうから、
何したのかを知りたい方は実際に実行してもらうということで説明は省略。

35手。TOPの2倍もキーを叩いていることになります。随分と無駄が多そうです。

このあと、次のような感じで少しずつ手数を減らしていきました。

"終了を:wq<CR>じゃなくてZZにする(2減る)
qayyp$xq10@aggyyGo<Esc>pqwyypxq10@wZZ

"行コピーをyyじゃなくてYにする(3減る)
qaYp$xq10@aggYGo<Esc>pqwYpxq10@wZZ

"前半はもうひとつマクロ実行すれば空白行も作ってくれる(2減る)
qaYp$xq11@aggYGpqwYpxq10@wZZ

"上部へはHで戻る(1減る)
qaYp$xq11@aHYGpqwYpxq10@wZZ

"上部に戻るんじゃなくて、最初に後半用のvimchallengeを書いておく(1減る)
YPqaYp$xq11@ajqwYpxq10@wZZ

この時点で26手です。
そこそこ減りましたが、自分で考えるのはこのあたりが限界でした。
他のアプローチがあるのではないか。
その答えは上位の人の回答にありました。
とはいえここでは載せません。興味ある方はチャレンジしてみてください。

感想

この
「普段の慣れたやり方でやってみる」

「手数を減らしてみる」

「限界を感じる」

「他の回答を見る」

「そんな方法が!」

という経験がVim力を上げてくれている気がします。上がっていて欲しい。モテたい。

常に自分より上位の人の回答が見えますので、
回答を真似ていけば最終的にTOPの人に並ぶことも可能です。
ただ、そんな1位には意味を感じませんね。
私は回答を見るためにカンニングでTOPまで上げましたけど、
回答を見たあとはカンニング回答は消しました。

削除の方法は、以下の手順で可能です。

  1. 自分の回答の「Comment / Edit」をクリック
  2. 右下の「Delete Entry」をクリック

便利なプラグインでウハウハなのもいいけど素のVim力も上げたい。
そんな人はぜひチャレンジしてみるといいんじゃないでしょうか。
中にはトリッキーで実用性が低い手順もあるかもしれませんが、
基本的にはVim脳の体操になって良いと思います。
私もちょっとずつやっていこうかなと考えています。

まとめ

Vimが好きです。

明日は@thincaさんです。