如何停止/冻结/暂停波动的 RAND / RANDBETWEEN / RANDARRAY?

Posted

技术标签:

【中文标题】如何停止/冻结/暂停波动的 RAND / RANDBETWEEN / RANDARRAY?【英文标题】:How to stop / freeze / pause volatile RAND / RANDBETWEEN / RANDARRAY? 【发布时间】:2021-05-17 22:42:44 【问题描述】:

有没有一种简单的方法(解决方法)如何在谷歌电子表格中禁用诸如 =RAND()=RANDARRAY()=RANDBETWEEN() 等易失性函数的自动重新计算 (?)

没有脚本 没有插件 没有宏

在构建密钥生成器的情况下,我们需要处理多个 RANDBETWEEN 输出,每次单元格更改都会重新计算,并且这些 RANDBETWEEN 数字不能保留更长的时间我们不断编辑的工作表中的时间。

那里有一个错误的冷冻插件,还有许多需要安装和一定程度的改装/知识的非通用脚本变体,那么如何以旧方式做到这一点?

【问题讨论】:

【参考方案1】:

首先,让我们看看狐狸怎么说

=WHATTHEFOXSAY()

是一个独特的复活节彩蛋谷歌表格功能(由 @kishkin 发现),它可以根据用户需求随机生成预设的文本字符串,这是一个巨大的交易,因为虽然生成是随机的,重新计算不受 onEditonChangeonOpen 事件的影响,因此通过一些调整,我们可以生成一个随机数,而无需使用 volatile 函数,例如RAND(), RANDBETWEEN(), ARRAYRAND() 不能被冻结/暂停

狐狸只会说这些短语:

A-oo-oo-oo-ooo!
Hatee-hatee-hatee-ho!   
Wa-pa-pa-pa-pa-pa-pow!  
A-bubu-duh-bubu-dwee-dum    
Fraka-kaka-kaka-kaka-kow!   
Jacha-chacha-chacha-chow!   
Gering-ding-ding-ding-dingeringeding    
Joff-tchoff-tchoff-tchoffo-tchoffo-tchoff!  
    

例如。我们用这个函数得到的是 8 次随机概率中的 1 次,这并不多,所以我们需要将其放大(假设按 9 条狐尾的顺序)。遗憾的是ARRAYFORMULA 不支持函数,因此我们需要构造 一个数组:

=WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()

然后我们将这种狐狸语言转换成如下数字:

=INDEX(LEN(
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()))

接下来,我们需要一个开关。没什么花哨的,只是一个简单的IF 语句和一个复选框:

=ARRAYFORMULA(LEN(IF(A1=TRUE, 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY(), 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY())))

这将使我们能够通过切换复选框来完全控制重新计算。最后一步是通过将所有数字与PRODUCT 相乘来增加我们最初的 1/8 机会,为我们的随机性添加更多变化,为了更有趣,我们将它乘以 PI 的 3 次幂:

=ARRAYFORMULA(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY(), 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY()))))



无限刀片作品

到目前为止,我们似乎还没有创建有用的东西...一个带有一些随机数字的复选框来回循环(此时这根本不是随机的)...所以让我们转到下一个等级。我们真正的目标是创建一串数字,从中提取某些部分并将它们转换为最终输出。为此,我们需要利用SEQUENCE 的力量,我们TRANSPOSE 以获得额外的力量:

=TRANSPOSE(SEQUENCE(5, 4, 3, 2))

这转换为 5 列乘以 4 行的网格,其中第一个单元格以数字 3 开头,并且每个下一个单元格的值(按列)都大 2 倍

现在让我们定义我们的最终输出:

3x 唯一字符串 每个字符串有 16 个字符 编号从 09 和从 af 的小写字母

此时我们的SEQUENCE 将如下所示:

=TRANSPOSE(SEQUENCE(16, 3, 29, 73))
16 = columns
3  = rows
29 = starting point
73 = stepping

对于第三个和第四个参数(29 & 73),我们可以使用一些不错的 prime numbers 并将我们的整个序列再次乘以 PI()^3 以增加混乱。我们还需要将我们的数字输出转换为纯文本字符串以避免1.79769E+308 符号,因此我们使用TEXT

=ARRAYFORMULA(TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY(), 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY())))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"))

此时,我们在整个网格中有一个非常好的数字分布



终极十六进制/密码生成器

