我知道有多种方法可以获取随机数,例如从 shell 中获取。但是,我在很少编译的 android 手机上运行 vim。此外,它不必是严格随机的。关键是,在 Vim 中获得一系列相当好的随机数的有趣、简洁、快速(即使用 vim 原生函数)或短方法是什么?
3 回答
尝试类似的东西
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]
看起来像包含纳秒的事情。
我最近自己玩过 Vim 脚本中的随机数。以下是我在此过程中找到的一些资源。
没有 Vim 脚本
如果可以,请务必使用外部随机数生成器。通常,它们比在 Vim 脚本中可以完成的任何事情都更好更快。
例如,尝试
:python import random; print random.randrange(1, 7)
:echo system('echo $RANDOM')
- 另一种脚本语言,例如 Ruby
图书馆
Vim 脚本库。这些希望努力提供质量不错的 RNG 实现。
vital.vim是由 vim-jp 用户组创建的一个优秀而全面的库。他们的随机数生成器具有一系列令人印象深刻的功能,是我所知道的最好的纯 Vim 脚本 RNG。vital.vim 使用Xorshift 算法。看看这个!
用vital.vim掷骰子:
let Random = vital#of('vital').import('Random') echo Random.range(1, 7)
vim-rng是一个小型随机数生成器插件。它导出了几个依赖于乘法进位算法的全局函数。这个项目似乎正在进行中。
用 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 脚本中有大量的 RNG 实现。很有用。
这个旧的邮件列表讨论有几个 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 的片段。受到推崇的。
wikia 上的 Vim wiki 有一篇文章'Jump to a random line'有一些尚未提及的资源。
根据其他人的答案和互联网上的其他资源,我编写了两个函数来生成给定范围内的随机整数[Low, High]
。
这两个函数都接收两个参数:Low
和High
返回此范围内的随机数。
结合 Python 和 Vim 脚本
第一个函数结合了 Python 和 Vim 脚本。
" 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 脚本
我建议的第二个函数使用纯 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 。
" 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)')
如果你想在不严重的场合产生随机数,你可以使用这些方法作为开始。