我知道有各种方法可以获取随机数,比如从shell中获取。但是,我在一台编译很少的安卓手机上运行vim。而且,它不必严格随机。问题是,在Vim中得到一系列相对较好的随机数的有趣、简洁、快速(即使用vim本地函数)和短的方法是什么?
尝试类似这样的代码
function Rand()
return str2nr(matchstr(reltimestr(reltime()), '\v\.@<=\d+')[1:])
endfunction
我认为最好的选择是使用一些时间函数(有两个: reltime()
和 localtime()
,但后者只有每秒更新一次)。我宁愿避免使用随机数或者使用 pyeval('random.randint(1, 10)')
(在该代码之前加上python import random
),因为shell比较慢,并且我不信任基于时间的解决方案。
注意:文档说明了由reltime()
返回的项的格式取决于系统,因此我使用reltimestr()
而不是对类似于包含纳秒的reltime()[1]
进行操作。
let newrandom = str2nr(matchstr(reltimestr(reltime()), '\d\d$'))
(抱歉) - Remanrandint()
和我的函数结果看起来很像,但这取决于系统。我没有更好的解决方案。请注意,如果没有Python,您将缺少一堆精彩的插件,例如powerline,并且在其他某些插件(例如我的aurum)中会出现性能下降或缺失功能。OP没有其他选择:在Android上没有带有+python
的vim。 - ZyXsystem()
函数实现。 - ZyX最近我也在 Vim script 中玩了一下随机数。以下是我在过程中找到的一些资源。
如果可以的话,请尽可能使用外部随机数生成器。通常来说,它们比 Vim script 实现更好、更快。
例如,尝试以下命令:
:python import random; print random.randrange(1, 7)
:echo system('echo $RANDOM')
Vim script 库。这些库旨在提供高质量的 RNG 实现。
vital.vim 是由 vim-jp 用户组创建的优秀而全面的库。它们的随机数生成器具有令人印象深刻的功能,并且是我所知道的最好的纯 Vim script RNG。vital.vim 使用 Xorshift 算法。赶紧试试吧!
使用 vital.vim 掷骰子:
let Random = vital#of('vital').import('Random')
echo Random.range(1, 7)
vim-rng是一个小型的随机数生成器插件。它导出了几个全局函数,这些函数依赖于multiply-with-carry算法。该项目似乎还在不断改进中。
使用rng掷骰子:
echo RandomNumber(1, 6)
magnum.vim 是我自己编写的一个大整数库。最近,我添加了一个随机数生成器,可以生成任意大小的整数。它使用XORSHIFT-ADD算法。
使用magnum.vim掷骰子:
let six = magnum#Int(6)
echo magnum#random#NextInt(six).Add(magnum#ONE).Number()
Rndm比其他库要早得多。它的功能通过一些全局函数暴露出来。使用Rndm掷骰子:
echo Urndm(1, 6)
最后,一些有见地的讨论和Vim脚本片段的链接。
ZyX的reltime
片段 在这个页面上。
loreb的 GitHub上的vimprng项目 有大量印象深刻的基于Vim脚本的随机数生成器实现。非常有用。
这篇旧的邮件列表讨论 有几个Vim脚本片段。由Bee-9给出的第一个片段仅限于16位,但我发现它相当有效。这是它:
let g:rnd = localtime() % 0x10000
function! Random(n) abort
let g:rnd = (g:rnd * 31421 + 6927) % 0x10000
return g:rnd * a:n / 0x10000
endfunction
另一个脚本,在一个名叫Bart的人的个人配置文件中找到。
Vimcasts.org的第57集介绍了Vim的“表达式寄存器”,并在整个过程中提到了随机数的示例。参考此Stackoverflow问题和ZyX的代码片段。推荐观看。
Vim维基上的Wikia有一篇“跳转到随机行”文章,其中包含一些尚未提到的资源。
Another script
的链接已经失效了。 - jdhao[Low, High]
内的随机整数。Low
和High
,并返回该范围内的随机数字。" generate a random integer from range [Low, High] using Python
function! RandInt(Low, High) abort
" if you use Python 3, the python block should start with `python3` instead of
" `python`, see https://github.com/neovim/neovim/issues/9927
python3 << EOF
import vim
import random
# using vim.eval to import variable outside Python script to python
idx = random.randint(int(vim.eval('a:Low')), int(vim.eval('a:High')))
# using vim.command to export variable inside Python script to vim script so
# we can return its value in vim script
vim.command("let index = {}".format(idx))
EOF
return index
endfunction
我提出的第二个函数使用纯Vim脚本:
function! RandInt(Low, High) abort
let l:milisec = str2nr(matchstr(reltimestr(reltime()), '\v\.\zs\d+'))
return l:milisec % (a:High - a:Low + 1) + a:Low
endfunction
luaeval()
(仅适用于Neovim)生成随机数的第三种方法是通过luaeval()使用lua。
注:该方法仅适用于Neovim。
最初的回答。
" math.randomseed() is need to make the random() function generate different numbers
" on each use. Otherwise, the first number it generate seems same all the time.
luaeval('math.randomseed(os.time())')
let num = luaeval('math.random(1, 10)')
如果你想在非严肃的场合生成随机数,可以使用以下方法作为起点。
原始答案翻译成中文为"最初的回答"。