python - 给定一个数字,找到到达它的序列

我正在应对这个挑战:

A bot can do either of the 2 instructions:

  • [F]orward: move ahead by +1 and double its speed
  • [B]ack: Stop, change direction and reset its speed.

The initial speed is 1.

Given a distance, return a sequence that will satisfy it. The sequence can only have a maximum of 3 'B's. If a solution is not possible with 3 'B's then return empty string.

For example,

findSeq(2) -> FFBF (1+2-1)
findSeq(3) -> FF (1+2)
findSeq(4) -> FFFBFF (1+2+4 - (1+2))

这是我目前所拥有的:

def findSeq(dist):
    curr = 0
    seq = ""
    speed = 1
    mul = 1
    
    while (curr != dist):
        seq += 'F'
        curr += (speed*mul)
        speed *= 2
        
        if curr > dist and mul != -1:
            seq += 'B'
            mul = -1
            speed = 1

        elif curr < dist:
            mul = 1
        
        if curr == dist:
            return seq

        
        if seq.count('B') == 3 and curr != dist:
            return ''
    
    return seq

这适用于 findSeq(2)findSeq(3)findSeq(4)。但是,它开始中断 findSeq(5) ->(它给出 FFFBFFFBFF)

我不确定我错过了什么。

最佳答案

一些观察:一系列 n F 命令,使火车沿当前方向移动 2^n - 1。不失一般性,所有解的形式都是 F^k1 B F^k2 B F^k3 B F^k4,其中 k1, k2, k3, k4 >= 0 因为如果我们不移动火车,我们可以简单地设置一些 k 为 0。

这给出了问题的重述:给定 n,找到非负 k1、k2、k3、k4,使得 (2^k1 - 1) - (2^k2 - 1) + (2^k3 - 1) - (2^k4 - 1) = n。

1 在和中消去,所以你需要找到 2^k1 + 2^k3 - 2^k2 - 2^k4 = n。

如果n有N位,那么不失一般性,四个数中的每一个至多可以是N+1。

我确信有更聪明的方法,但只需搜索 (N+2)^4 种可能性就会产生 O((log n)^4) 的解决方案。

import itertools

def findSeq(n):
    N = max(1, n.bit_length())
    for k1, k2, k3, k4 in itertools.product(tuple(range(N+2)), repeat=4):
        if (1<<k1) - (1<<k2) + (1<<k3) - (1<<k4) == n:
            return 'B'.join('F' * x for x in (k1, k2, k3, k4))
    return ''

for i in range(100):
    print(i, findSeq(i))

@MattTimmermans 建议改进 O((logn)^2):枚举所有形式为 q = 2^k1 + 2^k3 的数字,然后查看 q-n 是否具有相同形式。

def findSeq2(n):
    N = max(1, n.bit_length())
    b2 = {(1<<k1)+(1<<k2): (k1, k2) for k1, k2 in itertools.product(tuple(range(N+2)), repeat=2)}
    for k1, k3 in b2.values():
        r = (1 << k1) + (1 << k3) - n
        if r in b2:
            k2, k4 = b2[r]
            return 'B'.join('F' * x for x in (k1, k2, k3, k4))      
    return ''

https://stackoverflow.com/questions/71532887/

相关文章:

r - 使用逗号分隔的长度不等的数字字符串对多列进行数学运算

laravel - 如何通过单击进入 vs 代码中的一个类

amazon-web-services - 如何将事件从 EventBridge 发送到 Lambd

visual-studio - Visual Studio 2022 无法添加服务引用且没有程序集引

ASP.NET Core 6 - 从 swagger explorer 中隐藏最小的 api 端点

python - 如何将字典的键值对收集到 Python 中的一个大字典中?

javascript - 使用javascript更新foreach循环中的数组对象

typescript - 修改后的模板字面量类型

javascript - 找时间在一张图中写一个数字

r - 取消列出嵌套列表的倒数第二个列表