#numbers #positive #integer #ring #input #grambulation #diagonal

grambulate

在Rust中实现正整数的grambulation

2个版本

0.1.1 2023年11月1日
0.1.0 2023年10月31日

#7 in #positive

MIT许可证

24KB
448

grambulate-rust

Rust中的grambulation实现,最初在Reddit上解释,并在Code Golf中更精确地定义。

速度

下面描述的方法可能看起来有些复杂,但它避免了任何与输入变化的循环;我的代码中唯一的循环只遍历4种类型的Diagonal

这允许无论输入如何,都有非常低的执行时间;在我电脑上粗略测试的结果

value_a value_b 每次迭代的平均时间,100,000,000次迭代
1 2 529ns
10 25 395ns
100000 2500000 601ns
100000000000000 2500000000000000 364ns

这只是我最初选择的数字,这并不是一个真正的测试,但它可以给人一个印象。

实现

如果MathJax没有渲染,请尝试在GitHub上查看README

要将两个数字$a$和$b$grambulate到解决方案$c$,我们必须找到解决方案的坐标$c'$,为此,我们必须首先确定$a$和$b$在螺旋上的坐标($a'$和$b'$)。

为此,我们可以使用公式计算数字所在的'环'r(x)=⌊⌈√x⌉/2⌋来计算$r_a$和$r_b$。然后,可以使用公式v_d(r)=4r^2-(5-d)·r+1来计算环$x$上四个主对角线上的四个值,其中$d$指定使用哪个对角线。为此,我们将环1中给定对角线上的数字指定为$d$

对角线 $d$
右上角 3
左上角 5
左下角 7
右下角 9

这给我们提供了接近我们期望值($a$或$b$)的4个值。如果我们找到最接近但大于或等于目标值的值,我们可以计算差值并将其作为x或y偏移量应用,从而得到我们期望值的坐标。

现在我们有了两组坐标,我们可以计算连接向量$\vec{v}$并将其应用于$b'$以找到$c'$。

一旦我们知道$c'$,我们知道环是绝对x和y值中的较大者。

我们现在确定需要计算哪个对角线,使用上述公式检索值并减去相关坐标的差值。

示例

设$a=5$和$b=11$。

我们可以使用环公式确定$r_a=1$和$r_b=2$。

从$a$开始,我们可以在$r_a$环上计算4个对角线值
$v_3=3$
$v_5=5$
$v_7=7$
$v_9=9$

这些值中与$a$最接近且小于等于$a$的是$v_5=5$。该值的坐标是$v_5'=(-1\cdot{}r_a~|+1\cdot{}r_a) = (-1~|~1)$。因为$v_5=a$,我们不需要进一步的偏移。

继续到$b$
$v_3=13$
$v_5=17$
$v_7=21$
$v_9=25$

这些值中与$b$最接近且小于等于$b$的是$v_3=13$。该值的坐标是$v_3'=(+1\cdot{}r_b~|+1\cdot{}r_b)=(2~|~2)$。因为$v_3\neq{}b$,我们还需要做更多。

因为我们确定的$b$之前最接近的值是右上对角线,我们需要将$v_3'$的y坐标减少$v_3-b=13-11=2$。这留下了

\vec{c'}=\vec{v_3'}-\begin{pmatrix}0\\2\end{pmatrix}=\begin{pmatrix}2-0\\2-2\end{pmatrix}=\begin{pmatrix}2\\0\end{pmatrix}

现在我们知道

a'=(-1~|~1)\hspace{2cm}b'=(2~|~0)

连接向量是

\vec{v}=\vec{b'}-\vec{a'}=\begin{pmatrix}2-(-1)\\0-1\end{pmatrix}=\begin{pmatrix}3\\-1\end{pmatrix}

将此应用于$b'$,得到$c'$的位置向量。

$$\vec{c'}=\vec{b'}+\vec{v}=\begin{pmatrix}2+3\\0+(-1)\end{pmatrix}=\begin{pmatrix}5\\-1\end{pmatrix}$$

因为值不在对角线上($|x|\neq{}|y|$),我们可以使用以下表格来确定我们的目标值之前的对角线

条件 对角线
$|x|< y$ 左上角
$x>|y|$ 右上角
$x<-|y|$ 左下角
$-|x|>y$ 右下角

我们需要左上对角线。我们还知道我们的值在$r_c=\max(|5|, |-1|)=5$环上。环5上左上对角线的值,使用上述公式为$v_3(5)=91$。根据定义,$c$小于该值。因为左上对角线前方是垂直向上的,我们需要从91中减去91的y值和$c'$的y值之间的差值,我们应找到$c$。$$c=91-((y_{91})-(y_{c'}))=91-((+1\cdot{}5)-(-1))=91-6=85$$

就这样!$5~\lozenge{}~11=85$。

依赖关系

~160KB