Hack #236: 短期間でVim script力を向上する
Posted at 2011/10/15ツイート
こんにちは、ujihisaです。この記事はGentoo上で執筆しています。ちなみに来日することが決まりました。こんなカンファレンスや、勉強会を企画してみました。いずれも来月です。
問題
Vim scriptというプログラミング言語の能力を高める効率的な方法はあるのでしょうか?
Vimテクニックバイブルも既に完読してしまい、次にやるべきことを見失っている読者も多いかもしれません。
解決
Project Eulerというオンラインの問題集があります。オンラインで答え合わせもできます。
ぜひこれにVim scriptで挑戦してみましょう。以下に問1の回答例を示します。
(もっと良い回答を思いついた、という方はぜひコメントやトラックバックで示してください。楽しみにしています!)
問1
http://projecteuler.net/problem=1
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
回答例1
range()
で1から1000までの数値の配列を作り、それをもとにfor
で加算していきます。
function! s:p1()
let memo = 0
for i in range(1, 999)
if i % 3 == 0 || i % 5 == 0
let memo += i
endif
endfor
return memo
endfunction
echo s:p1()
これをfiletype=vim
なバッファで作成し、最後にquickrunしましょう。そこには答えがでているはずです。
回答例1
filter()
を使います。
function! s:p1()
let memo = 0
let list = filter(range(1, 999), 'v:val % 3 == 0 || v:val % 5 == 0')
for i in list
let memo += i
endfor
return memo
endfunction
echo s:p1()
さっきよりも見通しのよいコードになったでしょう。lambdaがなくて文字列になってしまうのがちょっと困りものですが…。
さて、この調子でfor
を消せると考えた人も多くいるかもしれません。そうです、つい5日前に読んだHack #235を思い出しましょう。vitalを使います。
function! s:p1()
let L = vital#of('vital').import('Data.List')
let list = filter(range(1, 999), 'v:val % 3 == 0 || v:val % 5 == 0')
return L.foldl1('v:memo + v:val', list)
endfunction
echo s:p1()
もうここまできたら一行にしたくなるのが人情ですよね。
echo vital#of('vital').import('Data.List').foldl1('v:memo + v:val', filter(range(1, 999), 'v:val % 3 == 0 || v:val % 5 == 0'))
ほかにも多くの解法があると思います。読みやすくかつ短いコードを高速で書くことができるよう、日々鍛錬あるのみです。
ujihisaもどる
blog comments powered by Disqus