从数学导入cell从分数导入gcd从numpy导入搜索排序从itertools导入组合#所有无序数对(mod 2),根据a^3+b^3(mod 2中)的值划分为多个集。第一比特=[[(0,0),(1,1)],[(0、1)]]出租车定义(N):"""返回所有不超过“N”的出租车号码。基本算法是枚举所有数对a,b<cubic_root(N),在散列映射中保留a^3+b^3,并返回与多个对对应的所有值。这具有O(N^(2/3))的时间和跨度复杂性。就时间而言,我们做得再好不过了——我们必须检查到以下所有数字对N^(1/3)。但对于空间,我们可以构造数字对(a,b)“位对位”。在每个阶段,数字都被定义(模2^位),并且成对被划分为若干组基于a^3+b^3(mod 2^bit)的值。只能定义出租车号码通过同一组中的两对,我们可以找到一对一对的出租车号码(以类似DFS的方式),而无需将所有集合保存在内存中。一旦我们有了将数字构造到所需的位,我们以通常的方式找到出租车号码。平均来说,每套房子的大小都是原来房子的两倍4倍的数量,但他们被分为2组。我们得到了O(N^(1/3))的空间复杂度。N的最佳值为2^(3k)-其他值在复杂性方面很难计算。"""up_to_bit=n_bits(int(ceil(n**(1./3)))-1)结果=[]对于FIRST_BIT中的pair_set:完成from_set(pair_set,2,up_to_bit,result)result.sort()#该算法为我们提供了大于N的出租车数量,但它们之间存在差距。返回结果[:searchsorted(result,N)]定义完成from_set(pair_set,bit,up_to_bit,result):“”“将可以从'pair_set'生成的所有出租车号码添加到'result'。”“”如果位>up_to_bit:结果扩展(all_taxicab_from_set(pair_set))返回对于add_bit_to_set(pair_set,bit)中的next_bit_set:完成from_set(next_bit_set,位+1,up_to_bit,结果)定义add_bit_to_set(对集,n):"""获取一组n位数字对(a,b)并返回所有可能的对(n+1)-位数,其中(a,b)为n个低位。两对被分开根据a^3+b^3(mod 2^(bit+1))的值进行设置。"""加=1<<(n-1)掩码=(1<<n)-1cube_dict={}对于pair_set中的配对:对于四个next_pairs中的next_pair(pair,add):n=cube_sum(*next_pair)和掩码cube_dict[n]=cube_dect.get(n,[])+[next_pair]返回cube_dict.itervalues()def four_next_pairs(配对,添加):“”“返回由添加到x、y、nither或both的'add'组成的对。”“”x、 y=对#结果和每对都将按大小排序。结果=[(x,y),(x,y+加法)]#这确保了我们没有重复的配对。如果x!=年:result.append((y,x+add))result.append((x+add,y+add))返回结果定义所有_最大cab _ from _ set(pair_set):“”“返回pair_set中两对定义的所有出租车号码。”“”cube_sum_dict={}对于pair_set中的配对:n=立方和(*对)cube_sum_dict[n]=cube_sum _dict.get(n,[])+[对]return(cube_sum表示cube_sum,cube_sam_dict.iteritems()中的对如果len(pairs)>1且所有coprime_pairs(pair))定义所有_主_空(对):gcds=(成对的gcd(*pair))return max(组合中的对(gcd,2))==1定义n_bits(n):“”“返回n的位数。”“”位=0而n:位+=1n=n>>1返回位定义cube_sum(a,b):返回a**3+b**3