那里的每个字符都有自己的代码。您可以通过在工作表中运行此 AF 来检查它:

=ARRAYFORMULA("character", "code";
 CHAR(SEQUENCE(2500, 1, 33)), SEQUENCE(2500, 1, 33))
ROW(48:57)     = 0-9
ROW(65:90)     = A-Z
ROW(97:122)    = a-z
ROW(1040:1071) = А-Я
ROW(1072:1103) = а-я
ROW(913-937)   = Α-Ω
ROW(945-969)   = α-ω

对于我们的示例,我们需要 0-9a-f 的字符代码:

ROW(48:57)     = 0-9
ROW(97:102)    = a-f

我们将它放入数组 并按降序对其进行排序(这是因为我们不想将自己锁定在列表中位置较低的字符之外)。然后我们用JOIN| 分隔符准备正则表达式:

=JOIN("|", SORT(ROW(48:57); ROW(97:102), 1, ))

基本上,这个想法是 REGEXEXTRACT 在我们的数字网格中从上面连接的字符串中首先找到数字,以防万一没有匹配,我们添加 IFNA 带有一些数字的后备(102 在此例如)从我们的范围:

=ARRAYFORMULA(IFNA(REGEXEXTRACT(
 TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY(), 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY())))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"), 
 JOIN("|", SORT(ROW(48:57); ROW(97:102), 1, ))), 102))

并召唤CHAR 字符:

=ARRAYFORMULA(CHAR(IFNA(REGEXEXTRACT(
 TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY(), 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY())))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"), 
 JOIN("|", SORT(ROW(48:57); ROW(97:102), 1, ))), 102)))

现在最后一步是用查询粉碎它并删除残留的空格 - 更多关于查询粉碎 here

=ARRAYFORMULA(SUBSTITUTE(FLATTEN(QUERY(TRANSPOSE(
 CHAR(IFNA(REGEXEXTRACT(TEXT(PI()^3*PRODUCT(LEN(IF(A1=TRUE, 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY(), 
 WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY();
  WHATTHEFOXSAY(); WHATTHEFOXSAY(); WHATTHEFOXSAY())))*
 TRANSPOSE(SEQUENCE(16, 3, 29, 73))*PI()^3, "0"), 
 JOIN("|", SORT(ROW(48:57); ROW(97:102), 1, ))), 102))),,
 9^9)), " ", ))


总结

这些字符串真的是随机的吗? ofc 不是 - 它们只是“足够随机”,因为我们知道“熵”规则,但祝你好运手动破解它...... 主要的关键点是没有发生第 3 方重新计算,因此值保持暂停状态,并在切换复选框时生成新值 这些字符串会在一段时间内重复吗? - 是的,他们可以,就像普通的 RAND() 函数一样 是否有可能一次性生成两个相同的密钥? - 是的,它可能会发生,但可以通过多种方式来降低几率或引入UNIQUE() 或添加更多狐狸尾巴 请注意这个特殊场合:onOpen 事件将在每个复选框切换后重新计算WHATTHEFOXSAY() 一次!因此,如果您需要使用冻结值,建议您在每次切换复选框后使用 F5 键刷新电子表格

如果您希望在特定时间段内自动生成新的字符串,您可以插入一个 volatile 函数 TODAY()NOW() - 但请注意,每次编辑任何单元格或每分钟/小时都会重新计算当您不编辑任何内容时 (取决于 ..//文件 > 电子表格设置)

不重新计算每个单元格更改并在每个复选框开关或每 6 分钟重新计算一次如何?每周一次?每个奇数月?只有星期一和星期三?每 11 小时? 可能!我们需要一个更简单的IF 语句放置在电子表格中的任何位置,它将托管我们的逻辑门并输出数组 星座中的值,以便我们可以将我们的狐狸公式引用到一个单元格不包含挥发性元素的公式。 example

【讨论】:

非常好?????? 看在狐狸的份上! ? ?哇!不确定我是否会使用它,但做得很好!

以上是关于如何停止/冻结/暂停波动的 RAND / RANDBETWEEN / RANDARRAY?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 rand() 获取特定范围的数字?

为啥 rand()%6 有偏见?

为啥Adjusted rand index(ARI)优于rand index(RI)以及如何从公式中直观理解ARI

leetcode中等470rand7实现rand10

如何正确使用 RAND() 的语法 [重复]

PHP程序实现利用rand(1,100)函数产生10个1~100之间的随机数