2个版本
0.1.1 | 2023年11月1日 |
---|---|
0.1.0 | 2023年10月31日 |
#7 in #positive
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